From dblaikie at gmail.com Mon Feb 6 00:32:45 2012 From: dblaikie at gmail.com (David Blaikie) Date: Sun, 5 Feb 2012 22:32:45 -0800 Subject: [llvm-commits] [llvm] r149849 - in /llvm/trunk: include/llvm/ include/llvm/ADT/ include/llvm/Analysis/ include/llvm/Bitcode/ include/llvm/CodeGen/ include/llvm/CodeGen/PBQP/ include/llvm/ExecutionEngine/ include/llvm/MC/ include/llvm/Support/ inc Message-ID: On Sun, Feb 5, 2012 at 2:14 PM, Craig Topper wrote: > Author: ctopper > Date: Sun Feb ?5 16:14:15 2012 > New Revision: 149849 > > URL: http://llvm.org/viewvc/llvm-project?rev=149849&view=rev > Log: > Convert assert(0) to llvm_unreachable > > Modified: > ? ?llvm/trunk/include/llvm/ADT/BitVector.h > ? ?llvm/trunk/include/llvm/ADT/ImmutableSet.h > ? ?llvm/trunk/include/llvm/ADT/SmallBitVector.h > ? ?llvm/trunk/include/llvm/ADT/SparseBitVector.h > ? ?llvm/trunk/include/llvm/ADT/Trie.h > ? ?llvm/trunk/include/llvm/ADT/Twine.h > ? ?llvm/trunk/include/llvm/Analysis/IntervalIterator.h > ? ?llvm/trunk/include/llvm/Analysis/ProfileInfo.h > ? ?llvm/trunk/include/llvm/Bitcode/BitCodes.h > ? ?llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > ? ?llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h > ? ?llvm/trunk/include/llvm/CodeGen/AsmPrinter.h > ? ?llvm/trunk/include/llvm/CodeGen/PBQP/HeuristicBase.h > ? ?llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h > ? ?llvm/trunk/include/llvm/CodeGen/SelectionDAG.h > ? ?llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h > ? ?llvm/trunk/include/llvm/CodeGen/ValueTypes.h > ? ?llvm/trunk/include/llvm/Constant.h > ? ?llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h > ? ?llvm/trunk/include/llvm/MC/MCAsmBackend.h > ? ?llvm/trunk/include/llvm/MC/MCFixup.h > ? ?llvm/trunk/include/llvm/MC/MCRegisterInfo.h > ? ?llvm/trunk/include/llvm/Support/CommandLine.h > ? ?llvm/trunk/include/llvm/Support/Recycler.h > ? ?llvm/trunk/include/llvm/TableGen/Record.h > ? ?llvm/trunk/include/llvm/Target/TargetInstrInfo.h > ? ?llvm/trunk/include/llvm/Target/TargetJITInfo.h > ? ?llvm/trunk/include/llvm/Target/TargetLowering.h > ? ?llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > ? ?llvm/trunk/include/llvm/User.h > ? ?llvm/trunk/lib/VMCore/Constants.cpp > ? ?llvm/trunk/lib/VMCore/Core.cpp > ? ?llvm/trunk/lib/VMCore/Instructions.cpp > ? ?llvm/trunk/lib/VMCore/PassManager.cpp > ? ?llvm/trunk/lib/VMCore/ValueTypes.cpp > > Modified: llvm/trunk/include/llvm/ADT/BitVector.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/BitVector.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/BitVector.h (original) > +++ llvm/trunk/include/llvm/ADT/BitVector.h Sun Feb ?5 16:14:15 2012 > @@ -14,12 +14,12 @@ > ?#ifndef LLVM_ADT_BITVECTOR_H > ?#define LLVM_ADT_BITVECTOR_H > > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/MathExtras.h" > ?#include > ?#include > ?#include > ?#include > -#include > > ?namespace llvm { > > @@ -116,7 +116,7 @@ > ? ? ? else if (sizeof(BitWord) == 8) > ? ? ? ? NumBits += CountPopulation_64(Bits[i]); > ? ? ? else > - ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? return NumBits; > ? } > > @@ -146,10 +146,9 @@ > ? ? ? if (Bits[i] != 0) { > ? ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); > - ? ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); > - ? ? ? ?else > - ? ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? ? } > ? ? return -1; > ? } > @@ -170,10 +169,9 @@ > ? ? if (Copy != 0) { > ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? return WordPos * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Copy); > - ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); > - ? ? ?else > - ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ?llvm_unreachable("Unsupported!"); > ? ? } > > ? ? // Check subsequent words. > @@ -181,10 +179,9 @@ > ? ? ? if (Bits[i] != 0) { > ? ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_32((uint32_t)Bits[i]); > - ? ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); > - ? ? ? ?else > - ? ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? ? } > ? ? return -1; > ? } > > Modified: llvm/trunk/include/llvm/ADT/ImmutableSet.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ImmutableSet.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/ImmutableSet.h (original) > +++ llvm/trunk/include/llvm/ADT/ImmutableSet.h Sun Feb ?5 16:14:15 2012 > @@ -18,6 +18,7 @@ > ?#include "llvm/ADT/DenseMap.h" > ?#include "llvm/ADT/FoldingSet.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include > ?#include > ?#include > @@ -686,7 +687,7 @@ > ? ? ? ? stack.back() |= VisitedRight; > ? ? ? ? break; > ? ? ? default: > - ? ? ? ?assert(false && "Unreachable."); > + ? ? ? ?llvm_unreachable("Unreachable."); > ? ? } > ? } > > @@ -722,7 +723,7 @@ > ? ? ? ? skipToParent(); > ? ? ? ? break; > ? ? ? default: > - ? ? ? ?assert(false && "Unreachable."); > + ? ? ? ?llvm_unreachable("Unreachable."); > ? ? } > ? ? return *this; > ? } > @@ -747,7 +748,7 @@ > ? ? ? ? ? stack.push_back(reinterpret_cast(R) | VisitedRight); > ? ? ? ? break; > ? ? ? default: > - ? ? ? ?assert(false && "Unreachable."); > + ? ? ? ?llvm_unreachable("Unreachable."); > ? ? } > ? ? return *this; > ? } > > Modified: llvm/trunk/include/llvm/ADT/SmallBitVector.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallBitVector.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/SmallBitVector.h (original) > +++ llvm/trunk/include/llvm/ADT/SmallBitVector.h Sun Feb ?5 16:14:15 2012 > @@ -175,7 +175,7 @@ > ? ? ? ? return CountPopulation_32(Bits); > ? ? ? if (sizeof(uintptr_t) * CHAR_BIT == 64) > ? ? ? ? return CountPopulation_64(Bits); > - ? ? ?assert(0 && "Unsupported!"); > + ? ? ?llvm_unreachable("Unsupported!"); > ? ? } > ? ? return getPointer()->count(); > ? } > @@ -212,7 +212,7 @@ > ? ? ? ? return CountTrailingZeros_32(Bits); > ? ? ? if (sizeof(uintptr_t) * CHAR_BIT == 64) > ? ? ? ? return CountTrailingZeros_64(Bits); > - ? ? ?assert(0 && "Unsupported!"); > + ? ? ?llvm_unreachable("Unsupported!"); > ? ? } > ? ? return getPointer()->find_first(); > ? } > @@ -230,7 +230,7 @@ > ? ? ? ? return CountTrailingZeros_32(Bits); > ? ? ? if (sizeof(uintptr_t) * CHAR_BIT == 64) > ? ? ? ? return CountTrailingZeros_64(Bits); > - ? ? ?assert(0 && "Unsupported!"); > + ? ? ?llvm_unreachable("Unsupported!"); > ? ? } > ? ? return getPointer()->find_next(Prev); > ? } > > Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SparseBitVector.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/SparseBitVector.h (original) > +++ llvm/trunk/include/llvm/ADT/SparseBitVector.h Sun Feb ?5 16:14:15 2012 > @@ -18,11 +18,11 @@ > ?#include "llvm/ADT/ilist.h" > ?#include "llvm/ADT/ilist_node.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/MathExtras.h" > ?#include "llvm/Support/raw_ostream.h" > ?#include > ?#include > -#include > > ?namespace llvm { > > @@ -128,7 +128,7 @@ > ? ? ? else if (sizeof(BitWord) == 8) > ? ? ? ? NumBits += CountPopulation_64(Bits[i]); > ? ? ? else > - ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? return NumBits; > ? } > > @@ -138,13 +138,11 @@ > ? ? ? if (Bits[i] != 0) { > ? ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]); > - ? ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); > - ? ? ? ?else > - ? ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? ? } > - ? ?assert(0 && "Illegal empty element"); > - ? ?return 0; // Not reached > + ? ?llvm_unreachable("Illegal empty element"); > ? } > > ? /// find_next - Returns the index of the next set bit starting from the > @@ -165,10 +163,9 @@ > ? ? if (Copy != 0) { > ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy); > - ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy); > - ? ? ?else > - ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ?llvm_unreachable("Unsupported!"); > ? ? } > > ? ? // Check subsequent words. > @@ -176,10 +173,9 @@ > ? ? ? if (Bits[i] != 0) { > ? ? ? ? if (sizeof(BitWord) == 4) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]); > - ? ? ? ?else if (sizeof(BitWord) == 8) > + ? ? ? ?if (sizeof(BitWord) == 8) > ? ? ? ? ? return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]); > - ? ? ? ?else > - ? ? ? ? ?assert(0 && "Unsupported!"); > + ? ? ? ?llvm_unreachable("Unsupported!"); > ? ? ? } > ? ? return -1; > ? } > > Modified: llvm/trunk/include/llvm/ADT/Trie.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Trie.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/Trie.h (original) > +++ llvm/trunk/include/llvm/ADT/Trie.h Sun Feb ?5 16:14:15 2012 > @@ -220,8 +220,7 @@ > ? ? ? ? assert(0 && "FIXME!"); > ? ? ? ? return false; > ? ? ? case Node::DontMatch: > - ? ? ? ?assert(0 && "Impossible!"); > - ? ? ? ?return false; > + ? ? ? ?llvm_unreachable("Impossible!"); > ? ? ? case Node::LabelIsPrefix: > ? ? ? ? s1 = s1.substr(nNode->label().length()); > ? ? ? ? cNode = nNode; > @@ -258,8 +257,7 @@ > ? ? ? case Node::StringIsPrefix: > ? ? ? ? return Empty; > ? ? ? case Node::DontMatch: > - ? ? ? ?assert(0 && "Impossible!"); > - ? ? ? ?return Empty; > + ? ? ? ?llvm_unreachable("Impossible!"); > ? ? ? case Node::LabelIsPrefix: > ? ? ? ? s1 = s1.substr(nNode->label().length()); > ? ? ? ? cNode = nNode; > > Modified: llvm/trunk/include/llvm/ADT/Twine.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Twine.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/Twine.h (original) > +++ llvm/trunk/include/llvm/ADT/Twine.h Sun Feb ?5 16:14:15 2012 > @@ -12,6 +12,7 @@ > > ?#include "llvm/ADT/StringRef.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include > ?#include > > @@ -425,7 +426,7 @@ > ? ? StringRef getSingleStringRef() const { > ? ? ? assert(isSingleStringRef() &&"This cannot be had as a single stringref!"); > ? ? ? switch (getLHSKind()) { > - ? ? ?default: assert(0 && "Out of sync with isSingleStringRef"); > + ? ? ?default: llvm_unreachable("Out of sync with isSingleStringRef"); > ? ? ? case EmptyKind: ? ? ?return StringRef(); > ? ? ? case CStringKind: ? ?return StringRef(LHS.cString); > ? ? ? case StdStringKind: ?return StringRef(*LHS.stdString); > > Modified: llvm/trunk/include/llvm/Analysis/IntervalIterator.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IntervalIterator.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/IntervalIterator.h (original) > +++ llvm/trunk/include/llvm/Analysis/IntervalIterator.h Sun Feb ?5 16:14:15 2012 > @@ -101,14 +101,14 @@ > ? IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) { > ? ? OrigContainer = M; > ? ? if (!ProcessInterval(&M->front())) { > - ? ? ?assert(0 && "ProcessInterval should never fail for first interval!"); > + ? ? ?llvm_unreachable("ProcessInterval should never fail for first interval!"); > ? ? } > ? } > > ? IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) { > ? ? OrigContainer = &IP; > ? ? if (!ProcessInterval(IP.getRootInterval())) { > - ? ? ?assert(0 && "ProcessInterval should never fail for first interval!"); > + ? ? ?llvm_unreachable("ProcessInterval should never fail for first interval!"); > ? ? } > ? } > > > Modified: llvm/trunk/include/llvm/Analysis/ProfileInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ProfileInfo.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Analysis/ProfileInfo.h (original) > +++ llvm/trunk/include/llvm/Analysis/ProfileInfo.h Sun Feb ?5 16:14:15 2012 > @@ -22,6 +22,7 @@ > ?#define LLVM_ANALYSIS_PROFILEINFO_H > > ?#include "llvm/Support/Debug.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/Format.h" > ?#include "llvm/Support/raw_ostream.h" > ?#include > @@ -85,13 +86,11 @@ > > ? ? // getFunction() - Returns the Function for an Edge, checking for validity. > ? ? static const FType* getFunction(Edge e) { > - ? ? ?if (e.first) { > + ? ? ?if (e.first) > ? ? ? ? return e.first->getParent(); > - ? ? ?} else if (e.second) { > + ? ? ?if (e.second) > ? ? ? ? return e.second->getParent(); > - ? ? ?} > - ? ? ?assert(0 && "Invalid ProfileInfo::Edge"); > - ? ? ?return (const FType*)0; > + ? ? ?llvm_unreachable("Invalid ProfileInfo::Edge"); > ? ? } > > ? ? // getEdge() - Creates an Edge from two BasicBlocks. > > Modified: llvm/trunk/include/llvm/Bitcode/BitCodes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitCodes.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Bitcode/BitCodes.h (original) > +++ llvm/trunk/include/llvm/Bitcode/BitCodes.h Sun Feb ?5 16:14:15 2012 > @@ -140,8 +140,7 @@ > ? ? if (C >= '0' && C <= '9') return C-'0'+26+26; > ? ? if (C == '.') return 62; > ? ? if (C == '_') return 63; > - ? ?assert(0 && "Not a value Char6 character!"); > - ? ?return 0; > + ? ?llvm_unreachable("Not a value Char6 character!"); > ? } > > ? static char DecodeChar6(unsigned V) { > @@ -151,8 +150,7 @@ > ? ? if (V < 26+26+10) return V-26-26+'0'; > ? ? if (V == 62) return '.'; > ? ? if (V == 63) return '_'; > - ? ?assert(0 && "Not a value Char6 character!"); > - ? ?return ' '; > + ? ?llvm_unreachable("Not a value Char6 character!"); > ? } > > ?}; > > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Sun Feb ?5 16:14:15 2012 > @@ -455,10 +455,10 @@ > ? void ReadAbbreviatedField(const BitCodeAbbrevOp &Op, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVectorImpl &Vals) { > ? ? assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!"); > - > + > ? ? // Decode the value as we are commanded. > ? ? switch (Op.getEncoding()) { > - ? ?default: assert(0 && "Unknown encoding!"); > + ? ?default: llvm_unreachable("Unknown encoding!"); > ? ? case BitCodeAbbrevOp::Fixed: > ? ? ? Vals.push_back(Read((unsigned)Op.getEncodingData())); > ? ? ? break; > > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h (original) > +++ llvm/trunk/include/llvm/Bitcode/BitstreamWriter.h Sun Feb ?5 16:14:15 2012 > @@ -275,7 +275,7 @@ > > ? ? // Encode the value as we are commanded. > ? ? switch (Op.getEncoding()) { > - ? ?default: assert(0 && "Unknown encoding!"); > + ? ?default: llvm_unreachable("Unknown encoding!"); > ? ? case BitCodeAbbrevOp::Fixed: > ? ? ? if (Op.getEncodingData()) > ? ? ? ? Emit((unsigned)V, (unsigned)Op.getEncodingData()); > > Modified: llvm/trunk/include/llvm/CodeGen/AsmPrinter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/AsmPrinter.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/AsmPrinter.h (original) > +++ llvm/trunk/include/llvm/CodeGen/AsmPrinter.h Sun Feb ?5 16:14:15 2012 > @@ -18,6 +18,7 @@ > > ?#include "llvm/CodeGen/MachineFunctionPass.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > > ?namespace llvm { > ? class BlockAddress; > @@ -37,7 +38,6 @@ > ? class MachineModuleInfo; > ? class MachineMove; > ? class MCAsmInfo; > - ?class MCInst; > ? class MCContext; > ? class MCSection; > ? class MCStreamer; > @@ -49,8 +49,6 @@ > ? class TargetLoweringObjectFile; > ? class TargetData; > ? class TargetMachine; > - ?class Twine; > - ?class Type; > > ? /// AsmPrinter - This class is intended to be used as a driving class for all > ? /// asm writers. > @@ -254,7 +252,7 @@ > > ? ? /// EmitInstruction - Targets should implement this to emit instructions. > ? ? virtual void EmitInstruction(const MachineInstr *) { > - ? ? ?assert(0 && "EmitInstruction not implemented"); > + ? ? ?llvm_unreachable("EmitInstruction not implemented"); > ? ? } > > ? ? virtual void EmitFunctionEntryLabel(); > > Modified: llvm/trunk/include/llvm/CodeGen/PBQP/HeuristicBase.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/PBQP/HeuristicBase.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/PBQP/HeuristicBase.h (original) > +++ llvm/trunk/include/llvm/CodeGen/PBQP/HeuristicBase.h Sun Feb ?5 16:14:15 2012 > @@ -157,7 +157,7 @@ > ? ? ? ? case 0: s.applyR0(nItr); break; > ? ? ? ? case 1: s.applyR1(nItr); break; > ? ? ? ? case 2: s.applyR2(nItr); break; > - ? ? ? ?default: assert(false && > + ? ? ? ?default: llvm_unreachable( > ? ? ? ? ? ? ? ? ? ? ? ? "Optimal reductions of degree > 2 nodes is invalid."); > ? ? ? } > > @@ -186,7 +186,7 @@ > ? ? /// \brief Add a node to the heuristic reduce list. > ? ? /// @param nItr Node iterator to add to the heuristic reduce list. > ? ? void addToHeuristicList(Graph::NodeItr nItr) { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Heuristically reduce one of the nodes in the heuristic > @@ -194,25 +194,25 @@ > ? ? /// @return True if a reduction takes place, false if the heuristic reduce > ? ? /// ? ? ? ? list is empty. > ? ? void heuristicReduce() { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Prepare a change in the costs on the given edge. > ? ? /// @param eItr Edge iterator. > ? ? void preUpdateEdgeCosts(Graph::EdgeItr eItr) { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Handle the change in the costs on the given edge. > ? ? /// @param eItr Edge iterator. > ? ? void postUpdateEdgeCostts(Graph::EdgeItr eItr) { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Handle the addition of a new edge into the PBQP graph. > ? ? /// @param eItr Edge iterator for the added edge. > ? ? void handleAddEdge(Graph::EdgeItr eItr) { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Handle disconnection of an edge from a node. > @@ -223,7 +223,7 @@ > ? ? /// method allows for the effect to be computed only for the remaining > ? ? /// node in the graph. > ? ? void handleRemoveEdge(Graph::EdgeItr eItr, Graph::NodeItr nItr) { > - ? ? ?assert(false && "Must be implemented in derived class."); > + ? ? ?llvm_unreachable("Must be implemented in derived class."); > ? ? } > > ? ? /// \brief Clean up any structures used by HeuristicBase. > > Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) > +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Sun Feb ?5 16:14:15 2012 > @@ -128,9 +128,8 @@ > ? ? ? ? ? ? ? ? ?Other.Contents.Order.isNormalMemory && > ? ? ? ? ? ? ? ?Contents.Order.isMustAlias == Other.Contents.Order.isMustAlias && > ? ? ? ? ? ? ? ?Contents.Order.isArtificial == Other.Contents.Order.isArtificial; > + ? ? ?default: llvm_unreachable("Invalid dependency kind!"); > ? ? ? } > - ? ? ?assert(0 && "Invalid dependency kind!"); > - ? ? ?return false; If you could keep trailing asserts like this as trailing (though feel free to convert them from assert to llvm_unreachable) that would be great. Adding a default to a fully-covered switch like this is unhelpful as it suppresses -Wswitch (which warns when a switch-over-enum is not fully covered) should a new element be added to the enumeration. Clang has a warning I recently added (-Wcovered-switch-default) that catches this case & your changes have caused several violations of this warning across LLVM. Let me know if you'd prefer me to fix them up. - David > ? ? } > > ? ? bool operator!=(const SDep &Other) const { > > Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Sun Feb ?5 16:14:15 2012 > @@ -51,7 +51,7 @@ > ? static void noteHead(SDNode*, SDNode*) {} > > ? static void deleteNode(SDNode *) { > - ? ?assert(0 && "ilist_traits shouldn't see a deleteNode call!"); > + ? ?llvm_unreachable("ilist_traits shouldn't see a deleteNode call!"); > ? } > ?private: > ? static void createNode(const SDNode &); > > Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h (original) > +++ llvm/trunk/include/llvm/CodeGen/SelectionDAGISel.h Sun Feb ?5 16:14:15 2012 > @@ -240,8 +240,7 @@ > ? /// succeeds or false if it fails. ?The number is a private implementation > ? /// detail to the code tblgen produces. > ? virtual bool CheckPatternPredicate(unsigned PredNo) const { > - ? ?assert(0 && "Tblgen should generate the implementation of this!"); > - ? ?return 0; > + ? ?llvm_unreachable("Tblgen should generate the implementation of this!"); > ? } > > ? /// CheckNodePredicate - This function is generated by tblgen in the target. > @@ -249,20 +248,17 @@ > ? /// false if it fails. ?The number is a private implementation > ? /// detail to the code tblgen produces. > ? virtual bool CheckNodePredicate(SDNode *N, unsigned PredNo) const { > - ? ?assert(0 && "Tblgen should generate the implementation of this!"); > - ? ?return 0; > + ? ?llvm_unreachable("Tblgen should generate the implementation of this!"); > ? } > > ? virtual bool CheckComplexPattern(SDNode *Root, SDNode *Parent, SDValue N, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned PatternNo, > ? ? ? ? ? ? ? ? ? ? ? ? SmallVectorImpl > &Result) { > - ? ?assert(0 && "Tblgen should generate the implementation of this!"); > - ? ?return false; > + ? ?llvm_unreachable("Tblgen should generate the implementation of this!"); > ? } > > ? virtual SDValue RunSDNodeXForm(SDValue V, unsigned XFormNo) { > - ? ?assert(0 && "Tblgen should generate this!"); > - ? ?return SDValue(); > + ? ?llvm_unreachable("Tblgen should generate this!"); > ? } > > ? SDNode *SelectCodeCommon(SDNode *NodeToMatch, > > Modified: llvm/trunk/include/llvm/CodeGen/ValueTypes.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ValueTypes.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/CodeGen/ValueTypes.h (original) > +++ llvm/trunk/include/llvm/CodeGen/ValueTypes.h Sun Feb ?5 16:14:15 2012 > @@ -16,10 +16,11 @@ > ?#ifndef LLVM_CODEGEN_VALUETYPES_H > ?#define LLVM_CODEGEN_VALUETYPES_H > > -#include > -#include > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/MathExtras.h" > +#include > +#include > > ?namespace llvm { > ? class Type; > @@ -246,13 +247,13 @@ > ? ? unsigned getSizeInBits() const { > ? ? ? switch (SimpleTy) { > ? ? ? case iPTR: > - ? ? ? ?assert(0 && "Value type size is target-dependent. Ask TLI."); > + ? ? ? ?llvm_unreachable("Value type size is target-dependent. Ask TLI."); > ? ? ? case iPTRAny: > ? ? ? case iAny: > ? ? ? case fAny: > - ? ? ? ?assert(0 && "Value type is overloaded."); > + ? ? ? ?llvm_unreachable("Value type is overloaded."); > ? ? ? default: > - ? ? ? ?assert(0 && "getSizeInBits called on extended MVT."); > + ? ? ? ?llvm_unreachable("getSizeInBits called on extended MVT."); > ? ? ? case i1 ?: ?return 1; > ? ? ? case i8 ?: ?return 8; > ? ? ? case i16 : > @@ -306,7 +307,7 @@ > ? ? static MVT getFloatingPointVT(unsigned BitWidth) { > ? ? ? switch (BitWidth) { > ? ? ? default: > - ? ? ? ?assert(false && "Bad bit width!"); > + ? ? ? ?llvm_unreachable("Bad bit width!"); > ? ? ? case 16: > ? ? ? ? return MVT::f16; > ? ? ? case 32: > > Modified: llvm/trunk/include/llvm/Constant.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constant.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Constant.h (original) > +++ llvm/trunk/include/llvm/Constant.h Sun Feb ?5 16:14:15 2012 > @@ -105,7 +105,7 @@ > ? /// available cached constants. ?Implementations should call > ? /// destroyConstantImpl as the last thing they do, to destroy all users and > ? /// delete this. > - ?virtual void destroyConstant() { assert(0 && "Not reached!"); } > + ?virtual void destroyConstant() { llvm_unreachable("Not reached!"); } > > ? //// Methods for support type inquiry through isa, cast, and dyn_cast: > ? static inline bool classof(const Constant *) { return true; } > @@ -131,11 +131,12 @@ > ? ? // to be here to avoid link errors. > ? ? assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be " > ? ? ? ? ? ?"implemented for all constants that have operands!"); > - ? ?assert(0 && "Constants that do not have operands cannot be using 'From'!"); > + ? ?llvm_unreachable("Constants that do not have operands cannot be using " > + ? ? ? ? ? ? ? ? ? ? "'From'!"); > ? } > - > + > ? static Constant *getNullValue(Type* Ty); > - > + > ? /// @returns the value for an integer constant of the given type that has all > ? /// its bits set to true. > ? /// @brief Get the all ones value > > Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original) > +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Sun Feb ?5 16:14:15 2012 > @@ -15,18 +15,19 @@ > ?#ifndef LLVM_EXECUTION_ENGINE_H > ?#define LLVM_EXECUTION_ENGINE_H > > -#include > -#include > -#include > ?#include "llvm/MC/MCCodeGenInfo.h" > ?#include "llvm/ADT/SmallVector.h" > ?#include "llvm/ADT/StringRef.h" > ?#include "llvm/ADT/ValueMap.h" > ?#include "llvm/ADT/DenseMap.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/ValueHandle.h" > ?#include "llvm/Support/Mutex.h" > ?#include "llvm/Target/TargetMachine.h" > ?#include "llvm/Target/TargetOptions.h" > +#include > +#include > +#include > > ?namespace llvm { > > @@ -244,7 +245,8 @@ > ? /// to the address in the target process as the running code will see it. > ? /// This is the address which will be used for relocation resolution. > ? virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) { > - ? ?assert(0 && "Re-mapping of section addresses not supported with this EE!"); > + ? ?llvm_unreachable("Re-mapping of section addresses not supported with this " > + ? ? ? ? ? ? ? ? ? ? "EE!"); > ? } > > ? /// runStaticConstructorsDestructors - This method is used to execute all of > > Modified: llvm/trunk/include/llvm/MC/MCAsmBackend.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmBackend.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/MC/MCAsmBackend.h (original) > +++ llvm/trunk/include/llvm/MC/MCAsmBackend.h Sun Feb ?5 16:14:15 2012 > @@ -14,6 +14,7 @@ > ?#include "llvm/MC/MCFixup.h" > ?#include "llvm/MC/MCFixupKindInfo.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > > ?namespace llvm { > ?class MCAsmLayout; > @@ -49,8 +50,8 @@ > ? /// createELFObjectTargetWriter - Create a new ELFObjectTargetWriter to enable > ? /// non-standard ELFObjectWriters. > ? virtual ?MCELFObjectTargetWriter *createELFObjectTargetWriter() const { > - ? ?assert(0 && "createELFObjectTargetWriter is not supported by asm backend"); > - ? ?return 0; > + ? ?llvm_unreachable("createELFObjectTargetWriter is not supported by asm " > + ? ? ? ? ? ? ? ? ? ? "backend"); > ? } > > ? /// hasReliableSymbolDifference - Check whether this target implements > > Modified: llvm/trunk/include/llvm/MC/MCFixup.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCFixup.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/MC/MCFixup.h (original) > +++ llvm/trunk/include/llvm/MC/MCFixup.h Sun Feb ?5 16:14:15 2012 > @@ -11,6 +11,7 @@ > ?#define LLVM_MC_MCFIXUP_H > > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/SMLoc.h" > ?#include > > @@ -95,7 +96,7 @@ > ? /// size. It is an error to pass an unsupported size. > ? static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { > ? ? switch (Size) { > - ? ?default: assert(0 && "Invalid generic fixup size!"); > + ? ?default: llvm_unreachable("Invalid generic fixup size!"); > ? ? case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1; > ? ? case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2; > ? ? case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4; > > Modified: llvm/trunk/include/llvm/MC/MCRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCRegisterInfo.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/MC/MCRegisterInfo.h (original) > +++ llvm/trunk/include/llvm/MC/MCRegisterInfo.h Sun Feb ?5 16:14:15 2012 > @@ -17,6 +17,7 @@ > ?#define LLVM_MC_MCREGISTERINFO_H > > ?#include "llvm/ADT/DenseMap.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include > > ?namespace llvm { > @@ -273,8 +274,7 @@ > ? ? const DenseMap &M = isEH ? EHDwarf2LRegs : Dwarf2LRegs; > ? ? const DenseMap::const_iterator I = M.find(RegNum); > ? ? if (I == M.end()) { > - ? ? ?assert(0 && "Invalid RegNum"); > - ? ? ?return -1; > + ? ? ?llvm_unreachable("Invalid RegNum"); > ? ? } > ? ? return I->second; > ? } > > Modified: llvm/trunk/include/llvm/Support/CommandLine.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Support/CommandLine.h (original) > +++ llvm/trunk/include/llvm/Support/CommandLine.h Sun Feb ?5 16:14:15 2012 > @@ -337,7 +337,7 @@ > > ? bool hasValue() const { return false; } > > - ?const DataType &getValue() const { assert(false && "no default value"); } > + ?const DataType &getValue() const { llvm_unreachable("no default value"); } > > ? // Some options may take their value from a different data type. > ? template > > Modified: llvm/trunk/include/llvm/Support/Recycler.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/Recycler.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Support/Recycler.h (original) > +++ llvm/trunk/include/llvm/Support/Recycler.h Sun Feb ?5 16:14:15 2012 > @@ -17,6 +17,7 @@ > > ?#include "llvm/ADT/ilist.h" > ?#include "llvm/Support/AlignOf.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include > > ?namespace llvm { > @@ -52,7 +53,7 @@ > ? static void noteHead(RecyclerStruct*, RecyclerStruct*) {} > > ? static void deleteNode(RecyclerStruct *) { > - ? ?assert(0 && "Recycler's ilist_traits shouldn't see a deleteNode call!"); > + ? ?llvm_unreachable("Recycler's ilist_traits shouldn't see a deleteNode call!"); > ? } > ?}; > > > Modified: llvm/trunk/include/llvm/TableGen/Record.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/TableGen/Record.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/TableGen/Record.h (original) > +++ llvm/trunk/include/llvm/TableGen/Record.h Sun Feb ?5 16:14:15 2012 > @@ -20,6 +20,7 @@ > ?#include "llvm/Support/Allocator.h" > ?#include "llvm/Support/SourceMgr.h" > ?#include "llvm/Support/DataTypes.h" > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Support/raw_ostream.h" > ?#include > > @@ -671,8 +672,7 @@ > ? /// > ? virtual Init *resolveBitReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Bit) const { > - ? ?assert(0 && "Illegal bit reference off int"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal bit reference off int"); > ? } > > ? /// resolveListElementReference - This method is used to implement > @@ -680,8 +680,7 @@ > ? /// now, we return the resolved value, otherwise we return null. > ? virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Elt) const { > - ? ?assert(0 && "Illegal element reference off int"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal element reference off int"); > ? } > ?}; > > @@ -716,8 +715,7 @@ > ? /// > ? virtual Init *resolveBitReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Bit) const { > - ? ?assert(0 && "Illegal bit reference off string"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal bit reference off string"); > ? } > > ? /// resolveListElementReference - This method is used to implement > @@ -725,8 +723,7 @@ > ? /// now, we return the resolved value, otherwise we return null. > ? virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Elt) const { > - ? ?assert(0 && "Illegal element reference off string"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal element reference off string"); > ? } > ?}; > > @@ -786,8 +783,7 @@ > ? /// > ? virtual Init *resolveBitReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Bit) const { > - ? ?assert(0 && "Illegal bit reference off list"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal bit reference off list"); > ? } > > ? /// resolveListElementReference - This method is used to implement > @@ -1132,8 +1128,7 @@ > ? /// > ? virtual Init *resolveBitReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Bit) const { > - ? ?assert(0 && "Illegal bit reference off def"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal bit reference off def"); > ? } > > ? /// resolveListElementReference - This method is used to implement > @@ -1141,8 +1136,7 @@ > ? /// now, we return the resolved value, otherwise we return null. > ? virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Elt) const { > - ? ?assert(0 && "Illegal element reference off def"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal element reference off def"); > ? } > ?}; > > @@ -1251,14 +1245,12 @@ > > ? virtual Init *resolveBitReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Bit) const { > - ? ?assert(0 && "Illegal bit reference off dag"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal bit reference off dag"); > ? } > > ? virtual Init *resolveListElementReference(Record &R, const RecordVal *RV, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned Elt) const { > - ? ?assert(0 && "Illegal element reference off dag"); > - ? ?return 0; > + ? ?llvm_unreachable("Illegal element reference off dag"); > ? } > ?}; > > @@ -1416,7 +1408,7 @@ > ? ? ? ? Values.erase(Values.begin()+i); > ? ? ? ? return; > ? ? ? } > - ? ?assert(0 && "Cannot remove an entry that does not exist!"); > + ? ?llvm_unreachable("Cannot remove an entry that does not exist!"); > ? } > > ? void removeValue(StringRef Name) { > > Modified: llvm/trunk/include/llvm/Target/TargetInstrInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetInstrInfo.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetInstrInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetInstrInfo.h Sun Feb ?5 16:14:15 2012 > @@ -279,8 +279,7 @@ > ? /// This is only invoked in cases where AnalyzeBranch returns success. It > ? /// returns the number of instructions that were removed. > ? virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const { > - ? ?assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!"); > - ? ?return 0; > + ? ?llvm_unreachable("Target didn't implement TargetInstrInfo::RemoveBranch!"); > ? } > > ? /// InsertBranch - Insert branch code into the end of the specified > @@ -297,8 +296,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock *FBB, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const SmallVectorImpl &Cond, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DebugLoc DL) const { > - ? ?assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!"); > - ? ?return 0; > + ? ?llvm_unreachable("Target didn't implement TargetInstrInfo::InsertBranch!"); > ? } > > ? /// ReplaceTailWithBranchTo - Delete the instruction OldInst and everything > @@ -375,7 +373,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ?MachineBasicBlock::iterator MI, DebugLoc DL, > ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned DestReg, unsigned SrcReg, > ? ? ? ? ? ? ? ? ? ? ? ? ? ?bool KillSrc) const { > - ? ?assert(0 && "Target didn't implement TargetInstrInfo::copyPhysReg!"); > + ? ?llvm_unreachable("Target didn't implement TargetInstrInfo::copyPhysReg!"); > ? } > > ? /// storeRegToStackSlot - Store the specified register of the given register > @@ -388,7 +386,8 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned SrcReg, bool isKill, int FrameIndex, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const TargetRegisterClass *RC, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const TargetRegisterInfo *TRI) const { > - ?assert(0 && "Target didn't implement TargetInstrInfo::storeRegToStackSlot!"); > + ? ?llvm_unreachable("Target didn't implement " > + ? ? ? ? ? ? ? ? ? ? "TargetInstrInfo::storeRegToStackSlot!"); > ? } > > ? /// loadRegFromStackSlot - Load the specified register of the given register > @@ -400,7 +399,8 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned DestReg, int FrameIndex, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const TargetRegisterClass *RC, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const TargetRegisterInfo *TRI) const { > - ?assert(0 && "Target didn't implement TargetInstrInfo::loadRegFromStackSlot!"); > + ? ?llvm_unreachable("Target didn't implement " > + ? ? ? ? ? ? ? ? ? ? "TargetInstrInfo::loadRegFromStackSlot!"); > ? } > > ? /// expandPostRAPseudo - This function is called for all pseudo instructions > > Modified: llvm/trunk/include/llvm/Target/TargetJITInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetJITInfo.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetJITInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetJITInfo.h Sun Feb ?5 16:14:15 2012 > @@ -46,8 +46,8 @@ > ? ? /// ptr. > ? ? virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?JITCodeEmitter &JCE) { > - ? ? ?assert(0 && "This target doesn't implement emitGlobalValueIndirectSym!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("This target doesn't implement " > + ? ? ? ? ? ? ? ? ? ? ? "emitGlobalValueIndirectSym!"); > ? ? } > > ? ? /// Records the required size and alignment for a call stub in bytes. > @@ -67,15 +67,13 @@ > ? ? /// aligned from the address the JCE was set up to emit at. > ? ? virtual void *emitFunctionStub(const Function* F, void *Target, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?JITCodeEmitter &JCE) { > - ? ? ?assert(0 && "This target doesn't implement emitFunctionStub!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("This target doesn't implement emitFunctionStub!"); > ? ? } > > ? ? /// getPICJumpTableEntry - Returns the value of the jumptable entry for the > ? ? /// specific basic block. > ? ? virtual uintptr_t getPICJumpTableEntry(uintptr_t BB, uintptr_t JTBase) { > - ? ? ?assert(0 && "This target doesn't implement getPICJumpTableEntry!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("This target doesn't implement getPICJumpTableEntry!"); > ? ? } > > ? ? /// LazyResolverFn - This typedef is used to represent the function that > @@ -96,8 +94,7 @@ > ? ? /// function, and giving the JIT the target function used to do the lazy > ? ? /// resolving. > ? ? virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) { > - ? ? ?assert(0 && "Not implemented for this target!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("Not implemented for this target!"); > ? ? } > > ? ? /// relocate - Before the JIT can run a block of code that has been emitted, > @@ -113,8 +110,7 @@ > ? ? /// handling thread local variables. This method returns a value only > ? ? /// meaningful to the target. > ? ? virtual char* allocateThreadLocalMemory(size_t size) { > - ? ? ?assert(0 && "This target does not implement thread local storage!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("This target does not implement thread local storage!"); > ? ? } > > ? ? /// needsGOT - Allows a target to specify that it would like the > > Modified: llvm/trunk/include/llvm/Target/TargetLowering.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetLowering.h (original) > +++ llvm/trunk/include/llvm/Target/TargetLowering.h Sun Feb ?5 16:14:15 2012 > @@ -294,8 +294,7 @@ > ? ? ? ? VT = getTypeToTransformTo(Context, VT); > ? ? ? ? break; > ? ? ? default: > - ? ? ? ?assert(false && "Type is not legal nor is it to be expanded!"); > - ? ? ? ?return VT; > + ? ? ? ?llvm_unreachable("Type is not legal nor is it to be expanded!"); > ? ? ? } > ? ? } > ? } > @@ -566,8 +565,7 @@ > ? ? if (VT.isInteger()) { > ? ? ? return getRegisterType(Context, getTypeToTransformTo(Context, VT)); > ? ? } > - ? ?assert(0 && "Unsupported extended type!"); > - ? ?return EVT(MVT::Other); // Not reached > + ? ?llvm_unreachable("Unsupported extended type!"); > ? } > > ? /// getNumRegisters - Return the number of registers that this ValueType will > @@ -592,8 +590,7 @@ > ? ? ? unsigned RegWidth = getRegisterType(Context, VT).getSizeInBits(); > ? ? ? return (BitWidth + RegWidth - 1) / RegWidth; > ? ? } > - ? ?assert(0 && "Unsupported extended type!"); > - ? ?return 0; // Not reached > + ? ?llvm_unreachable("Unsupported extended type!"); > ? } > > ? /// ShouldShrinkFPConstant - If true, then instruction selection should > @@ -784,8 +781,7 @@ > ? LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MachineBasicBlock * /*MBB*/, unsigned /*uid*/, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? MCContext &/*Ctx*/) const { > - ? ?assert(0 && "Need to implement this hook if target has custom JTIs"); > - ? ?return 0; > + ? ?llvm_unreachable("Need to implement this hook if target has custom JTIs"); > ? } > > ? /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC > @@ -1210,8 +1206,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ?const SmallVectorImpl &/*Ins*/, > ? ? ? ? ? ? ? ? ? ? ? ? ?DebugLoc /*dl*/, SelectionDAG &/*DAG*/, > ? ? ? ? ? ? ? ? ? ? ? ? ?SmallVectorImpl &/*InVals*/) const { > - ? ?assert(0 && "Not Implemented"); > - ? ?return SDValue(); ? ?// this is here to silence compiler errors > + ? ?llvm_unreachable("Not Implemented"); > ? } > > ? /// LowerCallTo - This function lowers an abstract call to a function into an > @@ -1256,8 +1251,7 @@ > ? ? ? ? ? ? ? const SmallVectorImpl &/*Ins*/, > ? ? ? ? ? ? ? DebugLoc /*dl*/, SelectionDAG &/*DAG*/, > ? ? ? ? ? ? ? SmallVectorImpl &/*InVals*/) const { > - ? ?assert(0 && "Not Implemented"); > - ? ?return SDValue(); ? ?// this is here to silence compiler errors > + ? ?llvm_unreachable("Not Implemented"); > ? } > > ? /// HandleByVal - Target-specific cleanup for formal ByVal parameters. > @@ -1287,8 +1281,7 @@ > ? ? ? ? ? ? ? ? const SmallVectorImpl &/*Outs*/, > ? ? ? ? ? ? ? ? const SmallVectorImpl &/*OutVals*/, > ? ? ? ? ? ? ? ? DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const { > - ? ?assert(0 && "Not Implemented"); > - ? ?return SDValue(); ? ?// this is here to silence compiler errors > + ? ?llvm_unreachable("Not Implemented"); > ? } > > ? /// isUsedByReturnOnly - Return true if result of the specified node is used > @@ -1353,7 +1346,7 @@ > ? virtual void ReplaceNodeResults(SDNode * /*N*/, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SmallVectorImpl &/*Results*/, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SelectionDAG &/*DAG*/) const { > - ? ?assert(0 && "ReplaceNodeResults not implemented for this target!"); > + ? ?llvm_unreachable("ReplaceNodeResults not implemented for this target!"); > ? } > > ? /// getTargetNodeName() - This method returns the name of a target specific > @@ -1939,9 +1932,6 @@ > ? ? // Vectors with illegal element types are expanded. > ? ? EVT NVT = EVT::getVectorVT(Context, EltVT, VT.getVectorNumElements() / 2); > ? ? return LegalizeKind(TypeSplitVector, NVT); > - > - ? ?assert(false && "Unable to handle this kind of vector type"); > - ? ?return LegalizeKind(TypeLegal, VT); > ? } > > ? std::vector > AvailableRegClasses; > > Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) > +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Sun Feb ?5 16:14:15 2012 > @@ -495,8 +495,7 @@ > ? /// values. ?If a target supports multiple different pointer register classes, > ? /// kind specifies which one is indicated. > ? virtual const TargetRegisterClass *getPointerRegClass(unsigned Kind=0) const { > - ? ?assert(0 && "Target didn't implement getPointerRegClass!"); > - ? ?return 0; // Must return a value in order to compile with VS 2005 > + ? ?llvm_unreachable("Target didn't implement getPointerRegClass!"); > ? } > > ? /// getCrossCopyRegClass - Returns a legal register class to copy a register > @@ -633,22 +632,22 @@ > ? virtual void materializeFrameBaseRegister(MachineBasicBlock *MBB, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned BaseReg, int FrameIdx, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int64_t Offset) const { > - ? ?assert(0 && "materializeFrameBaseRegister does not exist on this target"); > + ? ?llvm_unreachable("materializeFrameBaseRegister does not exist on this " > + ? ? ? ? ? ? ? ? ? ? "target"); > ? } > > ? /// resolveFrameIndex - Resolve a frame index operand of an instruction > ? /// to reference the indicated base register plus offset instead. > ? virtual void resolveFrameIndex(MachineBasicBlock::iterator I, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned BaseReg, int64_t Offset) const { > - ? ?assert(0 && "resolveFrameIndex does not exist on this target"); > + ? ?llvm_unreachable("resolveFrameIndex does not exist on this target"); > ? } > > ? /// isFrameOffsetLegal - Determine whether a given offset immediate is > ? /// encodable to resolve a frame index. > ? virtual bool isFrameOffsetLegal(const MachineInstr *MI, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int64_t Offset) const { > - ? ?assert(0 && "isFrameOffsetLegal does not exist on this target"); > - ? ?return false; // Must return a value in order to compile with VS 2005 > + ? ?llvm_unreachable("isFrameOffsetLegal does not exist on this target"); > ? } > > ? /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog > @@ -662,7 +661,8 @@ > ? eliminateCallFramePseudoInstr(MachineFunction &MF, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock &MBB, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MachineBasicBlock::iterator MI) const { > - ? ?assert(0 && "Call Frame Pseudo Instructions do not exist on this target!"); > + ? ?llvm_unreachable("Call Frame Pseudo Instructions do not exist on this " > + ? ? ? ? ? ? ? ? ? ? "target!"); > ? } > > > > Modified: llvm/trunk/include/llvm/User.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/User.h (original) > +++ llvm/trunk/include/llvm/User.h Sun Feb ?5 16:14:15 2012 > @@ -19,6 +19,7 @@ > ?#ifndef LLVM_USER_H > ?#define LLVM_USER_H > > +#include "llvm/Support/ErrorHandling.h" > ?#include "llvm/Value.h" > > ?namespace llvm { > @@ -65,11 +66,11 @@ > ? void operator delete(void *Usr); > ? /// placement delete - required by std, but never called. > ? void operator delete(void*, unsigned) { > - ? ?assert(0 && "Constructor throws?"); > + ? ?llvm_unreachable("Constructor throws?"); > ? } > ? /// placement delete - required by std, but never called. > ? void operator delete(void*, unsigned, bool) { > - ? ?assert(0 && "Constructor throws?"); > + ? ?llvm_unreachable("Constructor throws?"); > ? } > ?protected: > ? template static Use &OpFrom(const U *that) { > > Modified: llvm/trunk/lib/VMCore/Constants.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/lib/VMCore/Constants.cpp (original) > +++ llvm/trunk/lib/VMCore/Constants.cpp Sun Feb ?5 16:14:15 2012 > @@ -117,8 +117,7 @@ > ? ? return ConstantAggregateZero::get(Ty); > ? default: > ? ? // Function, Label, or Opaque type? > - ? ?assert(0 && "Cannot create a null constant of that type!"); > - ? ?return 0; > + ? ?llvm_unreachable("Cannot create a null constant of that type!"); > ? } > ?} > > @@ -2285,7 +2284,7 @@ > ? // The data is stored in host byte order, make sure to cast back to the right > ? // type to load with the right endianness. > ? switch (getElementType()->getIntegerBitWidth()) { > - ?default: assert(0 && "Invalid bitwidth for CDS"); > + ?default: llvm_unreachable("Invalid bitwidth for CDS"); > ? case 8: ?return *(uint8_t*)EltPtr; > ? case 16: return *(uint16_t*)EltPtr; > ? case 32: return *(uint32_t*)EltPtr; > @@ -2300,7 +2299,7 @@ > > ? switch (getElementType()->getTypeID()) { > ? default: > - ? ?assert(0 && "Accessor can only be used when element is float/double!"); > + ? ?llvm_unreachable("Accessor can only be used when element is float/double!"); > ? case Type::FloatTyID: return APFloat(*(float*)EltPtr); > ? case Type::DoubleTyID: return APFloat(*(double*)EltPtr); > ? } > > Modified: llvm/trunk/lib/VMCore/Core.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/lib/VMCore/Core.cpp (original) > +++ llvm/trunk/lib/VMCore/Core.cpp Sun Feb ?5 16:14:15 2012 > @@ -133,8 +133,7 @@ > > ?LLVMTypeKind LLVMGetTypeKind(LLVMTypeRef Ty) { > ? switch (unwrap(Ty)->getTypeID()) { > - ?default: > - ? ?assert(false && "Unhandled TypeID."); > + ?default: llvm_unreachable("Unhandled TypeID."); > ? case Type::VoidTyID: > ? ? return LLVMVoidTypeKind; > ? case Type::HalfTyID: > @@ -680,8 +679,7 @@ > ?static LLVMOpcode map_to_llvmopcode(int opcode) > ?{ > ? ? switch (opcode) { > - ? ? ?default: > - ? ? ? ?assert(0 && "Unhandled Opcode."); > + ? ? ?default: llvm_unreachable("Unhandled Opcode."); > ?#define HANDLE_INST(num, opc, clas) case num: return LLVM##opc; > ?#include "llvm/Instruction.def" > ?#undef HANDLE_INST > > Modified: llvm/trunk/lib/VMCore/Instructions.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/lib/VMCore/Instructions.cpp (original) > +++ llvm/trunk/lib/VMCore/Instructions.cpp Sun Feb ?5 16:14:15 2012 > @@ -1410,8 +1410,7 @@ > ? if (PointerType *PTy = dyn_cast(Ty)) > ? ? return PTy->getAddressSpace(); > > - ?assert(false && "Invalid GEP pointer type"); > - ?return 0; > + ?llvm_unreachable("Invalid GEP pointer type"); > ?} > > ?/// hasAllZeroIndices - Return true if all of the indices of this GEP are > @@ -2079,8 +2078,7 @@ > ? ? ? ? ? ? ? ? ? ? ? ? ? Type *DestTy, > ? ? ? ? ? ? ? ? ? ? ? ? ? Type *IntPtrTy) { > ? switch (Opcode) { > - ? ?default: > - ? ? ?assert(0 && "Invalid CastOp"); > + ? ?default: llvm_unreachable("Invalid CastOp"); > ? ? case Instruction::Trunc: > ? ? case Instruction::ZExt: > ? ? case Instruction::SExt: > @@ -2273,11 +2271,9 @@ > ? ? case 99: > ? ? ? // cast combination can't happen (error in input). This is for all cases > ? ? ? // where the MidTy is not the same for the two cast instructions. > - ? ? ?assert(0 && "Invalid Cast Combination"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("Invalid Cast Combination"); > ? ? default: > - ? ? ?assert(0 && "Error in CastResults table!!!"); > - ? ? ?return 0; > + ? ? ?llvm_unreachable("Error in CastResults table!!!"); > ? } > ?} > > @@ -2298,9 +2294,7 @@ > ? ? case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertBefore); > ? ? case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertBefore); > ? ? case BitCast: ?return new BitCastInst ?(S, Ty, Name, InsertBefore); > - ? ?default: > - ? ? ?assert(0 && "Invalid opcode provided"); > - ? ? ?return 0; > + ? ?default: llvm_unreachable("Invalid opcode provided"); > ? } > ?} > > @@ -2321,9 +2315,7 @@ > ? ? case PtrToInt: return new PtrToIntInst (S, Ty, Name, InsertAtEnd); > ? ? case IntToPtr: return new IntToPtrInst (S, Ty, Name, InsertAtEnd); > ? ? case BitCast: ?return new BitCastInst ?(S, Ty, Name, InsertAtEnd); > - ? ?default: > - ? ? ?assert(0 && "Invalid opcode provided"); > - ? ? ?return 0; > + ? ?default: llvm_unreachable("Invalid opcode provided"); > ? } > ?} > > @@ -2606,17 +2598,17 @@ > ? ? } else if (SrcTy->isIntegerTy()) { > ? ? ? return IntToPtr; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?// int -> ptr > ? ? } else { > - ? ? ?assert(0 && "Casting pointer to other than pointer or int"); > + ? ? ?llvm_unreachable("Casting pointer to other than pointer or int"); > ? ? } > ? } else if (DestTy->isX86_MMXTy()) { > ? ? if (SrcTy->isVectorTy()) { > ? ? ? assert(DestBits == SrcBits && "Casting vector of wrong width to X86_MMX"); > ? ? ? return BitCast; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 64-bit vector to MMX > ? ? } else { > - ? ? ?assert(0 && "Illegal cast to X86_MMX"); > + ? ? ?llvm_unreachable("Illegal cast to X86_MMX"); > ? ? } > ? } else { > - ? ?assert(0 && "Casting to type that is not first-class"); > + ? ?llvm_unreachable("Casting to type that is not first-class"); > ? } > > ? // If we fall through to here we probably hit an assertion cast above > @@ -2938,7 +2930,7 @@ > > ?CmpInst::Predicate CmpInst::getInversePredicate(Predicate pred) { > ? switch (pred) { > - ? ?default: assert(0 && "Unknown cmp predicate!"); > + ? ?default: llvm_unreachable("Unknown cmp predicate!"); > ? ? case ICMP_EQ: return ICMP_NE; > ? ? case ICMP_NE: return ICMP_EQ; > ? ? case ICMP_UGT: return ICMP_ULE; > @@ -2971,7 +2963,7 @@ > > ?ICmpInst::Predicate ICmpInst::getSignedPredicate(Predicate pred) { > ? switch (pred) { > - ? ?default: assert(0 && "Unknown icmp predicate!"); > + ? ?default: llvm_unreachable("Unknown icmp predicate!"); > ? ? case ICMP_EQ: case ICMP_NE: > ? ? case ICMP_SGT: case ICMP_SLT: case ICMP_SGE: case ICMP_SLE: > ? ? ? ?return pred; > @@ -2984,7 +2976,7 @@ > > ?ICmpInst::Predicate ICmpInst::getUnsignedPredicate(Predicate pred) { > ? switch (pred) { > - ? ?default: assert(0 && "Unknown icmp predicate!"); > + ? ?default: llvm_unreachable("Unknown icmp predicate!"); > ? ? case ICMP_EQ: case ICMP_NE: > ? ? case ICMP_UGT: case ICMP_ULT: case ICMP_UGE: case ICMP_ULE: > ? ? ? ?return pred; > @@ -3060,7 +3052,7 @@ > > ?CmpInst::Predicate CmpInst::getSwappedPredicate(Predicate pred) { > ? switch (pred) { > - ? ?default: assert(0 && "Unknown cmp predicate!"); > + ? ?default: llvm_unreachable("Unknown cmp predicate!"); > ? ? case ICMP_EQ: case ICMP_NE: > ? ? ? return pred; > ? ? case ICMP_SGT: return ICMP_SLT; > > Modified: llvm/trunk/lib/VMCore/PassManager.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/PassManager.cpp?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/lib/VMCore/PassManager.cpp (original) > +++ llvm/trunk/lib/VMCore/PassManager.cpp Sun Feb ?5 16:14:15 2012 > @@ -1228,8 +1228,7 @@ > ?} > > ?Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) { > - ?assert(0 && "Unable to find on the fly pass"); > - ?return NULL; > + ?llvm_unreachable("Unable to find on the fly pass"); > ?} > > ?// Destructor > > Modified: llvm/trunk/lib/VMCore/ValueTypes.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ValueTypes.cpp?rev=149849&r1=149848&r2=149849&view=diff > ============================================================================== > --- llvm/trunk/lib/VMCore/ValueTypes.cpp (original) > +++ llvm/trunk/lib/VMCore/ValueTypes.cpp Sun Feb ?5 16:14:15 2012 > @@ -87,8 +87,7 @@ > ? ? return ITy->getBitWidth(); > ? if (VectorType *VTy = dyn_cast(LLVMTy)) > ? ? return VTy->getBitWidth(); > - ?assert(false && "Unrecognized extended type!"); > - ?return 0; // Suppress warnings. > + ?llvm_unreachable("Unrecognized extended type!"); > ?} > > ?/// getEVTString - This function returns value type as a string, e.g. "i32". > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From echristo at apple.com Mon Feb 6 00:54:19 2012 From: echristo at apple.com (Eric Christopher) Date: Sun, 05 Feb 2012 22:54:19 -0800 Subject: [llvm-commits] Fixed a bug in VCMPPS (X86 AVX) pseudo instructions - Please review In-Reply-To: References: Message-ID: <416CAC16-05CB-447A-AD52-0A9A2798FC77@apple.com> On Feb 5, 2012, at 9:24 PM, Craig Topper wrote: > As nothing protects the value written in the intrinsic in the source code. I don't think that having a default case for all unexpected values is the right way to go. Maybe the immediate should be masked to remove the reserved encodings? Or the full value should be printed as an integer if its too big? Sounds good to me. -eric From elena.demikhovsky at intel.com Mon Feb 6 01:05:31 2012 From: elena.demikhovsky at intel.com (Demikhovsky, Elena) Date: Mon, 6 Feb 2012 07:05:31 +0000 Subject: [llvm-commits] Fixed a bug in VCMPPS (X86 AVX) pseudo instructions - Please review In-Reply-To: <416CAC16-05CB-447A-AD52-0A9A2798FC77@apple.com> References: <416CAC16-05CB-447A-AD52-0A9A2798FC77@apple.com> Message-ID: According to AVX spec only 5 bits are taken, other just ignored. But you do not expect that clang or another user writes a bigger number. It sounds like a bug in compiler or user code. And the better way is indicating that value is unexpected then just truncating it. - Elena -----Original Message----- From: Eric Christopher [mailto:echristo at apple.com] Sent: Monday, February 06, 2012 08:54 To: Craig Topper Cc: Demikhovsky, Elena; llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] Fixed a bug in VCMPPS (X86 AVX) pseudo instructions - Please review On Feb 5, 2012, at 9:24 PM, Craig Topper wrote: > As nothing protects the value written in the intrinsic in the source code. I don't think that having a default case for all unexpected values is the right way to go. Maybe the immediate should be masked to remove the reserved encodings? Or the full value should be printed as an integer if its too big? Sounds good to me. -eric --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From bob.wilson at apple.com Mon Feb 6 01:09:37 2012 From: bob.wilson at apple.com (Bob Wilson) Date: Sun, 05 Feb 2012 23:09:37 -0800 Subject: [llvm-commits] [llvm] r149800 - in /llvm/trunk: include/llvm/ include/llvm/Analysis/ lib/Analysis/ lib/AsmParser/ lib/Bitcode/Writer/ lib/CodeGen/AsmPrinter/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Target/CppBackend/ lib/Transforms/Instrumentation/ lib/Transforms/Scalar/ lib/VMCore/ tools/bugpoint/ tools/lto/ In-Reply-To: <6A690A30-20CD-4437-8E9F-3A9506171A5C@apple.com> References: <20120205022944.D667F2A6C12C@llvm.org> <4F2E467B.9020802@free.fr> <6A690A30-20CD-4437-8E9F-3A9506171A5C@apple.com> Message-ID: <8FF98670-8734-4A5E-AA51-EB46A1A2C86B@apple.com> My llvm-gcc nightly tester has been continuing to find different problems than the clang testers (e.g., most recently the lack of auto-upgrade support for some intrinsics that were removed). But, I don't have time to keep it working, and I think the time has come to let it die. On Feb 5, 2012, at 2:07 AM, Chad Rosier wrote: > Hi Duncan, > > On Feb 5, 2012, at 1:06 AM, Duncan Sands wrote: > >> Hi Chad, >> >>> This commit is causing our llvm-gcc build bot to fail at stage 1. >> >> I'm getting rid of the two llvm-gcc buildbots >> >> http://lab.llvm.org:8011/builders/llvm-gcc-i386-linux-selfhost >> http://lab.llvm.org:8011/builders/llvm-x86_64-linux-checks >> >> today. Do we really want to keep any llvm-gcc buildbots? > > I personally have no problem with killing off the buildbots. Bob keeps reviving llvm-gcc, so I went ahead and CC'ed him to see if he had an opinion on the matter. > > Chad > > >> Ciao, Duncan. >> >>> >>> ../../llvm-gcc.src/gcc/llvm-backend.cpp: In function 'void readLLVMValues()': >>> >>> ../../llvm-gcc.src/gcc/llvm-backend.cpp:282: error:'class llvm::ConstantArray' has no member named'getAsString' >>> ../../llvm-gcc.src/gcc/llvm-backend.cpp: In function'llvm::Constant* ConvertMetadataStringToGV(const char*)': >>> ../../llvm-gcc.src/gcc/llvm-backend.cpp:1302: error: no matching function for call to'llvm::ConstantArray::get(llvm::LLVMContext&, std::string)' >>> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.llvm-gcc-i386-darwin9-RA/llvm.src/include/llvm/Constants.h:353: note: candidates are: static llvm::Constant* llvm::ConstantArray::get(llvm::ArrayType*, llvm::ArrayRef) >>> >>> Chad >>> >>> On Feb 4, 2012, at 6:29 PM, Chris Lattner wrote: >>> >>>> Author: lattner >>>> Date: Sat Feb 4 20:29:43 2012 >>>> New Revision: 149800 >>>> >>>> URL: http://llvm.org/viewvc/llvm-project?rev=149800&view=rev >>>> >>>> Log: >>>> reapply the patches reverted in r149470 that reenable ConstantDataArray, >>>> but with a critical fix to the SelectionDAG code that optimizes copies >>>> from strings into immediate stores: the previous code was stopping reading >>>> string data at the first nul. Address this by adding a new argument to >>>> llvm::getConstantStringInfo, preserving the behavior before the patch. >>>> >>>> >>>> Modified: >>>> llvm/trunk/include/llvm/Analysis/ValueTracking.h >>>> llvm/trunk/include/llvm/Constants.h >>>> llvm/trunk/lib/Analysis/ConstantFolding.cpp >>>> llvm/trunk/lib/Analysis/ValueTracking.cpp >>>> llvm/trunk/lib/AsmParser/LLParser.cpp >>>> llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp >>>> llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp >>>> llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp >>>> llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp >>>> llvm/trunk/lib/Target/CBackend/CBackend.cpp >>>> llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp >>>> llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp >>>> llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp >>>> llvm/trunk/lib/VMCore/AsmWriter.cpp >>>> llvm/trunk/lib/VMCore/Constants.cpp >>>> llvm/trunk/lib/VMCore/Core.cpp >>>> llvm/trunk/lib/VMCore/IRBuilder.cpp >>>> llvm/trunk/tools/bugpoint/Miscompilation.cpp >>>> llvm/trunk/tools/lto/LTOModule.cpp >>>> >>>> Modified: llvm/trunk/include/llvm/Analysis/ValueTracking.h >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ValueTracking.h?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/include/llvm/Analysis/ValueTracking.h (original) >>>> +++ llvm/trunk/include/llvm/Analysis/ValueTracking.h Sat Feb 4 20:29:43 2012 >>>> @@ -17,14 +17,13 @@ >>>> >>>> #include "llvm/ADT/ArrayRef.h" >>>> #include "llvm/Support/DataTypes.h" >>>> -#include >>>> >>>> namespace llvm { >>>> - template class SmallVectorImpl; >>>> class Value; >>>> class Instruction; >>>> class APInt; >>>> class TargetData; >>>> + class StringRef; >>>> >>>> /// ComputeMaskedBits - Determine which of the bits specified in Mask are >>>> /// known to be either zero or one and return them in the KnownZero/KnownOne >>>> @@ -125,16 +124,15 @@ >>>> return GetPointerBaseWithConstantOffset(const_cast(Ptr), Offset,TD); >>>> } >>>> >>>> - /// GetConstantStringInfo - This function computes the length of a >>>> + /// getConstantStringInfo - This function computes the length of a >>>> /// null-terminated C string pointed to by V. If successful, it returns true >>>> - /// and returns the string in Str. If unsuccessful, it returns false. If >>>> - /// StopAtNul is set to true (the default), the returned string is truncated >>>> - /// by a nul character in the global. If StopAtNul is false, the nul >>>> - /// character is included in the result string. >>>> - bool GetConstantStringInfo(const Value *V, std::string &Str, >>>> - uint64_t Offset = 0, >>>> - bool StopAtNul = true); >>>> - >>>> + /// and returns the string in Str. If unsuccessful, it returns false. This >>>> + /// does not include the trailing nul character by default. If TrimAtNul is >>>> + /// set to false, then this returns any trailing nul characters as well as any >>>> + /// other characters that come after it. >>>> + bool getConstantStringInfo(const Value *V, StringRef &Str, >>>> + uint64_t Offset = 0, bool TrimAtNul = true); >>>> + >>>> /// GetStringLength - If we can compute the length of the string pointed to by >>>> /// the specified pointer, return 'len+1'. If we can't, return 0. >>>> uint64_t GetStringLength(Value *V); >>>> >>>> Modified: llvm/trunk/include/llvm/Constants.h >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Constants.h?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/include/llvm/Constants.h (original) >>>> +++ llvm/trunk/include/llvm/Constants.h Sat Feb 4 20:29:43 2012 >>>> @@ -352,17 +352,6 @@ >>>> // ConstantArray accessors >>>> static Constant *get(ArrayType *T, ArrayRef V); >>>> >>>> - /// This method constructs a ConstantArray and initializes it with a text >>>> - /// string. The default behavior (AddNull==true) causes a null terminator to >>>> - /// be placed at the end of the array. This effectively increases the length >>>> - /// of the array by one (you've been warned). However, in some situations >>>> - /// this is not desired so if AddNull==false then the string is copied without >>>> - /// null termination. >>>> - >>>> - // FIXME Remove this. >>>> - static Constant *get(LLVMContext &Context, StringRef Initializer, >>>> - bool AddNull = true); >>>> - >>>> /// Transparently provide more efficient getOperand methods. >>>> DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant); >>>> >>>> @@ -373,31 +362,6 @@ >>>> return reinterpret_cast(Value::getType()); >>>> } >>>> >>>> - // FIXME: String methods will eventually be removed. >>>> - >>>> - >>>> - /// isString - This method returns true if the array is an array of i8 and >>>> - /// the elements of the array are all ConstantInt's. >>>> - bool isString() const; >>>> - >>>> - /// isCString - This method returns true if the array is a string (see >>>> - /// @verbatim >>>> - /// isString) and it ends in a null byte \0 and does not contains any other >>>> - /// @endverbatim >>>> - /// null bytes except its terminator. >>>> - bool isCString() const; >>>> - >>>> - /// getAsString - If this array is isString(), then this method converts the >>>> - /// array to an std::string and returns it. Otherwise, it asserts out. >>>> - /// >>>> - std::string getAsString() const; >>>> - >>>> - /// getAsCString - If this array is isCString(), then this method converts the >>>> - /// array (without the trailing null byte) to an std::string and returns it. >>>> - /// Otherwise, it asserts out. >>>> - /// >>>> - std::string getAsCString() const; >>>> - >>>> virtual void destroyConstant(); >>>> virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U); >>>> >>>> >>>> Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) >>>> +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -476,9 +476,9 @@ >>>> >>>> // Instead of loading constant c string, use corresponding integer value >>>> // directly if string length is small enough. >>>> - std::string Str; >>>> - if (TD && GetConstantStringInfo(CE, Str) && !Str.empty()) { >>>> - unsigned StrLen = Str.length(); >>>> + StringRef Str; >>>> + if (TD && getConstantStringInfo(CE, Str) && !Str.empty()) { >>>> + unsigned StrLen = Str.size(); >>>> Type *Ty = cast(CE->getType())->getElementType(); >>>> unsigned NumBits = Ty->getPrimitiveSizeInBits(); >>>> // Replace load with immediate integer if the result is an integer or fp >>>> >>>> Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) >>>> +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -1369,25 +1369,21 @@ >>>> } >>>> } >>>> >>>> - // A ConstantArray is splatable if all its members are equal and also >>>> - // splatable. >>>> - if (ConstantArray *CA = dyn_cast(V)) { >>>> - if (CA->getNumOperands() == 0) >>>> - return 0; >>>> - >>>> - Value *Val = isBytewiseValue(CA->getOperand(0)); >>>> + // A ConstantDataArray/Vector is splatable if all its members are equal and >>>> + // also splatable. >>>> + if (ConstantDataSequential *CA = dyn_cast(V)) { >>>> + Value *Elt = CA->getElementAsConstant(0); >>>> + Value *Val = isBytewiseValue(Elt); >>>> if (!Val) >>>> return 0; >>>> >>>> - for (unsigned I = 1, E = CA->getNumOperands(); I != E; ++I) >>>> - if (CA->getOperand(I-1) != CA->getOperand(I)) >>>> + for (unsigned I = 1, E = CA->getNumElements(); I != E; ++I) >>>> + if (CA->getElementAsConstant(I) != Elt) >>>> return 0; >>>> >>>> return Val; >>>> } >>>> >>>> - // FIXME: Vector types (e.g., <4 x i32> ). >>>> - >>>> // Conceptually, we could handle things like: >>>> // %a = zext i8 %X to i16 >>>> // %b = shl i16 %a, 8 >>>> @@ -1607,33 +1603,19 @@ >>>> } >>>> >>>> >>>> -/// GetConstantStringInfo - This function computes the length of a >>>> +/// getConstantStringInfo - This function computes the length of a >>>> /// null-terminated C string pointed to by V. If successful, it returns true >>>> /// and returns the string in Str. If unsuccessful, it returns false. >>>> -bool llvm::GetConstantStringInfo(const Value *V, std::string &Str, >>>> - uint64_t Offset, bool StopAtNul) { >>>> - // If V is NULL then return false; >>>> - if (V == NULL) return false; >>>> - >>>> - // Look through bitcast instructions. >>>> - if (const BitCastInst *BCI = dyn_cast(V)) >>>> - return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul); >>>> - >>>> - // If the value is not a GEP instruction nor a constant expression with a >>>> - // GEP instruction, then return false because ConstantArray can't occur >>>> - // any other way. >>>> - const User *GEP = 0; >>>> - if (const GetElementPtrInst *GEPI = dyn_cast(V)) { >>>> - GEP = GEPI; >>>> - } else if (const ConstantExpr *CE = dyn_cast(V)) { >>>> - if (CE->getOpcode() == Instruction::BitCast) >>>> - return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul); >>>> - if (CE->getOpcode() != Instruction::GetElementPtr) >>>> - return false; >>>> - GEP = CE; >>>> - } >>>> - >>>> - if (GEP) { >>>> +bool llvm::getConstantStringInfo(const Value *V, StringRef &Str, >>>> + uint64_t Offset, bool TrimAtNul) { >>>> + assert(V); >>>> + >>>> + // Look through bitcast instructions and geps. >>>> + V = V->stripPointerCasts(); >>>> + >>>> + // If the value is a GEP instructionor constant expression, treat it as an >>>> + // offset. >>>> + if (const GEPOperator *GEP = dyn_cast(V)) { >>>> // Make sure the GEP has exactly three arguments. >>>> if (GEP->getNumOperands() != 3) >>>> return false; >>>> @@ -1658,51 +1640,48 @@ >>>> StartIdx = CI->getZExtValue(); >>>> else >>>> return false; >>>> - return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset, >>>> - StopAtNul); >>>> + return getConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset); >>>> } >>>> >>>> // The GEP instruction, constant or instruction, must reference a global >>>> // variable that is a constant and is initialized. The referenced constant >>>> // initializer is the array that we'll use for optimization. >>>> - const GlobalVariable* GV = dyn_cast(V); >>>> + const GlobalVariable *GV = dyn_cast(V); >>>> if (!GV || !GV->isConstant() || !GV->hasDefinitiveInitializer()) >>>> return false; >>>> - const Constant *GlobalInit = GV->getInitializer(); >>>> - >>>> + >>>> // Handle the all-zeros case >>>> - if (GlobalInit->isNullValue()) { >>>> + if (GV->getInitializer()->isNullValue()) { >>>> // This is a degenerate case. The initializer is constant zero so the >>>> // length of the string must be zero. >>>> - Str.clear(); >>>> + Str = ""; >>>> return true; >>>> } >>>> >>>> // Must be a Constant Array >>>> - const ConstantArray *Array = dyn_cast(GlobalInit); >>>> - if (Array == 0 || !Array->getType()->getElementType()->isIntegerTy(8)) >>>> + const ConstantDataArray *Array = >>>> + dyn_cast(GV->getInitializer()); >>>> + if (Array == 0 || !Array->isString()) >>>> return false; >>>> >>>> // Get the number of elements in the array >>>> - uint64_t NumElts = Array->getType()->getNumElements(); >>>> - >>>> + uint64_t NumElts = Array->getType()->getArrayNumElements(); >>>> + >>>> + // Start out with the entire array in the StringRef. >>>> + Str = Array->getAsString(); >>>> + >>>> if (Offset > NumElts) >>>> return false; >>>> >>>> - // Traverse the constant array from 'Offset' which is the place the GEP refers >>>> - // to in the array. >>>> - Str.reserve(NumElts-Offset); >>>> - for (unsigned i = Offset; i != NumElts; ++i) { >>>> - const Constant *Elt = Array->getOperand(i); >>>> - const ConstantInt *CI = dyn_cast(Elt); >>>> - if (!CI) // This array isn't suitable, non-int initializer. >>>> - return false; >>>> - if (StopAtNul && CI->isZero()) >>>> - return true; // we found end of string, success! >>>> - Str += (char)CI->getZExtValue(); >>>> - } >>>> + // Skip over 'offset' bytes. >>>> + Str = Str.substr(Offset); >>>> >>>> - // The array isn't null terminated, but maybe this is a memcpy, not a strcpy. >>>> + if (TrimAtNul) { >>>> + // Trim off the \0 and anything after it. If the array is not nul >>>> + // terminated, we just return the whole end of string. The client may know >>>> + // some other way that the string is length-bound. >>>> + Str = Str.substr(0, Str.find('\0')); >>>> + } >>>> return true; >>>> } >>>> >>>> @@ -1714,8 +1693,7 @@ >>>> /// the specified pointer, return 'len+1'. If we can't, return 0. >>>> static uint64_t GetStringLengthH(Value *V, SmallPtrSet &PHIs) { >>>> // Look through noop bitcast instructions. >>>> - if (BitCastInst *BCI = dyn_cast(V)) >>>> - return GetStringLengthH(BCI->getOperand(0), PHIs); >>>> + V = V->stripPointerCasts(); >>>> >>>> // If this is a PHI node, there are two cases: either we have already seen it >>>> // or we haven't. >>>> @@ -1751,83 +1729,13 @@ >>>> if (Len1 != Len2) return 0; >>>> return Len1; >>>> } >>>> - >>>> - // As a special-case, "@string = constant i8 0" is also a string with zero >>>> - // length, not wrapped in a bitcast or GEP. >>>> - if (GlobalVariable *GV = dyn_cast(V)) { >>>> - if (GV->isConstant() && GV->hasDefinitiveInitializer()) >>>> - if (GV->getInitializer()->isNullValue()) return 1; >>>> - return 0; >>>> - } >>>> - >>>> - // If the value is not a GEP instruction nor a constant expression with a >>>> - // GEP instruction, then return unknown. >>>> - User *GEP = 0; >>>> - if (GetElementPtrInst *GEPI = dyn_cast(V)) { >>>> - GEP = GEPI; >>>> - } else if (ConstantExpr *CE = dyn_cast(V)) { >>>> - if (CE->getOpcode() != Instruction::GetElementPtr) >>>> - return 0; >>>> - GEP = CE; >>>> - } else { >>>> - return 0; >>>> - } >>>> - >>>> - // Make sure the GEP has exactly three arguments. >>>> - if (GEP->getNumOperands() != 3) >>>> - return 0; >>>> - >>>> - // Check to make sure that the first operand of the GEP is an integer and >>>> - // has value 0 so that we are sure we're indexing into the initializer. >>>> - if (ConstantInt *Idx = dyn_cast(GEP->getOperand(1))) { >>>> - if (!Idx->isZero()) >>>> - return 0; >>>> - } else >>>> - return 0; >>>> - >>>> - // If the second index isn't a ConstantInt, then this is a variable index >>>> - // into the array. If this occurs, we can't say anything meaningful about >>>> - // the string. >>>> - uint64_t StartIdx = 0; >>>> - if (ConstantInt *CI = dyn_cast(GEP->getOperand(2))) >>>> - StartIdx = CI->getZExtValue(); >>>> - else >>>> - return 0; >>>> - >>>> - // The GEP instruction, constant or instruction, must reference a global >>>> - // variable that is a constant and is initialized. The referenced constant >>>> - // initializer is the array that we'll use for optimization. >>>> - GlobalVariable* GV = dyn_cast(GEP->getOperand(0)); >>>> - if (!GV || !GV->isConstant() || !GV->hasInitializer() || >>>> - GV->mayBeOverridden()) >>>> + >>>> + // Otherwise, see if we can read the string. >>>> + StringRef StrData; >>>> + if (!getConstantStringInfo(V, StrData)) >>>> return 0; >>>> - Constant *GlobalInit = GV->getInitializer(); >>>> - >>>> - // Handle the ConstantAggregateZero case, which is a degenerate case. The >>>> - // initializer is constant zero so the length of the string must be zero. >>>> - if (isa(GlobalInit)) >>>> - return 1; // Len = 0 offset by 1. >>>> - >>>> - // Must be a Constant Array >>>> - ConstantArray *Array = dyn_cast(GlobalInit); >>>> - if (!Array || !Array->getType()->getElementType()->isIntegerTy(8)) >>>> - return false; >>>> - >>>> - // Get the number of elements in the array >>>> - uint64_t NumElts = Array->getType()->getNumElements(); >>>> - >>>> - // Traverse the constant array from StartIdx (derived above) which is >>>> - // the place the GEP refers to in the array. >>>> - for (unsigned i = StartIdx; i != NumElts; ++i) { >>>> - Constant *Elt = Array->getOperand(i); >>>> - ConstantInt *CI = dyn_cast(Elt); >>>> - if (!CI) // This array isn't suitable, non-int initializer. >>>> - return 0; >>>> - if (CI->isZero()) >>>> - return i-StartIdx+1; // We found end of string, success! >>>> - } >>>> >>>> - return 0; // The array isn't null terminated, conservatively return 'unknown'. >>>> + return StrData.size()+1; >>>> } >>>> >>>> /// GetStringLength - If we can compute the length of the string pointed to by >>>> >>>> Modified: llvm/trunk/lib/AsmParser/LLParser.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) >>>> +++ llvm/trunk/lib/AsmParser/LLParser.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -2018,7 +2018,8 @@ >>>> } >>>> case lltok::kw_c: // c "foo" >>>> Lex.Lex(); >>>> - ID.ConstantVal = ConstantArray::get(Context, Lex.getStrVal(), false); >>>> + ID.ConstantVal = ConstantDataArray::getString(Context, Lex.getStrVal(), >>>> + false); >>>> if (ParseToken(lltok::StringConstant, "expected string")) return true; >>>> ID.Kind = ValID::t_Constant; >>>> return false; >>>> >>>> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) >>>> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -845,32 +845,6 @@ >>>> } else { >>>> assert (0 && "Unknown FP type!"); >>>> } >>>> - } else if (isa(C) && cast(C)->isString()) { >>>> - const ConstantArray *CA = cast(C); >>>> - // Emit constant strings specially. >>>> - unsigned NumOps = CA->getNumOperands(); >>>> - // If this is a null-terminated string, use the denser CSTRING encoding. >>>> - if (CA->getOperand(NumOps-1)->isNullValue()) { >>>> - Code = bitc::CST_CODE_CSTRING; >>>> - --NumOps; // Don't encode the null, which isn't allowed by char6. >>>> - } else { >>>> - Code = bitc::CST_CODE_STRING; >>>> - AbbrevToUse = String8Abbrev; >>>> - } >>>> - bool isCStr7 = Code == bitc::CST_CODE_CSTRING; >>>> - bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING; >>>> - for (unsigned i = 0; i != NumOps; ++i) { >>>> - unsigned char V = cast(CA->getOperand(i))->getZExtValue(); >>>> - Record.push_back(V); >>>> - isCStr7 &= (V & 128) == 0; >>>> - if (isCStrChar6) >>>> - isCStrChar6 = BitCodeAbbrevOp::isChar6(V); >>>> - } >>>> - >>>> - if (isCStrChar6) >>>> - AbbrevToUse = CString6Abbrev; >>>> - else if (isCStr7) >>>> - AbbrevToUse = CString7Abbrev; >>>> } else if (isa(C) && >>>> cast(C)->isString()) { >>>> const ConstantDataSequential *Str = cast(C); >>>> >>>> Modified: llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp (original) >>>> +++ llvm/trunk/lib/Bitcode/Writer/ValueEnumerator.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -321,10 +321,6 @@ >>>> if (const Constant *C = dyn_cast(V)) { >>>> if (isa(C)) { >>>> // Initializers for globals are handled explicitly elsewhere. >>>> - } else if (isa(C) && cast(C)->isString()) { >>>> - // Do not enumerate the initializers for an array of simple characters. >>>> - // The initializers just pollute the value table, and we emit the strings >>>> - // specially. >>>> } else if (C->getNumOperands()) { >>>> // If a constant has operands, enumerate them. This makes sure that if a >>>> // constant has uses (for example an array of const ints), that they are >>>> >>>> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original) >>>> +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -1684,31 +1684,18 @@ >>>> >>>> static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, >>>> AsmPrinter &AP) { >>>> - if (AddrSpace != 0 || !CA->isString()) { >>>> - // Not a string. Print the values in successive locations. >>>> - >>>> - // See if we can aggregate some values. Make sure it can be >>>> - // represented as a series of bytes of the constant value. >>>> - int Value = isRepeatedByteSequence(CA, AP.TM); >>>> - >>>> - if (Value != -1) { >>>> - uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType()); >>>> - AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); >>>> - } >>>> - else { >>>> - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) >>>> - EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); >>>> - } >>>> - return; >>>> + // See if we can aggregate some values. Make sure it can be >>>> + // represented as a series of bytes of the constant value. >>>> + int Value = isRepeatedByteSequence(CA, AP.TM); >>>> + >>>> + if (Value != -1) { >>>> + uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType()); >>>> + AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace); >>>> + } >>>> + else { >>>> + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) >>>> + EmitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP); >>>> } >>>> - >>>> - // Otherwise, it can be emitted as .ascii. >>>> - SmallVector TmpVec; >>>> - TmpVec.reserve(CA->getNumOperands()); >>>> - for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) >>>> - TmpVec.push_back(cast(CA->getOperand(i))->getZExtValue()); >>>> - >>>> - AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace); >>>> } >>>> >>>> static void EmitGlobalConstantVector(const ConstantVector *CV, >>>> >>>> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original) >>>> +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -3298,8 +3298,7 @@ >>>> /// used when a memcpy is turned into a memset when the source is a constant >>>> /// string ptr. >>>> static SDValue getMemsetStringVal(EVT VT, DebugLoc dl, SelectionDAG &DAG, >>>> - const TargetLowering &TLI, >>>> - std::string &Str, unsigned Offset) { >>>> + const TargetLowering &TLI, StringRef Str) { >>>> // Handle vector with all elements zero. >>>> if (Str.empty()) { >>>> if (VT.isInteger()) >>>> @@ -3317,15 +3316,18 @@ >>>> } >>>> >>>> assert(!VT.isVector() && "Can't handle vector type here!"); >>>> - unsigned NumBits = VT.getSizeInBits(); >>>> - unsigned MSB = NumBits / 8; >>>> + unsigned NumVTBytes = VT.getSizeInBits() / 8; >>>> + unsigned NumBytes = std::min(NumVTBytes, unsigned(Str.size())); >>>> + >>>> uint64_t Val = 0; >>>> - if (TLI.isLittleEndian()) >>>> - Offset = Offset + MSB - 1; >>>> - for (unsigned i = 0; i != MSB; ++i) { >>>> - Val = (Val << 8) | (unsigned char)Str[Offset]; >>>> - Offset += TLI.isLittleEndian() ? -1 : 1; >>>> + if (TLI.isLittleEndian()) { >>>> + for (unsigned i = 0; i != NumBytes; ++i) >>>> + Val |= (uint64_t)(unsigned char)Str[i] << i*8; >>>> + } else { >>>> + for (unsigned i = 0; i != NumBytes; ++i) >>>> + Val |= (uint64_t)(unsigned char)Str[i] << (NumVTBytes-i-1)*8; >>>> } >>>> + >>>> return DAG.getConstant(Val, VT); >>>> } >>>> >>>> @@ -3340,7 +3342,7 @@ >>>> >>>> /// isMemSrcFromString - Returns true if memcpy source is a string constant. >>>> /// >>>> -static bool isMemSrcFromString(SDValue Src, std::string &Str) { >>>> +static bool isMemSrcFromString(SDValue Src, StringRef &Str) { >>>> unsigned SrcDelta = 0; >>>> GlobalAddressSDNode *G = NULL; >>>> if (Src.getOpcode() == ISD::GlobalAddress) >>>> @@ -3354,11 +3356,7 @@ >>>> if (!G) >>>> return false; >>>> >>>> - const GlobalVariable *GV = dyn_cast(G->getGlobal()); >>>> - if (GV && GetConstantStringInfo(GV, Str, SrcDelta, false)) >>>> - return true; >>>> - >>>> - return false; >>>> + return getConstantStringInfo(G->getGlobal(), Str, SrcDelta, false); >>>> } >>>> >>>> /// FindOptimalMemOpLowering - Determines the optimial series memory ops >>>> @@ -3461,7 +3459,7 @@ >>>> unsigned SrcAlign = DAG.InferPtrAlignment(Src); >>>> if (Align > SrcAlign) >>>> SrcAlign = Align; >>>> - std::string Str; >>>> + StringRef Str; >>>> bool CopyFromStr = isMemSrcFromString(Src, Str); >>>> bool isZeroStr = CopyFromStr && Str.empty(); >>>> unsigned Limit = AlwaysInline ? ~0U : TLI.getMaxStoresPerMemcpy(OptSize); >>>> @@ -3498,7 +3496,7 @@ >>>> // We only handle zero vectors here. >>>> // FIXME: Handle other cases where store of vector immediate is done in >>>> // a single instruction. >>>> - Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff); >>>> + Value = getMemsetStringVal(VT, dl, DAG, TLI, Str.substr(SrcOff)); >>>> Store = DAG.getStore(Chain, dl, Value, >>>> getMemBasePlusOffset(Dst, DstOff, DAG), >>>> DstPtrInfo.getWithOffset(DstOff), isVol, >>>> >>>> Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) >>>> +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -558,73 +558,21 @@ >>>> } >>>> >>>> void CWriter::printConstantArray(ConstantArray *CPA, bool Static) { >>>> - // As a special case, print the array as a string if it is an array of >>>> - // ubytes or an array of sbytes with positive values. >>>> - // >>>> - if (CPA->isCString()) { >>>> - Out << '\"'; >>>> - // Keep track of whether the last number was a hexadecimal escape. >>>> - bool LastWasHex = false; >>>> - >>>> - // Do not include the last character, which we know is null >>>> - for (unsigned i = 0, e = CPA->getNumOperands()-1; i != e; ++i) { >>>> - unsigned char C = cast(CPA->getOperand(i))->getZExtValue(); >>>> - >>>> - // Print it out literally if it is a printable character. The only thing >>>> - // to be careful about is when the last letter output was a hex escape >>>> - // code, in which case we have to be careful not to print out hex digits >>>> - // explicitly (the C compiler thinks it is a continuation of the previous >>>> - // character, sheesh...) >>>> - // >>>> - if (isprint(C) && (!LastWasHex || !isxdigit(C))) { >>>> - LastWasHex = false; >>>> - if (C == '"' || C == '\\') >>>> - Out << "\\" << (char)C; >>>> - else >>>> - Out << (char)C; >>>> - } else { >>>> - LastWasHex = false; >>>> - switch (C) { >>>> - case '\n': Out << "\\n "; break; >>>> - case '\t': Out << "\\t "; break; >>>> - case '\r': Out << "\\r "; break; >>>> - case '\v': Out << "\\v "; break; >>>> - case '\a': Out << "\\a "; break; >>>> - case '\"': Out << "\\\""; break; >>>> - case '\'': Out << "\\\'"; break; >>>> - default: >>>> - Out << "\\x "; >>>> - Out << (char)(( C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A')); >>>> - Out << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A')); >>>> - LastWasHex = true; >>>> - break; >>>> - } >>>> - } >>>> - } >>>> - Out << '\"'; >>>> - } else { >>>> - Out << '{'; >>>> - if (CPA->getNumOperands()) { >>>> - Out << ' '; >>>> - printConstant(cast(CPA->getOperand(0)), Static); >>>> - for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) { >>>> - Out << ", "; >>>> - printConstant(cast(CPA->getOperand(i)), Static); >>>> - } >>>> - } >>>> - Out << " }"; >>>> + Out << "{ "; >>>> + printConstant(cast(CPA->getOperand(0)), Static); >>>> + for (unsigned i = 1, e = CPA->getNumOperands(); i != e; ++i) { >>>> + Out << ", "; >>>> + printConstant(cast(CPA->getOperand(i)), Static); >>>> } >>>> + Out << " }"; >>>> } >>>> >>>> void CWriter::printConstantVector(ConstantVector *CP, bool Static) { >>>> - Out << '{'; >>>> - if (CP->getNumOperands()) { >>>> - Out << ' '; >>>> - printConstant(cast(CP->getOperand(0)), Static); >>>> - for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { >>>> - Out << ", "; >>>> - printConstant(cast(CP->getOperand(i)), Static); >>>> - } >>>> + Out << "{ "; >>>> + printConstant(cast(CP->getOperand(0)), Static); >>>> + for (unsigned i = 1, e = CP->getNumOperands(); i != e; ++i) { >>>> + Out << ", "; >>>> + printConstant(cast(CP->getOperand(i)), Static); >>>> } >>>> Out << " }"; >>>> } >>>> >>>> Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) >>>> +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -698,36 +698,17 @@ >>>> printCFP(CFP); >>>> Out << ";"; >>>> } else if (const ConstantArray *CA = dyn_cast(CV)) { >>>> - if (CA->isString()) { >>>> - Out << "Constant* " << constName << >>>> - " = ConstantArray::get(mod->getContext(), \""; >>>> - std::string tmp = CA->getAsString(); >>>> - bool nullTerminate = false; >>>> - if (tmp[tmp.length()-1] == 0) { >>>> - tmp.erase(tmp.length()-1); >>>> - nullTerminate = true; >>>> - } >>>> - printEscapedString(tmp); >>>> - // Determine if we want null termination or not. >>>> - if (nullTerminate) >>>> - Out << "\", true"; // Indicate that the null terminator should be >>>> - // added. >>>> - else >>>> - Out << "\", false";// No null terminator >>>> - Out << ");"; >>>> - } else { >>>> - Out << "std::vector " << constName << "_elems;"; >>>> + Out << "std::vector " << constName << "_elems;"; >>>> + nl(Out); >>>> + unsigned N = CA->getNumOperands(); >>>> + for (unsigned i = 0; i < N; ++i) { >>>> + printConstant(CA->getOperand(i)); // recurse to print operands >>>> + Out << constName << "_elems.push_back(" >>>> + << getCppName(CA->getOperand(i)) << ");"; >>>> nl(Out); >>>> - unsigned N = CA->getNumOperands(); >>>> - for (unsigned i = 0; i < N; ++i) { >>>> - printConstant(CA->getOperand(i)); // recurse to print operands >>>> - Out << constName << "_elems.push_back(" >>>> - << getCppName(CA->getOperand(i)) << ");"; >>>> - nl(Out); >>>> - } >>>> - Out << "Constant* " << constName << " = ConstantArray::get(" >>>> - << typeName << ", " << constName << "_elems);"; >>>> } >>>> + Out << "Constant* " << constName << " = ConstantArray::get(" >>>> + << typeName << ", " << constName << "_elems);"; >>>> } else if (const ConstantStruct *CS = dyn_cast(CV)) { >>>> Out << "std::vector " << constName << "_fields;"; >>>> nl(Out); >>>> @@ -740,14 +721,14 @@ >>>> } >>>> Out << "Constant* " << constName << " = ConstantStruct::get(" >>>> << typeName << ", " << constName << "_fields);"; >>>> - } else if (const ConstantVector *CP = dyn_cast(CV)) { >>>> + } else if (const ConstantVector *CV = dyn_cast(CV)) { >>>> Out << "std::vector " << constName << "_elems;"; >>>> nl(Out); >>>> - unsigned N = CP->getNumOperands(); >>>> + unsigned N = CV->getNumOperands(); >>>> for (unsigned i = 0; i < N; ++i) { >>>> - printConstant(CP->getOperand(i)); >>>> + printConstant(CV->getOperand(i)); >>>> Out << constName << "_elems.push_back(" >>>> - << getCppName(CP->getOperand(i)) << ");"; >>>> + << getCppName(CV->getOperand(i)) << ");"; >>>> nl(Out); >>>> } >>>> Out << "Constant* " << constName << " = ConstantVector::get(" >>>> @@ -760,7 +741,7 @@ >>>> if (CDS->isString()) { >>>> Out << "Constant *" << constName << >>>> " = ConstantDataArray::getString(mod->getContext(), \""; >>>> - StringRef Str = CA->getAsString(); >>>> + StringRef Str = CDS->getAsString(); >>>> bool nullTerminate = false; >>>> if (Str.back() == 0) { >>>> Str = Str.drop_back(); >>>> >>>> Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original) >>>> +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Sat Feb 4 >>>> 20:29:43 2012 >>>> @@ -213,7 +213,7 @@ >>>> >>>> // Create a constant for Str so that we can pass it to the run-time lib. >>>> static GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str) { >>>> - Constant *StrConst = ConstantArray::get(M.getContext(), Str); >>>> + Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); >>>> return new GlobalVariable(M, StrConst->getType(), true, >>>> GlobalValue::PrivateLinkage, StrConst, ""); >>>> } >>>> >>>> Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp (original) >>>> +++ llvm/trunk/lib/Transforms/Scalar/SimplifyLibCalls.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -256,19 +256,18 @@ >>>> ConstantInt::get(TD->getIntPtrType(*Context), Len), >>>> B, TD); >>>> } >>>> - >>>> + >>>> // Otherwise, the character is a constant, see if the first argument is >>>> // a string literal. If so, we can constant fold. >>>> - std::string Str; >>>> - if (!GetConstantStringInfo(SrcStr, Str)) >>>> + StringRef Str; >>>> + if (!getConstantStringInfo(SrcStr, Str)) >>>> return 0; >>>> >>>> - // strchr can find the nul character. >>>> - Str += '\0'; >>>> - >>>> - // Compute the offset. >>>> - size_t I = Str.find(CharC->getSExtValue()); >>>> - if (I == std::string::npos) // Didn't find the char. strchr returns null. >>>> + // Compute the offset, make sure to handle the case when we're searching for >>>> + // zero (a weird way to spell strlen). >>>> + size_t I = CharC->getSExtValue() == 0 ? >>>> + Str.size() : Str.find(CharC->getSExtValue()); >>>> + if (I == StringRef::npos) // Didn't find the char. strchr returns null. >>>> return Constant::getNullValue(CI->getType()); >>>> >>>> // strchr(s+n,c) -> gep(s+n+i,c) >>>> @@ -296,20 +295,18 @@ >>>> if (!CharC) >>>> return 0; >>>> >>>> - std::string Str; >>>> - if (!GetConstantStringInfo(SrcStr, Str)) { >>>> + StringRef Str; >>>> + if (!getConstantStringInfo(SrcStr, Str)) { >>>> // strrchr(s, 0) -> strchr(s, 0) >>>> if (TD && CharC->isZero()) >>>> return EmitStrChr(SrcStr, '\0', B, TD); >>>> return 0; >>>> } >>>> >>>> - // strrchr can find the nul character. >>>> - Str += '\0'; >>>> - >>>> // Compute the offset. >>>> - size_t I = Str.rfind(CharC->getSExtValue()); >>>> - if (I == std::string::npos) // Didn't find the char. Return null. >>>> + size_t I = CharC->getSExtValue() == 0 ? >>>> + Str.size() : Str.rfind(CharC->getSExtValue()); >>>> + if (I == StringRef::npos) // Didn't find the char. Return null. >>>> return Constant::getNullValue(CI->getType()); >>>> >>>> // strrchr(s+n,c) -> gep(s+n+i,c) >>>> @@ -334,14 +331,13 @@ >>>> if (Str1P == Str2P) // strcmp(x,x) -> 0 >>>> return ConstantInt::get(CI->getType(), 0); >>>> >>>> - std::string Str1, Str2; >>>> - bool HasStr1 = GetConstantStringInfo(Str1P, Str1); >>>> - bool HasStr2 = GetConstantStringInfo(Str2P, Str2); >>>> + StringRef Str1, Str2; >>>> + bool HasStr1 = getConstantStringInfo(Str1P, Str1); >>>> + bool HasStr2 = getConstantStringInfo(Str2P, Str2); >>>> >>>> // strcmp(x, y) -> cnst (if both x and y are constant strings) >>>> if (HasStr1 && HasStr2) >>>> - return ConstantInt::get(CI->getType(), >>>> - StringRef(Str1).compare(Str2)); >>>> + return ConstantInt::get(CI->getType(), Str1.compare(Str2)); >>>> >>>> if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x >>>> return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), >>>> @@ -397,14 +393,14 @@ >>>> if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) >>>> return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD); >>>> >>>> - std::string Str1, Str2; >>>> - bool HasStr1 = GetConstantStringInfo(Str1P, Str1); >>>> - bool HasStr2 = GetConstantStringInfo(Str2P, Str2); >>>> + StringRef Str1, Str2; >>>> + bool HasStr1 = getConstantStringInfo(Str1P, Str1); >>>> + bool HasStr2 = getConstantStringInfo(Str2P, Str2); >>>> >>>> // strncmp(x, y) -> cnst (if both x and y are constant strings) >>>> if (HasStr1 && HasStr2) { >>>> - StringRef SubStr1 = StringRef(Str1).substr(0, Length); >>>> - StringRef SubStr2 = StringRef(Str2).substr(0, Length); >>>> + StringRef SubStr1 = Str1.substr(0, Length); >>>> + StringRef SubStr2 = Str2.substr(0, Length); >>>> return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); >>>> } >>>> >>>> @@ -549,9 +545,9 @@ >>>> FT->getReturnType() != FT->getParamType(0)) >>>> return 0; >>>> >>>> - std::string S1, S2; >>>> - bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1); >>>> - bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2); >>>> + StringRef S1, S2; >>>> + bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); >>>> + bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); >>>> >>>> // strpbrk(s, "") -> NULL >>>> // strpbrk("", s) -> NULL >>>> @@ -609,9 +605,9 @@ >>>> !FT->getReturnType()->isIntegerTy()) >>>> return 0; >>>> >>>> - std::string S1, S2; >>>> - bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1); >>>> - bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2); >>>> + StringRef S1, S2; >>>> + bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); >>>> + bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); >>>> >>>> // strspn(s, "") -> 0 >>>> // strspn("", s) -> 0 >>>> @@ -619,8 +615,11 @@ >>>> return Constant::getNullValue(CI->getType()); >>>> >>>> // Constant folding. >>>> - if (HasS1 && HasS2) >>>> - return ConstantInt::get(CI->getType(), strspn(S1.c_str(), S2.c_str())); >>>> + if (HasS1 && HasS2) { >>>> + size_t Pos = S1.find_first_not_of(S2); >>>> + if (Pos == StringRef::npos) Pos = S1.size(); >>>> + return ConstantInt::get(CI->getType(), Pos); >>>> + } >>>> >>>> return 0; >>>> } >>>> @@ -638,17 +637,20 @@ >>>> !FT->getReturnType()->isIntegerTy()) >>>> return 0; >>>> >>>> - std::string S1, S2; >>>> - bool HasS1 = GetConstantStringInfo(CI->getArgOperand(0), S1); >>>> - bool HasS2 = GetConstantStringInfo(CI->getArgOperand(1), S2); >>>> + StringRef S1, S2; >>>> + bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); >>>> + bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); >>>> >>>> // strcspn("", s) -> 0 >>>> if (HasS1 && S1.empty()) >>>> return Constant::getNullValue(CI->getType()); >>>> >>>> // Constant folding. >>>> - if (HasS1 && HasS2) >>>> - return ConstantInt::get(CI->getType(), strcspn(S1.c_str(), S2.c_str())); >>>> + if (HasS1 && HasS2) { >>>> + size_t Pos = S1.find_first_of(S2); >>>> + if (Pos == StringRef::npos) Pos = S1.size(); >>>> + return ConstantInt::get(CI->getType(), Pos); >>>> + } >>>> >>>> // strcspn(s, "") -> strlen(s) >>>> if (TD && HasS2 && S2.empty()) >>>> @@ -692,9 +694,9 @@ >>>> } >>>> >>>> // See if either input string is a constant string. >>>> - std::string SearchStr, ToFindStr; >>>> - bool HasStr1 = GetConstantStringInfo(CI->getArgOperand(0), SearchStr); >>>> - bool HasStr2 = GetConstantStringInfo(CI->getArgOperand(1), ToFindStr); >>>> + StringRef SearchStr, ToFindStr; >>>> + bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr); >>>> + bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr); >>>> >>>> // fold strstr(x, "") -> x. >>>> if (HasStr2 && ToFindStr.empty()) >>>> @@ -704,7 +706,7 @@ >>>> if (HasStr1 && HasStr2) { >>>> std::string::size_type Offset = SearchStr.find(ToFindStr); >>>> >>>> - if (Offset == std::string::npos) // strstr("foo", "bar") -> null >>>> + if (Offset == StringRef::npos) // strstr("foo", "bar") -> null >>>> return Constant::getNullValue(CI->getType()); >>>> >>>> // strstr("abcd", "bc") -> gep((char*)"abcd", 1) >>>> @@ -756,11 +758,11 @@ >>>> } >>>> >>>> // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant) >>>> - std::string LHSStr, RHSStr; >>>> - if (GetConstantStringInfo(LHS, LHSStr) && >>>> - GetConstantStringInfo(RHS, RHSStr)) { >>>> + StringRef LHSStr, RHSStr; >>>> + if (getConstantStringInfo(LHS, LHSStr) && >>>> + getConstantStringInfo(RHS, RHSStr)) { >>>> // Make sure we're not reading out-of-bounds memory. >>>> - if (Len > LHSStr.length() || Len > RHSStr.length()) >>>> + if (Len > LHSStr.size() || Len > RHSStr.size()) >>>> return 0; >>>> uint64_t Ret = memcmp(LHSStr.data(), RHSStr.data(), Len); >>>> return ConstantInt::get(CI->getType(), Ret); >>>> @@ -1116,8 +1118,8 @@ >>>> Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, >>>> IRBuilder<> &B) { >>>> // Check for a fixed format string. >>>> - std::string FormatStr; >>>> - if (!GetConstantStringInfo(CI->getArgOperand(0), FormatStr)) >>>> + StringRef FormatStr; >>>> + if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr)) >>>> return 0; >>>> >>>> // Empty format string -> noop. >>>> @@ -1143,7 +1145,7 @@ >>>> FormatStr.find('%') == std::string::npos) { // no format characters. >>>> // Create a string literal with no \n on it. We expect the constant merge >>>> // pass to be run after this pass, to merge duplicate strings. >>>> - FormatStr.erase(FormatStr.end()-1); >>>> + FormatStr = FormatStr.drop_back(); >>>> Value *GV = B.CreateGlobalString(FormatStr, "str"); >>>> EmitPutS(GV, B, TD); >>>> return CI->use_empty() ? (Value*)CI : >>>> @@ -1203,8 +1205,8 @@ >>>> Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, >>>> IRBuilder<> &B) { >>>> // Check for a fixed format string. >>>> - std::string FormatStr; >>>> - if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr)) >>>> + StringRef FormatStr; >>>> + if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) >>>> return 0; >>>> >>>> // If we just have a format string (nothing else crazy) transform it. >>>> @@ -1358,8 +1360,8 @@ >>>> Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, >>>> IRBuilder<> &B) { >>>> // All the optimizations depend on the format string. >>>> - std::string FormatStr; >>>> - if (!GetConstantStringInfo(CI->getArgOperand(1), FormatStr)) >>>> + StringRef FormatStr; >>>> + if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) >>>> return 0; >>>> >>>> // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) >>>> @@ -1442,8 +1444,8 @@ >>>> return 0; >>>> >>>> // Check for a constant string. >>>> - std::string Str; >>>> - if (!GetConstantStringInfo(CI->getArgOperand(0), Str)) >>>> + StringRef Str; >>>> + if (!getConstantStringInfo(CI->getArgOperand(0), Str)) >>>> return 0; >>>> >>>> if (Str.empty() && CI->use_empty()) { >>>> @@ -2413,6 +2415,8 @@ >>>> // * stpcpy(str, "literal") -> >>>> // llvm.memcpy(str,"literal",strlen("literal")+1,1) >>>> // >>>> +// strchr: >>>> +// * strchr(p, 0) -> strlen(p) >>>> // tan, tanf, tanl: >>>> // * tan(atan(x)) -> x >>>> // >>>> >>>> Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/VMCore/AsmWriter.cpp (original) >>>> +++ llvm/trunk/lib/VMCore/AsmWriter.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -827,30 +827,21 @@ >>>> } >>>> >>>> if (const ConstantArray *CA = dyn_cast(CV)) { >>>> - // As a special case, print the array as a string if it is an array of >>>> - // i8 with ConstantInt values. >>>> - // >>>> Type *ETy = CA->getType()->getElementType(); >>>> - if (CA->isString()) { >>>> - Out << "c\""; >>>> - PrintEscapedString(CA->getAsString(), Out); >>>> - Out << '"'; >>>> - } else { // Cannot output in string format... >>>> - Out << '['; >>>> + Out << '['; >>>> + TypePrinter.print(ETy, Out); >>>> + Out << ' '; >>>> + WriteAsOperandInternal(Out, CA->getOperand(0), >>>> + &TypePrinter, Machine, >>>> + Context); >>>> + for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { >>>> + Out << ", "; >>>> TypePrinter.print(ETy, Out); >>>> Out << ' '; >>>> - WriteAsOperandInternal(Out, CA->getOperand(0), >>>> - &TypePrinter, Machine, >>>> + WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine, >>>> Context); >>>> - for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) { >>>> - Out << ", "; >>>> - TypePrinter.print(ETy, Out); >>>> - Out << ' '; >>>> - WriteAsOperandInternal(Out, CA->getOperand(i), &TypePrinter, Machine, >>>> - Context); >>>> - } >>>> - Out << ']'; >>>> } >>>> + Out << ']'; >>>> return; >>>> } >>>> >>>> >>>> Modified: llvm/trunk/lib/VMCore/Constants.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/VMCore/Constants.cpp (original) >>>> +++ llvm/trunk/lib/VMCore/Constants.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -176,7 +176,7 @@ >>>> return UV->getElementValue(Elt); >>>> >>>> if (const ConstantDataSequential *CDS =dyn_cast(this)) >>>> - return CDS->getElementAsConstant(Elt); >>>> + return Elt < CDS->getNumElements() ? CDS->getElementAsConstant(Elt) : 0; >>>> return 0; >>>> } >>>> >>>> @@ -666,6 +666,13 @@ >>>> // ConstantXXX Classes >>>> //===----------------------------------------------------------------------===// >>>> >>>> +template >>>> +static bool rangeOnlyContains(ItTy Start, ItTy End, EltTy Elt) { >>>> + for (; Start != End; ++Start) >>>> + if (*Start != Elt) >>>> + return false; >>>> + return true; >>>> +} >>>> >>>> ConstantArray::ConstantArray(ArrayType *T, ArrayRef V) >>>> : Constant(T, ConstantArrayVal, >>>> @@ -680,54 +687,97 @@ >>>> } >>>> >>>> Constant *ConstantArray::get(ArrayType *Ty, ArrayRef V) { >>>> + // Empty arrays are canonicalized to ConstantAggregateZero. >>>> + if (V.empty()) >>>> + return ConstantAggregateZero::get(Ty); >>>> + >>>> for (unsigned i = 0, e = V.size(); i != e; ++i) { >>>> assert(V[i]->getType() == Ty->getElementType() && >>>> "Wrong type in array element initializer"); >>>> } >>>> LLVMContextImpl *pImpl = Ty->getContext().pImpl; >>>> - // If this is an all-zero array, return a ConstantAggregateZero object >>>> - bool isAllZero = true; >>>> - bool isUndef = false; >>>> - if (!V.empty()) { >>>> - Constant *C = V[0]; >>>> - isAllZero = C->isNullValue(); >>>> - isUndef = isa(C); >>>> - >>>> - if (isAllZero || isUndef) >>>> - for (unsigned i = 1, e = V.size(); i != e; ++i) >>>> - if (V[i] != C) { >>>> - isAllZero = false; >>>> - isUndef = false; >>>> - break; >>>> - } >>>> - } >>>> + >>>> + // If this is an all-zero array, return a ConstantAggregateZero object. If >>>> + // all undef, return an UndefValue, if "all simple", then return a >>>> + // ConstantDataArray. >>>> + Constant *C = V[0]; >>>> + if (isa(C) && rangeOnlyContains(V.begin(), V.end(), C)) >>>> + return UndefValue::get(Ty); >>>> >>>> - if (isAllZero) >>>> + if (C->isNullValue() && rangeOnlyContains(V.begin(), V.end(), C)) >>>> return ConstantAggregateZero::get(Ty); >>>> - if (isUndef) >>>> - return UndefValue::get(Ty); >>>> - return pImpl->ArrayConstants.getOrCreate(Ty, V); >>>> -} >>>> >>>> -/// ConstantArray::get(const string&) - Return an array that is initialized to >>>> -/// contain the specified string. If length is zero then a null terminator is >>>> -/// added to the specified string so that it may be used in a natural way. >>>> -/// Otherwise, the length parameter specifies how much of the string to use >>>> -/// and it won't be null terminated. >>>> -/// >>>> -Constant *ConstantArray::get(LLVMContext &Context, StringRef Str, >>>> - bool AddNull) { >>>> - SmallVector ElementVals; >>>> - ElementVals.reserve(Str.size() + size_t(AddNull)); >>>> - for (unsigned i = 0; i < Str.size(); ++i) >>>> - ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i])); >>>> - >>>> - // Add a null terminator to the string... >>>> - if (AddNull) >>>> - ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), 0)); >>>> + // Check to see if all of the elements are ConstantFP or ConstantInt and if >>>> + // the element type is compatible with ConstantDataVector. If so, use it. >>>> + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { >>>> + // We speculatively build the elements here even if it turns out that there >>>> + // is a constantexpr or something else weird in the array, since it is so >>>> + // uncommon for that to happen. >>>> + if (ConstantInt *CI = dyn_cast(C)) { >>>> + if (CI->getType()->isIntegerTy(8)) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantInt *CI = dyn_cast(V[i])) >>>> + Elts.push_back(CI->getZExtValue()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } else if (CI->getType()->isIntegerTy(16)) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantInt *CI = dyn_cast(V[i])) >>>> + Elts.push_back(CI->getZExtValue()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } else if (CI->getType()->isIntegerTy(32)) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantInt *CI = dyn_cast(V[i])) >>>> + Elts.push_back(CI->getZExtValue()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } else if (CI->getType()->isIntegerTy(64)) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantInt *CI = dyn_cast(V[i])) >>>> + Elts.push_back(CI->getZExtValue()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } >>>> + } >>>> + >>>> + if (ConstantFP *CFP = dyn_cast(C)) { >>>> + if (CFP->getType()->isFloatTy()) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantFP *CFP = dyn_cast(V[i])) >>>> + Elts.push_back(CFP->getValueAPF().convertToFloat()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } else if (CFP->getType()->isDoubleTy()) { >>>> + SmallVector Elts; >>>> + for (unsigned i = 0, e = V.size(); i != e; ++i) >>>> + if (ConstantFP *CFP = dyn_cast(V[i])) >>>> + Elts.push_back(CFP->getValueAPF().convertToDouble()); >>>> + else >>>> + break; >>>> + if (Elts.size() == V.size()) >>>> + return ConstantDataArray::get(C->getContext(), Elts); >>>> + } >>>> + } >>>> + } >>>> >>>> - ArrayType *ATy = ArrayType::get(Type::getInt8Ty(Context), ElementVals.size()); >>>> - return get(ATy, ElementVals); >>>> + // Otherwise, we really do want to create a ConstantArray. >>>> + return pImpl->ArrayConstants.getOrCreate(Ty, V); >>>> } >>>> >>>> /// getTypeForElements - Return an anonymous struct type to use for a constant >>>> @@ -839,8 +889,7 @@ >>>> >>>> // Check to see if all of the elements are ConstantFP or ConstantInt and if >>>> // the element type is compatible with ConstantDataVector. If so, use it. >>>> - if (ConstantDataSequential::isElementTypeCompatible(C->getType()) && >>>> - (isa(C) || isa(C))) { >>>> + if (ConstantDataSequential::isElementTypeCompatible(C->getType())) { >>>> // We speculatively build the elements here even if it turns out that there >>>> // is a constantexpr or something else weird in the array, since it is so >>>> // uncommon for that to happen. >>>> @@ -1146,69 +1195,6 @@ >>>> destroyConstantImpl(); >>>> } >>>> >>>> -/// isString - This method returns true if the array is an array of i8, and >>>> -/// if the elements of the array are all ConstantInt's. >>>> -bool ConstantArray::isString() const { >>>> - // Check the element type for i8... >>>> - if (!getType()->getElementType()->isIntegerTy(8)) >>>> - return false; >>>> - // Check the elements to make sure they are all integers, not constant >>>> - // expressions. >>>> - for (unsigned i = 0, e = getNumOperands(); i != e; ++i) >>>> - if (!isa(getOperand(i))) >>>> - return false; >>>> - return true; >>>> -} >>>> - >>>> -/// isCString - This method returns true if the array is a string (see >>>> -/// isString) and it ends in a null byte \\0 and does not contains >>>> any other >>>> -/// null bytes except its terminator. >>>> -bool ConstantArray::isCString() const { >>>> - // Check the element type for i8... >>>> - if (!getType()->getElementType()->isIntegerTy(8)) >>>> - return false; >>>> - >>>> - // Last element must be a null. >>>> - if (!getOperand(getNumOperands()-1)->isNullValue()) >>>> - return false; >>>> - // Other elements must be non-null integers. >>>> - for (unsigned i = 0, e = getNumOperands()-1; i != e; ++i) { >>>> - if (!isa(getOperand(i))) >>>> - return false; >>>> - if (getOperand(i)->isNullValue()) >>>> - return false; >>>> - } >>>> - return true; >>>> -} >>>> - >>>> - >>>> -/// convertToString - Helper function for getAsString() and getAsCString(). >>>> -static std::string convertToString(const User *U, unsigned len) { >>>> - std::string Result; >>>> - Result.reserve(len); >>>> - for (unsigned i = 0; i != len; ++i) >>>> - Result.push_back((char)cast(U->getOperand(i))->getZExtValue()); >>>> - return Result; >>>> -} >>>> - >>>> -/// getAsString - If this array is isString(), then this method converts the >>>> -/// array to an std::string and returns it. Otherwise, it asserts out. >>>> -/// >>>> -std::string ConstantArray::getAsString() const { >>>> - assert(isString() && "Not a string!"); >>>> - return convertToString(this, getNumOperands()); >>>> -} >>>> - >>>> - >>>> -/// getAsCString - If this array is isCString(), then this method converts the >>>> -/// array (without the trailing null byte) to an std::string and returns it. >>>> -/// Otherwise, it asserts out. >>>> -/// >>>> -std::string ConstantArray::getAsCString() const { >>>> - assert(isCString() && "Not a string!"); >>>> - return convertToString(this, getNumOperands() - 1); >>>> -} >>>> - >>>> >>>> //---- ConstantStruct::get() implementation... >>>> // >>>> >>>> Modified: llvm/trunk/lib/VMCore/Core.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Core.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/VMCore/Core.cpp (original) >>>> +++ llvm/trunk/lib/VMCore/Core.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -634,8 +634,8 @@ >>>> LLVMBool DontNullTerminate) { >>>> /* Inverted the sense of AddNull because ', 0)' is a >>>> better mnemonic for null termination than ', 1)'. */ >>>> - return wrap(ConstantArray::get(*unwrap(C), StringRef(Str, Length), >>>> - DontNullTerminate == 0)); >>>> + return wrap(ConstantDataArray::getString(*unwrap(C), StringRef(Str, Length), >>>> + DontNullTerminate == 0)); >>>> } >>>> LLVMValueRef LLVMConstStructInContext(LLVMContextRef C, >>>> LLVMValueRef *ConstantVals, >>>> >>>> Modified: llvm/trunk/lib/VMCore/IRBuilder.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/IRBuilder.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/lib/VMCore/IRBuilder.cpp (original) >>>> +++ llvm/trunk/lib/VMCore/IRBuilder.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -24,7 +24,7 @@ >>>> /// specified. If Name is specified, it is the name of the global variable >>>> /// created. >>>> Value *IRBuilderBase::CreateGlobalString(StringRef Str, const Twine &Name) { >>>> - Constant *StrConstant = ConstantArray::get(Context, Str, true); >>>> + Constant *StrConstant = ConstantDataArray::getString(Context, Str); >>>> Module &M = *BB->getParent()->getParent(); >>>> GlobalVariable *GV = new GlobalVariable(M, StrConstant->getType(), >>>> true, GlobalValue::PrivateLinkage, >>>> >>>> Modified: llvm/trunk/tools/bugpoint/Miscompilation.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/Miscompilation.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/tools/bugpoint/Miscompilation.cpp (original) >>>> +++ llvm/trunk/tools/bugpoint/Miscompilation.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -820,7 +820,8 @@ >>>> // Don't forward functions which are external in the test module too. >>>> if (TestFn && !TestFn->isDeclaration()) { >>>> // 1. Add a string constant with its name to the global file >>>> - Constant *InitArray = ConstantArray::get(F->getContext(), F->getName()); >>>> + Constant *InitArray = >>>> + ConstantDataArray::getString(F->getContext(), F->getName()); >>>> GlobalVariable *funcName = >>>> new GlobalVariable(*Safe, InitArray->getType(), true /*isConstant*/, >>>> GlobalValue::InternalLinkage, InitArray, >>>> >>>> Modified: llvm/trunk/tools/lto/LTOModule.cpp >>>> URL: >>>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=149800&r1=149799&r2=149800&view=diff >>>> >>>> ============================================================================== >>>> --- llvm/trunk/tools/lto/LTOModule.cpp (original) >>>> +++ llvm/trunk/tools/lto/LTOModule.cpp Sat Feb 4 20:29:43 2012 >>>> @@ -190,9 +190,9 @@ >>>> Constant *op = ce->getOperand(0); >>>> if (GlobalVariable *gvn = dyn_cast(op)) { >>>> Constant *cn = gvn->getInitializer(); >>>> - if (ConstantArray *ca = dyn_cast(cn)) { >>>> + if (ConstantDataArray *ca = dyn_cast(cn)) { >>>> if (ca->isCString()) { >>>> - name = ".objc_class_name_" + ca->getAsCString(); >>>> + name = ".objc_class_name_" + ca->getAsCString().str(); >>>> return true; >>>> } >>>> } >>>> >>>> >>>> _______________________________________________ >>>> llvm-commits mailing list >>>> llvm-commits at cs.uiuc.edu >>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >>> >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From craig.topper at gmail.com Mon Feb 6 01:17:52 2012 From: craig.topper at gmail.com (Craig Topper) Date: Mon, 06 Feb 2012 07:17:52 -0000 Subject: [llvm-commits] [llvm] r149859 - in /llvm/trunk/lib/Target/X86: InstPrinter/X86InstComments.cpp Utils/X86ShuffleDecode.cpp Utils/X86ShuffleDecode.h X86ISelLowering.cpp Message-ID: <20120206071752.29A7F2A6C12C@llvm.org> Author: ctopper Date: Mon Feb 6 01:17:51 2012 New Revision: 149859 URL: http://llvm.org/viewvc/llvm-project?rev=149859&view=rev Log: Add shuffle decoding support for 256-bit pshufd. Merge vpermilp* and pshufd decoding. Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86InstComments.cpp llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.cpp llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.h llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86InstComments.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86InstComments.cpp?rev=149859&r1=149858&r2=149859&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/InstPrinter/X86InstComments.cpp (original) +++ llvm/trunk/lib/Target/X86/InstPrinter/X86InstComments.cpp Mon Feb 6 01:17:51 2012 @@ -76,10 +76,19 @@ case X86::PSHUFDmi: case X86::VPSHUFDmi: DestName = getRegName(MI->getOperand(0).getReg()); - DecodePSHUFMask(4, MI->getOperand(MI->getNumOperands()-1).getImm(), + DecodePSHUFMask(MVT::v4i32, MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); + break; + case X86::VPSHUFDYri: + Src1Name = getRegName(MI->getOperand(1).getReg()); + // FALL THROUGH. + case X86::VPSHUFDYmi: + DestName = getRegName(MI->getOperand(0).getReg()); + DecodePSHUFMask(MVT::v8i32, MI->getOperand(MI->getNumOperands()-1).getImm(), ShuffleMask); break; + case X86::PSHUFHWri: case X86::VPSHUFHWri: Src1Name = getRegName(MI->getOperand(1).getReg()); @@ -437,31 +446,31 @@ Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. case X86::VPERMILPSmi: - DecodeVPERMILPMask(MVT::v4f32, MI->getOperand(MI->getNumOperands()-1).getImm(), - ShuffleMask); + DecodePSHUFMask(MVT::v4f32, MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); DestName = getRegName(MI->getOperand(0).getReg()); break; case X86::VPERMILPSYri: Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. case X86::VPERMILPSYmi: - DecodeVPERMILPMask(MVT::v8f32, MI->getOperand(MI->getNumOperands()-1).getImm(), - ShuffleMask); + DecodePSHUFMask(MVT::v8f32, MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); DestName = getRegName(MI->getOperand(0).getReg()); break; case X86::VPERMILPDri: Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. case X86::VPERMILPDmi: - DecodeVPERMILPMask(MVT::v2f64, MI->getOperand(MI->getNumOperands()-1).getImm(), - ShuffleMask); + DecodePSHUFMask(MVT::v2f64, MI->getOperand(MI->getNumOperands()-1).getImm(), + ShuffleMask); DestName = getRegName(MI->getOperand(0).getReg()); break; case X86::VPERMILPDYri: Src1Name = getRegName(MI->getOperand(1).getReg()); // FALL THROUGH. case X86::VPERMILPDYmi: - DecodeVPERMILPMask(MVT::v4f64, MI->getOperand(MI->getNumOperands()-1).getImm(), + DecodePSHUFMask(MVT::v4f64, MI->getOperand(MI->getNumOperands()-1).getImm(), ShuffleMask); DestName = getRegName(MI->getOperand(0).getReg()); break; @@ -471,7 +480,9 @@ // FALL THROUGH. case X86::VPERM2F128rm: case X86::VPERM2I128rm: - DecodeVPERM2F128Mask(MI->getOperand(MI->getNumOperands()-1).getImm(), + // For instruction comments purpose, assume the 256-bit vector is v4i64. + DecodeVPERM2X128Mask(MVT::v4i64, + MI->getOperand(MI->getNumOperands()-1).getImm(), ShuffleMask); Src1Name = getRegName(MI->getOperand(1).getReg()); DestName = getRegName(MI->getOperand(0).getReg()); Modified: llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.cpp?rev=149859&r1=149858&r2=149859&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.cpp (original) +++ llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.cpp Mon Feb 6 01:17:51 2012 @@ -63,11 +63,23 @@ ShuffleMask.push_back(NElts+i); } -void DecodePSHUFMask(unsigned NElts, unsigned Imm, +/// DecodePSHUFMask - This decodes the shuffle masks for pshufd, and vpermilp*. +/// VT indicates the type of the vector allowing it to handle different +/// datatypes and vector widths. +void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { - for (unsigned i = 0; i != NElts; ++i) { - ShuffleMask.push_back(Imm % NElts); - Imm /= NElts; + unsigned NumElts = VT.getVectorNumElements(); + + unsigned NumLanes = VT.getSizeInBits() / 128; + unsigned NumLaneElts = NumElts / NumLanes; + + int NewImm = Imm; + for (unsigned l = 0; l != NumElts; l += NumLaneElts) { + for (unsigned i = 0; i != NumLaneElts; ++i) { + ShuffleMask.push_back(NewImm % NumLaneElts + l); + NewImm /= NumLaneElts; + } + if (NumLaneElts == 4) NewImm = Imm; // reload imm } } @@ -95,6 +107,9 @@ ShuffleMask.push_back(7); } +/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates +/// the type of the vector allowing it to handle different datatypes and vector +/// widths. void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); @@ -103,22 +118,24 @@ unsigned NumLaneElts = NumElts / NumLanes; int NewImm = Imm; - for (unsigned l = 0; l < NumLanes; ++l) { - unsigned LaneStart = l * NumLaneElts; + for (unsigned l = 0; l != NumElts; l += NumLaneElts) { // Part that reads from dest. for (unsigned i = 0; i != NumLaneElts/2; ++i) { - ShuffleMask.push_back(NewImm % NumLaneElts + LaneStart); + ShuffleMask.push_back(NewImm % NumLaneElts + l); NewImm /= NumLaneElts; } // Part that reads from src. for (unsigned i = 0; i != NumLaneElts/2; ++i) { - ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + LaneStart); + ShuffleMask.push_back(NewImm % NumLaneElts + NumElts + l); NewImm /= NumLaneElts; } if (NumLaneElts == 4) NewImm = Imm; // reload imm } } +/// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd +/// and punpckh*. VT indicates the type of the vector allowing it to handle +/// different datatypes and vector widths. void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); @@ -128,10 +145,8 @@ if (NumLanes == 0 ) NumLanes = 1; // Handle MMX unsigned NumLaneElts = NumElts / NumLanes; - for (unsigned s = 0; s < NumLanes; ++s) { - unsigned Start = s * NumLaneElts + NumLaneElts/2; - unsigned End = s * NumLaneElts + NumLaneElts; - for (unsigned i = Start; i != End; ++i) { + for (unsigned l = 0; l != NumElts; l += NumLaneElts) { + for (unsigned i = l + NumLaneElts/2, e = l + NumLaneElts; i != e; ++i) { ShuffleMask.push_back(i); // Reads from dest/src1 ShuffleMask.push_back(i+NumElts); // Reads from src/src2 } @@ -139,8 +154,8 @@ } /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd -/// etc. VT indicates the type of the vector allowing it to handle different -/// datatypes and vector widths. +/// and punpckl*. VT indicates the type of the vector allowing it to handle +/// different datatypes and vector widths. void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask) { unsigned NumElts = VT.getVectorNumElements(); @@ -150,38 +165,15 @@ if (NumLanes == 0 ) NumLanes = 1; // Handle MMX unsigned NumLaneElts = NumElts / NumLanes; - for (unsigned s = 0; s < NumLanes; ++s) { - unsigned Start = s * NumLaneElts; - unsigned End = s * NumLaneElts + NumLaneElts/2; - for (unsigned i = Start; i != End; ++i) { + for (unsigned l = 0; l != NumElts; l += NumLaneElts) { + for (unsigned i = l, e = l + NumLaneElts/2; i != e; ++i) { ShuffleMask.push_back(i); // Reads from dest/src1 ShuffleMask.push_back(i+NumElts); // Reads from src/src2 } } } -// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit -// 32-bit or 64-bit elements. For 256-bit vectors, it's considered as two 128 -// lanes. For VPERMILPS, referenced elements can't cross lanes and the mask of -// the first lane must be the same of the second. -void DecodeVPERMILPMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask) { - unsigned NumElts = VT.getVectorNumElements(); - - unsigned NumLanes = VT.getSizeInBits() / 128; - unsigned NumLaneElts = NumElts / NumLanes; - - for (unsigned l = 0; l != NumLanes; ++l) { - unsigned LaneStart = l*NumLaneElts; - for (unsigned i = 0; i != NumLaneElts; ++i) { - unsigned Idx = NumLaneElts == 4 ? (Imm >> (i*2)) & 0x3 - : (Imm >> (i+LaneStart)) & 0x1; - ShuffleMask.push_back(Idx+LaneStart); - } - } -} - -void DecodeVPERM2F128Mask(EVT VT, unsigned Imm, +void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask) { unsigned HalfSize = VT.getVectorNumElements()/2; unsigned FstHalfBegin = (Imm & 0x3) * HalfSize; @@ -193,12 +185,4 @@ ShuffleMask.push_back(i); } -void DecodeVPERM2F128Mask(unsigned Imm, - SmallVectorImpl &ShuffleMask) { - // VPERM2F128 is used by any 256-bit EVT, but X86InstComments only - // has information about the instruction and not the types. So for - // instruction comments purpose, assume the 256-bit vector is v4i64. - return DecodeVPERM2F128Mask(MVT::v4i64, Imm, ShuffleMask); -} - } // llvm namespace Modified: llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.h?rev=149859&r1=149858&r2=149859&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.h (original) +++ llvm/trunk/lib/Target/X86/Utils/X86ShuffleDecode.h Mon Feb 6 01:17:51 2012 @@ -37,7 +37,7 @@ void DecodeMOVLHPSMask(unsigned NElts, SmallVectorImpl &ShuffleMask); -void DecodePSHUFMask(unsigned NElts, unsigned Imm, +void DecodePSHUFMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); void DecodePSHUFHWMask(unsigned Imm, @@ -46,30 +46,24 @@ void DecodePSHUFLWMask(unsigned Imm, SmallVectorImpl &ShuffleMask); +/// DecodeSHUFPMask - This decodes the shuffle masks for shufp*. VT indicates +/// the type of the vector allowing it to handle different datatypes and vector +/// widths. void DecodeSHUFPMask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); /// DecodeUNPCKHMask - This decodes the shuffle masks for unpckhps/unpckhpd -/// etc. VT indicates the type of the vector allowing it to handle different -/// datatypes and vector widths. +/// and punpckh*. VT indicates the type of the vector allowing it to handle +/// different datatypes and vector widths. void DecodeUNPCKHMask(EVT VT, SmallVectorImpl &ShuffleMask); /// DecodeUNPCKLMask - This decodes the shuffle masks for unpcklps/unpcklpd -/// etc. VT indicates the type of the vector allowing it to handle different -/// datatypes and vector widths. +/// and punpckl*. VT indicates the type of the vector allowing it to handle +/// different datatypes and vector widths. void DecodeUNPCKLMask(EVT VT, SmallVectorImpl &ShuffleMask); -// DecodeVPERMILPMask - Decodes VPERMILPS/ VPERMILPD permutes for any 128-bit -// 32-bit or 64-bit elements. For 256-bit vectors, it's considered as two 128 -// lanes. For VPERMILPS, referenced elements can't cross lanes and the mask of -// the first lane must be the same of the second. -void DecodeVPERMILPMask(EVT VT, unsigned Imm, - SmallVectorImpl &ShuffleMask); - -void DecodeVPERM2F128Mask(unsigned Imm, - SmallVectorImpl &ShuffleMask); -void DecodeVPERM2F128Mask(EVT VT, unsigned Imm, +void DecodeVPERM2X128Mask(EVT VT, unsigned Imm, SmallVectorImpl &ShuffleMask); } // llvm namespace Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=149859&r1=149858&r2=149859&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Feb 6 01:17:51 2012 @@ -4430,14 +4430,15 @@ if (Index < 0) return DAG.getUNDEF(VT.getVectorElementType()); - int NumElems = VT.getVectorNumElements(); - SDValue NewV = (Index < NumElems) ? SV->getOperand(0) : SV->getOperand(1); + unsigned NumElems = VT.getVectorNumElements(); + SDValue NewV = (Index < (int)NumElems) ? SV->getOperand(0) + : SV->getOperand(1); return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG, Depth+1); } // Recurse into target specific vector shuffles to find scalars. if (isTargetShuffle(Opcode)) { - int NumElems = VT.getVectorNumElements(); + unsigned NumElems = VT.getVectorNumElements(); SmallVector ShuffleMask; SDValue ImmN; @@ -4460,9 +4461,9 @@ DecodeMOVLHPSMask(NumElems, ShuffleMask); break; case X86ISD::PSHUFD: + case X86ISD::VPERMILP: ImmN = N->getOperand(N->getNumOperands()-1); - DecodePSHUFMask(NumElems, - cast(ImmN)->getZExtValue(), + DecodePSHUFMask(VT, cast(ImmN)->getZExtValue(), ShuffleMask); break; case X86ISD::PSHUFHW: @@ -4484,14 +4485,9 @@ return getShuffleScalarElt(V.getOperand(OpNum).getNode(), Index, DAG, Depth+1); } - case X86ISD::VPERMILP: - ImmN = N->getOperand(N->getNumOperands()-1); - DecodeVPERMILPMask(VT, cast(ImmN)->getZExtValue(), - ShuffleMask); - break; case X86ISD::VPERM2X128: ImmN = N->getOperand(N->getNumOperands()-1); - DecodeVPERM2F128Mask(VT, cast(ImmN)->getZExtValue(), + DecodeVPERM2X128Mask(VT, cast(ImmN)->getZExtValue(), ShuffleMask); break; case X86ISD::MOVDDUP: @@ -4509,7 +4505,8 @@ if (Index < 0) return DAG.getUNDEF(VT.getVectorElementType()); - SDValue NewV = (Index < NumElems) ? N->getOperand(0) : N->getOperand(1); + SDValue NewV = (Index < (int)NumElems) ? N->getOperand(0) + : N->getOperand(1); return getShuffleScalarElt(NewV.getNode(), Index % NumElems, DAG, Depth+1); } From craig.topper at gmail.com Mon Feb 6 01:36:03 2012 From: craig.topper at gmail.com (Craig Topper) Date: Sun, 5 Feb 2012 23:36:03 -0800 Subject: [llvm-commits] [llvm] r149849 - in /llvm/trunk: include/llvm/ include/llvm/ADT/ include/llvm/Analysis/ include/llvm/Bitcode/ include/llvm/CodeGen/ include/llvm/CodeGen/PBQP/ include/llvm/ExecutionEngine/ include/llvm/MC/ include/llvm/Support/ inc In-Reply-To: References: Message-ID: I'll get those cleaned up. On Sun, Feb 5, 2012 at 10:32 PM, David Blaikie wrote: > > Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=149849&r1=149848&r2=149849&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) > > +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Sun Feb 5 16:14:15 > 2012 > > @@ -128,9 +128,8 @@ > > Other.Contents.Order.isNormalMemory && > > Contents.Order.isMustAlias == > Other.Contents.Order.isMustAlias && > > Contents.Order.isArtificial == > Other.Contents.Order.isArtificial; > > + default: llvm_unreachable("Invalid dependency kind!"); > > } > > - assert(0 && "Invalid dependency kind!"); > > - return false; > > If you could keep trailing asserts like this as trailing (though feel > free to convert them from assert to llvm_unreachable) that would be > great. Adding a default to a fully-covered switch like this is > unhelpful as it suppresses -Wswitch (which warns when a > switch-over-enum is not fully covered) should a new element be added > to the enumeration. > > Clang has a warning I recently added (-Wcovered-switch-default) that > catches this case & your changes have caused several violations of > this warning across LLVM. > > Let me know if you'd prefer me to fix them up. > > - David > > > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120205/21090afc/attachment-0001.html From sundeepk at codeaurora.org Mon Feb 6 02:06:12 2012 From: sundeepk at codeaurora.org (Sundeep) Date: Mon, 6 Feb 2012 02:06:12 -0600 Subject: [llvm-commits] Target independent VLIW Packetizer Message-ID: <000001cce4a6$3140dbe0$93c293a0$@org> Hi All, I have been working on a target independent VLIW packetizer in LLVM. On VLIW machines, an instruction packet represents a group of instructions which can be executed in parallel. The compiler is responsible for identifying independent machine instructions and grouping those together into packets. The VLIW packetizer in LLVM is implemented as follows: Implementation Details: 1. The VLIW packetizer is implemented after all target specific passes are run. This ensures that all pseudo instructions and spill code is enumerated before packetization. 2. The VLIW packetizer extends "ScheduleDAGInstrs" class. The Packetizer uses "BuildSchedGraph" API to build dependence graph. The dependence graph along with deterministic finite automaton (DFA) is used to group independent instructions into packets. 3. The instruction packets are finalized using "finalizeBundle" API. This API inserts BUNDLE instructions and updates each packet instruction with "insideBundle" bit. 4. The Hexagon backend assembly printer is updated to handle BUNDLE instruction and print packet semantics correctly. Other VLIW targets will also have to update the assembly printer. The VLIW packetizer roughly implements the following algorithm: 1 Instantiate DFA resource tracker 2 For all basic blocks (BB) in Machine Function 3 do 4 reset DFA 5 CurrentPacket = {} 6 For all machine instructions (I) in BB 7 do 8 avail = DFA.IsAvailable(I) 9 if (avail == true) { 10 For all machine instructions (Ip) in CurrentPacket 11 do 12 if (DependenceGraph.HasDependence(I, Ip)) { 13 if (Target.CanPruneDependence(I, Ip)) { 14 // End current packet 15 finalizeBundle 16 reset DFA 17 reset CurrentPacket 18 } 19 } 20 done 21 } 22 else { 23 // End current packet 24 finalizeBundle 25 reset DFA 26 reset CurrentPacket 27 } 28 29 // Add I to CurrentPacket 30 CurrentPacket.Add(I) 31 done 32 done I have already verified that it builds and runs regression test suites clean on x86. I attaching the initial patch for review and comments. Thanks, Sundeep -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: vliw-packetizer-patch.txt Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/2285fbb1/attachment.txt From craig.topper at gmail.com Mon Feb 6 02:17:44 2012 From: craig.topper at gmail.com (Craig Topper) Date: Mon, 06 Feb 2012 08:17:44 -0000 Subject: [llvm-commits] [llvm] r149860 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h lib/CodeGen/MachineFunction.cpp Message-ID: <20120206081744.2511C2A6C12C@llvm.org> Author: ctopper Date: Mon Feb 6 02:17:43 2012 New Revision: 149860 URL: http://llvm.org/viewvc/llvm-project?rev=149860&view=rev Log: Move some llvm_unreachable's from r149849 out of switch statements to satisfy -Wcovered-switch-default Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h llvm/trunk/lib/CodeGen/MachineFunction.cpp Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=149860&r1=149859&r2=149860&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original) +++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Mon Feb 6 02:17:43 2012 @@ -128,8 +128,8 @@ Other.Contents.Order.isNormalMemory && Contents.Order.isMustAlias == Other.Contents.Order.isMustAlias && Contents.Order.isArtificial == Other.Contents.Order.isArtificial; - default: llvm_unreachable("Invalid dependency kind!"); } + llvm_unreachable("Invalid dependency kind!"); } bool operator!=(const SDep &Other) const { Modified: llvm/trunk/lib/CodeGen/MachineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineFunction.cpp?rev=149860&r1=149859&r2=149860&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineFunction.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineFunction.cpp Mon Feb 6 02:17:43 2012 @@ -528,7 +528,6 @@ // The size of a jump table entry is 4 bytes unless the entry is just the // address of a block, in which case it is the pointer size. switch (getEntryKind()) { - default: llvm_unreachable("Unknown jump table encoding!"); case MachineJumpTableInfo::EK_BlockAddress: return TD.getPointerSize(); case MachineJumpTableInfo::EK_GPRel64BlockAddress: @@ -540,6 +539,7 @@ case MachineJumpTableInfo::EK_Inline: return 0; } + llvm_unreachable("Unknown jump table encoding!"); } /// getEntryAlignment - Return the alignment of each entry in the jump table. @@ -548,7 +548,6 @@ // entry is just the address of a block, in which case it is the pointer // alignment. switch (getEntryKind()) { - default: llvm_unreachable("Unknown jump table encoding!"); case MachineJumpTableInfo::EK_BlockAddress: return TD.getPointerABIAlignment(); case MachineJumpTableInfo::EK_GPRel64BlockAddress: @@ -560,6 +559,7 @@ case MachineJumpTableInfo::EK_Inline: return 1; } + llvm_unreachable("Unknown jump table encoding!"); } /// createJumpTableIndex - Create a new jump table entry in the jump table info. From nicholas at mxc.ca Mon Feb 6 02:24:44 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 06 Feb 2012 08:24:44 -0000 Subject: [llvm-commits] [llvm] r149861 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20120206082444.CCE262A6C12C@llvm.org> Author: nicholas Date: Mon Feb 6 02:24:44 2012 New Revision: 149861 URL: http://llvm.org/viewvc/llvm-project?rev=149861&view=rev Log: Split part of EvaluateFunction into a new EvaluateBlock method. No functionality change. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=149861&r1=149860&r2=149861&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Feb 6 02:24:44 2012 @@ -2282,9 +2282,6 @@ return 0; // don't know how to evaluate. } -/// EvaluateFunction - Evaluate a call to function F, returning true if -/// successful, false if we can't evaluate it. ActualArgs contains the formal -/// arguments for the function. static bool EvaluateFunction(Function *F, Constant *&RetVal, const SmallVectorImpl &ActualArgs, std::vector &CallStack, @@ -2292,30 +2289,21 @@ std::vector &AllocaTmps, SmallPtrSet &SimpleConstants, const TargetData *TD, - const TargetLibraryInfo *TLI) { - // Check to see if this function is already executing (recursion). If so, - // bail out. TODO: we might want to accept limited recursion. - if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end()) - return false; - - CallStack.push_back(F); - - /// Values - As we compute SSA register values, we store their contents here. - DenseMap Values; - - // Initialize arguments to the incoming values specified. - unsigned ArgNo = 0; - for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; - ++AI, ++ArgNo) - Values[AI] = ActualArgs[ArgNo]; - - /// ExecutedBlocks - We only handle non-looping, non-recursive code. As such, - /// we can only evaluate any one basic block at most once. This set keeps - /// track of what we have executed so we can detect recursive cases etc. - SmallPtrSet ExecutedBlocks; + const TargetLibraryInfo *TLI); +/// EvaluateBlock - Evaluate all instructions in block BB, returning true if +/// successful, false if we can't evaluate it. NewBB returns the next BB that +/// control flows into, or null upon return. +static bool EvaluateBlock(BasicBlock *BB, BasicBlock *&NextBB, + std::vector &CallStack, + DenseMap &Values, + DenseMap &MutatedMemory, + std::vector &AllocaTmps, + SmallPtrSet &SimpleConstants, + const TargetData *TD, + const TargetLibraryInfo *TLI) { // CurInst - The current instruction we're evaluating. - BasicBlock::iterator CurInst = F->begin()->begin(); + BasicBlock::iterator CurInst = BB->getFirstNonPHI(); // This is the main evaluation loop. while (1) { @@ -2342,7 +2330,7 @@ // stored value. Ptr = CE->getOperand(0); - Type *NewTy=cast(Ptr->getType())->getElementType(); + Type *NewTy = cast(Ptr->getType())->getElementType(); // In order to push the bitcast onto the stored value, a bitcast // from NewTy to Val's type must be legal. If it's not, we can try @@ -2354,7 +2342,7 @@ if (StructType *STy = dyn_cast(NewTy)) { NewTy = STy->getTypeAtIndex(0U); - IntegerType *IdxTy =IntegerType::get(NewTy->getContext(), 32); + IntegerType *IdxTy = IntegerType::get(NewTy->getContext(), 32); Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); Constant * const IdxList[] = {IdxZero, IdxZero}; @@ -2363,7 +2351,7 @@ // If we can't improve the situation by introspecting NewTy, // we have to give up. } else { - return 0; + return false; } } @@ -2467,57 +2455,37 @@ InstResult = RetVal; } } else if (isa(CurInst)) { - BasicBlock *NewBB = 0; if (BranchInst *BI = dyn_cast(CurInst)) { if (BI->isUnconditional()) { - NewBB = BI->getSuccessor(0); + NextBB = BI->getSuccessor(0); } else { ConstantInt *Cond = dyn_cast(getVal(Values, BI->getCondition())); if (!Cond) return false; // Cannot determine. - NewBB = BI->getSuccessor(!Cond->getZExtValue()); + NextBB = BI->getSuccessor(!Cond->getZExtValue()); } } else if (SwitchInst *SI = dyn_cast(CurInst)) { ConstantInt *Val = dyn_cast(getVal(Values, SI->getCondition())); if (!Val) return false; // Cannot determine. unsigned ValTISucc = SI->resolveSuccessorIndex(SI->findCaseValue(Val)); - NewBB = SI->getSuccessor(ValTISucc); + NextBB = SI->getSuccessor(ValTISucc); } else if (IndirectBrInst *IBI = dyn_cast(CurInst)) { Value *Val = getVal(Values, IBI->getAddress())->stripPointerCasts(); if (BlockAddress *BA = dyn_cast(Val)) - NewBB = BA->getBasicBlock(); + NextBB = BA->getBasicBlock(); else return false; // Cannot determine. - } else if (ReturnInst *RI = dyn_cast(CurInst)) { - if (RI->getNumOperands()) - RetVal = getVal(Values, RI->getOperand(0)); - - CallStack.pop_back(); // return from fn. - return true; // We succeeded at evaluating this ctor! + } else if (isa(CurInst)) { + NextBB = 0; } else { // invoke, unwind, resume, unreachable. return false; // Cannot handle this terminator. } - // Okay, we succeeded in evaluating this control flow. See if we have - // executed the new block before. If so, we have a looping function, - // which we cannot evaluate in reasonable time. - if (!ExecutedBlocks.insert(NewBB)) - return false; // looped! - - // Okay, we have never been in this block before. Check to see if there - // are any PHI nodes. If so, evaluate them with information about where - // we came from. - BasicBlock *OldBB = CurInst->getParent(); - CurInst = NewBB->begin(); - PHINode *PN; - for (; (PN = dyn_cast(CurInst)); ++CurInst) - Values[PN] = getVal(Values, PN->getIncomingValueForBlock(OldBB)); - - // Do NOT increment CurInst. We know that the terminator had no value. - continue; + // We succeeded at evaluating this block! + return true; } else { // Did not know how to evaluate this! return false; @@ -2535,6 +2503,76 @@ } } +/// EvaluateFunction - Evaluate a call to function F, returning true if +/// successful, false if we can't evaluate it. ActualArgs contains the formal +/// arguments for the function. +static bool EvaluateFunction(Function *F, Constant *&RetVal, + const SmallVectorImpl &ActualArgs, + std::vector &CallStack, + DenseMap &MutatedMemory, + std::vector &AllocaTmps, + SmallPtrSet &SimpleConstants, + const TargetData *TD, + const TargetLibraryInfo *TLI) { + // Check to see if this function is already executing (recursion). If so, + // bail out. TODO: we might want to accept limited recursion. + if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end()) + return false; + + CallStack.push_back(F); + + /// Values - As we compute SSA register values, we store their contents here. + DenseMap Values; + + // Initialize arguments to the incoming values specified. + unsigned ArgNo = 0; + for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E; + ++AI, ++ArgNo) + Values[AI] = ActualArgs[ArgNo]; + + // ExecutedBlocks - We only handle non-looping, non-recursive code. As such, + // we can only evaluate any one basic block at most once. This set keeps + // track of what we have executed so we can detect recursive cases etc. + SmallPtrSet ExecutedBlocks; + + // CurBB - The current basic block we're evaluating. + BasicBlock *CurBB = F->begin(); + + while (1) { + BasicBlock *NextBB; + if (!EvaluateBlock(CurBB, NextBB, CallStack, Values, MutatedMemory, + AllocaTmps, SimpleConstants, TD, TLI)) + return false; + + if (NextBB == 0) { + // Successfully running until there's no next block means that we found + // the return. Fill it the return value and pop the call stack. + ReturnInst *RI = cast(CurBB->getTerminator()); + if (RI->getNumOperands()) + RetVal = getVal(Values, RI->getOperand(0)); + CallStack.pop_back(); + return true; + } + + // Okay, we succeeded in evaluating this control flow. See if we have + // executed the new block before. If so, we have a looping function, + // which we cannot evaluate in reasonable time. + if (!ExecutedBlocks.insert(NextBB)) + return false; // looped! + + // Okay, we have never been in this block before. Check to see if there + // are any PHI nodes. If so, evaluate them with information about where + // we came from. + PHINode *PN = 0; + for (BasicBlock::iterator Inst = NextBB->begin(); + (PN = dyn_cast(Inst)); ++Inst) + Values[PN] = getVal(Values, PN->getIncomingValueForBlock(CurBB)); + + // Advance to the next block. + CurBB = NextBB; + } +} + /// EvaluateStaticConstructor - Evaluate static constructors in the function, if /// we can. Return true if we can, false otherwise. static bool EvaluateStaticConstructor(Function *F, const TargetData *TD, From elena.demikhovsky at intel.com Mon Feb 6 03:02:02 2012 From: elena.demikhovsky at intel.com (Demikhovsky, Elena) Date: Mon, 6 Feb 2012 09:02:02 +0000 Subject: [llvm-commits] Fixed a bug in VCMPPS (X86 AVX) pseudo instructions - Please review In-Reply-To: References: Message-ID: I added the full testing for all possible pseudo-ops of cmp. I extended X86AsmPrinter.cpp and X86IntelInstPrinter.cpp. You?ll also see lines alignments (unrelated to this fix) in X86IselLowering.cpp from my previous check-in. - Elena From: Craig Topper [mailto:craig.topper at gmail.com] Sent: Monday, February 06, 2012 07:26 To: Eric Christopher Cc: Demikhovsky, Elena; llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] Fixed a bug in VCMPPS (X86 AVX) pseudo instructions - Please review Also you should fix the two other places that do the same thing as well. X86AsmPrinter.cpp and X86IntelInstPrinter.cpp. On Sun, Feb 5, 2012 at 9:24 PM, Craig Topper > wrote: As nothing protects the value written in the intrinsic in the source code. I don't think that having a default case for all unexpected values is the right way to go. Maybe the immediate should be masked to remove the reserved encodings? Or the full value should be printed as an integer if its too big? On Sun, Feb 5, 2012 at 5:01 PM, Eric Christopher > wrote: Looks fine, but could you get an exhaustive testcase please? vcmpgeps reg1, reg2, reg3 vcmapfalseps reg1, reg2, reg3 etc? Thanks! On Feb 5, 2012, at 5:12 AM, Demikhovsky, Elena wrote: > This IR code > %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 14) > fails with assertion: > > llc: X86ATTInstPrinter.cpp:62: void llvm::X86ATTInstPrinter::printSSECC(const llvm::MCInst*, unsigned int, llvm::raw_ostream&): Assertion `0 && "Invalid ssecc argument!"' failed. > 0 llc 0x0000000001355803 > 1 llc 0x0000000001355dc9 > 2 libpthread.so.0 0x00007f79a30575d0 > 3 libc.so.6 0x00007f79a23a1945 gsignal + 53 > 4 libc.so.6 0x00007f79a23a2f21 abort + 385 > 5 libc.so.6 0x00007f79a239a810 __assert_fail + 240 > 6 llc 0x00000000011858d5 llvm::X86ATTInstPrinter::printSSECC(llvm::MCInst const*, unsigned int, llvm::raw_ostream&) + 119 > > > Attached a fix. Please review. > > > - Elena > > > --------------------------------------------------------------------- > Intel Israel (74) Limited > > This e-mail and any attachments may contain confidential material for > the sole use of the intended recipient(s). Any review or distribution > by others is strictly prohibited. If you are not the intended > recipient, please contact the sender and delete all copies. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- ~Craig -- ~Craig --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/e44833dd/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: cmp2.diff Type: application/octet-stream Size: 13063 bytes Desc: cmp2.diff Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/e44833dd/attachment.obj From baldrick at free.fr Mon Feb 6 03:04:06 2012 From: baldrick at free.fr (Duncan Sands) Date: Mon, 06 Feb 2012 10:04:06 +0100 Subject: [llvm-commits] [llvm] r149808 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp In-Reply-To: <1271BF87-7645-46D2-8636-73FB3B6DA662@apple.com> References: <20120205034323.74E6F2A6C12C@llvm.org> <4F2E43D1.50709@free.fr> <983DFDC3-8CD8-4AC9-B312-8321A359B79B@apple.com> <1271BF87-7645-46D2-8636-73FB3B6DA662@apple.com> Message-ID: <4F2F9786.4020502@free.fr> ... >> Maybe I'm misremembering, but I thought the conclusion last time this came up >> was that llvm_unreachable should only be used in cases where it was needed to >> mark unreachable code, not to replace assert. Unless I missed something, the >> preferred idiom for "shouldn't be reachable" switch cases is to put them at >> the beginning of the switch with an assert. In a release build, they'll fall >> through but that's no different than any other situation where things fall >> apart when an assertion is not satisfied. > > Some digging shows that indeed I did miss something?. I was remembering Chris > expressing a preference for assert: > > http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20110110/115042.html > > but more recently, John McCall has recommended using llvm_unreachable: > > http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20110919/046498.html > > Sorry for the noise. Can this please then be clearly documented in doc/ProgrammersManual.html or somewhere like that, so that discussion can be laid to rest once and for all. Ciao, Duncan. From benny.kra at googlemail.com Mon Feb 6 04:19:30 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 06 Feb 2012 10:19:30 -0000 Subject: [llvm-commits] [llvm] r149863 - in /llvm/trunk/lib/Target/Hexagon: HexagonCFGOptimizer.cpp HexagonExpandPredSpillCode.cpp HexagonFrameLowering.cpp HexagonInstrInfo.cpp HexagonRegisterInfo.cpp HexagonRemoveSZExtArgs.cpp HexagonSplitTFRCondSets.cpp HexagonTargetMachine.cpp Message-ID: <20120206101930.63B4E2A6C12C@llvm.org> Author: d0k Date: Mon Feb 6 04:19:29 2012 New Revision: 149863 URL: http://llvm.org/viewvc/llvm-project?rev=149863&view=rev Log: Hexagon: Remove forbidden iostream includes (it introduces static initializers) Reorder includes while at it. Modified: llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp llvm/trunk/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp llvm/trunk/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp Modified: llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp Mon Feb 6 04:19:29 2012 @@ -6,27 +6,22 @@ // //===----------------------------------------------------------------------===// - #define DEBUG_TYPE "hexagon_cfg" -#include "llvm/CodeGen/Passes.h" +#include "HexagonTargetMachine.h" +#include "HexagonSubtarget.h" +#include "HexagonMachineFunctionInfo.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/MathExtras.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "HexagonTargetMachine.h" -#include "HexagonSubtarget.h" -#include "HexagonMachineFunctionInfo.h" -#include - -#include "llvm/Support/CommandLine.h" using namespace llvm; Modified: llvm/trunk/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//===--- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ----===// +//===- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code -------===// // // The LLVM Compiler Infrastructure // @@ -17,31 +17,25 @@ // //===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/Passes.h" +#include "HexagonTargetMachine.h" +#include "HexagonSubtarget.h" +#include "HexagonMachineFunctionInfo.h" +#include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/LatencyPriorityQueue.h" -#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" +#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/MathExtras.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "HexagonTargetMachine.h" -#include "HexagonSubtarget.h" -#include "HexagonMachineFunctionInfo.h" -#include -#include - -#include "llvm/Support/CommandLine.h" - using namespace llvm; Modified: llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonFrameLowering.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//==-- HexagonFrameLowering.cpp - Define frame lowering --*- C++ -*-==// +//===- HexagonFrameLowering.cpp - Define frame lowering -------------------===// // // The LLVM Compiler Infrastructure // @@ -7,6 +7,7 @@ // // //===----------------------------------------------------------------------===// + #include "Hexagon.h" #include "HexagonInstrInfo.h" #include "HexagonRegisterInfo.h" @@ -14,27 +15,25 @@ #include "HexagonTargetMachine.h" #include "HexagonMachineFunctionInfo.h" #include "HexagonFrameLowering.h" - +#include "llvm/Function.h" +#include "llvm/Type.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Type.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include +#include "llvm/Support/CommandLine.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Function.h" using namespace llvm; static cl::opt DisableDeallocRet( Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//=- HexagonInstrInfo.cpp - Hexagon Instruction Information -------*- C++ -*-=// +//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===// // // The LLVM Compiler Infrastructure // @@ -15,22 +15,19 @@ #include "HexagonInstrInfo.h" #include "HexagonSubtarget.h" #include "Hexagon.h" -#include "llvm/Support/MathExtras.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/PseudoSourceValue.h" +#include "llvm/Support/MathExtras.h" #define GET_INSTRINFO_CTOR -#include "llvm/CodeGen/DFAPacketizer.h" #include "HexagonGenInstrInfo.inc" #include "HexagonGenDFAPacketizer.inc" -#include - - using namespace llvm; /// Modified: llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//==- HexagonRegisterInfo.cpp - Hexagon Register Information -----*- C++ -*-==// +//===- HexagonRegisterInfo.cpp - Hexagon Register Information -------------===// // // The LLVM Compiler Infrastructure // @@ -17,24 +17,23 @@ #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" #include "HexagonMachineFunctionInfo.h" +#include "llvm/Function.h" +#include "llvm/Type.h" +#include "llvm/ADT/BitVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterScavenging.h" #include "llvm/MC/MachineLocation.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Type.h" -#include "llvm/ADT/BitVector.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -#include +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/Function.h" using namespace llvm; Modified: llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonRemoveSZExtArgs.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//=- HexagonRemoveExtendArgs.cpp - Remove unecessary argument sign extends --=// +//===- HexagonRemoveExtendArgs.cpp - Remove unecessary argument sign extends =// // // The LLVM Compiler Infrastructure // @@ -12,15 +12,12 @@ // //===----------------------------------------------------------------------===// - - -#include "llvm/Pass.h" +#include "HexagonTargetMachine.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/Transforms/Scalar.h" +#include "llvm/Pass.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "HexagonTargetMachine.h" -#include +#include "llvm/Transforms/Scalar.h" using namespace llvm; namespace { Modified: llvm/trunk/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonSplitTFRCondSets.cpp Mon Feb 6 04:19:29 2012 @@ -27,31 +27,24 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "xfer" +#include "HexagonTargetMachine.h" +#include "HexagonSubtarget.h" +#include "HexagonMachineFunctionInfo.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/LatencyPriorityQueue.h" -#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h" -#include "llvm/Target/TargetMachine.h" +#include "llvm/CodeGen/SchedulerRegistry.h" #include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" -#include "llvm/ADT/Statistic.h" #include "llvm/Support/MathExtras.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "HexagonTargetMachine.h" -#include "HexagonSubtarget.h" -#include "HexagonMachineFunctionInfo.h" -#include -#include - -#include "llvm/Support/CommandLine.h" -#define DEBUG_TYPE "xfer" - using namespace llvm; Modified: llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp?rev=149863&r1=149862&r2=149863&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp Mon Feb 6 04:19:29 2012 @@ -1,4 +1,4 @@ -//===-- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon -------===// +//===- HexagonTargetMachine.cpp - Define TargetMachine for Hexagon --------===// // // The LLVM Compiler Infrastructure // @@ -16,11 +16,10 @@ #include "llvm/Module.h" #include "llvm/CodeGen/Passes.h" #include "llvm/PassManager.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Scalar.h" +#include "llvm/Support/CommandLine.h" #include "llvm/Support/TargetRegistry.h" -#include using namespace llvm; From james.molloy at arm.com Mon Feb 6 04:42:57 2012 From: james.molloy at arm.com (James Molloy) Date: Mon, 6 Feb 2012 10:42:57 -0000 Subject: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE Message-ID: <000c01cce4bc$173fe630$45bfb290$@molloy@arm.com> Hi, ARM has the concept of an "unpredictable" instruction - one which is valid (and will be executed) but whose results are not defined. An example of an unpredictable instruction is a load with address increment and writeback where the writeback register is the same as the load destination. The MC disassembler has the concept of a "soft failure" which maps well to unpredictability (coincidentally because it was added for that purpose). However this soft failure can currently only be triggered by manual C++ code such as that in ARMDisassembler.cpp - it cannot be triggered from tablegen-generated code. The attached patch adds this functionality. It adds the ability for the FixedLenDecoderEmitter to take into account a bitfield in a tablegen record called "SoftFail" that mirrors the "Inst" field. If a bitpattern BP matches the Inst field of an instruction record but differs from Inst in any bits which are set to '1' in the SoftFail field, then that instruction is matched by the disassembler but the status SoftFail is returned instead of Success. For example, this is a modified Thumb BX instruction with unpredictability modelled as per the ARMARM: def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>, T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25 bits<4> Rm; let Inst{6-3} = Rm; let Inst{2-0} = 0b000; // Any of the bottom 3 bits set is unpredictable. let SoftFail{2-0} = 0b111; } And this is the generated disassembler code (new code bolded): if ((Bits & ARM::ModeThumb)) { if (insn & 0x7) S = MCDisassembler::SoftFail; MI.setOpcode(2662); tmp = fieldFromInstruction16(insn, 3, 4); if (!Check(S, DecodeGPRRegisterClass(MI, tmp, Address, Decoder))) return MCDisassembler::Fail; return S; // tBXT } This results in the MC now correctly identifying such an instruction: $ echo '0x01 0x47' | ./bin/llvm-mc -triple thumbv7 -disassemble :1:1: warning: potentially undefined instruction encoding 0x01 0x47 ^ bx r0 The patch works by removing any bits that could SoftFail from the set of possible disassembly island values, and emitting an extra test if required in the generated disassembler. If no SoftFail bits are set, no extra code will be emitted. In the ARM tablegen files, this patch aliases SoftFail to "Unpredictable" so it is more recognisable what it is doing in the ARM world. Please review! It wires the new functionality up to "tBX" as a proof of concept and testing codepath, and adds a regression test. Cheers, James -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/6e6a772d/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: softfail.patch Type: application/octet-stream Size: 6605 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/6e6a772d/attachment-0001.obj From benny.kra at googlemail.com Mon Feb 6 05:28:19 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 06 Feb 2012 11:28:19 -0000 Subject: [llvm-commits] [llvm] r149865 - /llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Message-ID: <20120206112819.91E5B2A6C12C@llvm.org> Author: d0k Date: Mon Feb 6 05:28:19 2012 New Revision: 149865 URL: http://llvm.org/viewvc/llvm-project?rev=149865&view=rev Log: Make helper static. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=149865&r1=149864&r2=149865&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon Feb 6 05:28:19 2012 @@ -90,12 +90,12 @@ } } -/// getICmpValue - This is the complement of getICmpCode, which turns an +/// getNewICmpValue - This is the complement of getICmpCode, which turns an /// opcode and two operands into either a constant true or false, or a brand /// new ICmp instruction. The sign is passed in to determine which kind /// of predicate to use in the new icmp instruction. -Value *getNewICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS, - InstCombiner::BuilderTy *Builder) { +static Value *getNewICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS, + InstCombiner::BuilderTy *Builder) { ICmpInst::Predicate NewPred; if (Value *NewConstant = getICmpValue(Sign, Code, LHS, RHS, NewPred)) return NewConstant; From benny.kra at googlemail.com Mon Feb 6 06:06:18 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Mon, 06 Feb 2012 12:06:18 -0000 Subject: [llvm-commits] [llvm] r149866 - /llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Message-ID: <20120206120619.0B7F82A6C12C@llvm.org> Author: d0k Date: Mon Feb 6 06:06:18 2012 New Revision: 149866 URL: http://llvm.org/viewvc/llvm-project?rev=149866&view=rev Log: X86: Don't call malloc for 4 bits. No functionality change. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=149866&r1=149865&r2=149866&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Feb 6 06:06:18 2012 @@ -39,7 +39,6 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSymbol.h" -#include "llvm/ADT/BitVector.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" @@ -5412,7 +5411,7 @@ // mask values count as coming from any quadword, for better codegen. unsigned LoQuad[] = { 0, 0, 0, 0 }; unsigned HiQuad[] = { 0, 0, 0, 0 }; - BitVector InputQuads(4); + std::bitset<4> InputQuads; for (unsigned i = 0; i < 8; ++i) { unsigned *Quad = i < 4 ? LoQuad : HiQuad; int EltIdx = SVOp->getMaskElt(i); @@ -5454,8 +5453,8 @@ bool V2Used = InputQuads[2] || InputQuads[3]; if (Subtarget->hasSSSE3()) { if (InputQuads.count() == 2 && V1Used && V2Used) { - BestLoQuad = InputQuads.find_first(); - BestHiQuad = InputQuads.find_next(BestLoQuad); + BestLoQuad = InputQuads[0] ? 0 : 1; + BestHiQuad = InputQuads[2] ? 2 : 3; } if (InputQuads.count() > 2) { BestLoQuad = -1; From timurrrr at google.com Mon Feb 6 07:49:02 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Mon, 06 Feb 2012 13:49:02 +0000 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) Message-ID: <20cf3074b31ed1cd6704b84bec6b@google.com> Reviewers: kcc1, Message: Hi Kostya, Can you please review this small patch? Regarding the GET_CURRENT_FRAME - see the other e-mail in your inbox; we can un-stub it later if we decide it's needed. Thanks, Timur http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode218 lib/asan/asan_internal.h:218: (uintptr_t)__builtin_extract_return_address(__builtin_return_address(0)) Looks like the __builtin_return_address macro was slightly misused See http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html Description: Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro Please review this at http://codereview.appspot.com/5630065/ Affected files: M lib/asan/asan_internal.h Index: lib/asan/asan_internal.h diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index 713f17c06af3e6a2fba8a50b5a6b6101d20864cf..53656a1f6ffebf6ab93e17254a395b9d81a71a59 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -21,6 +21,8 @@ #include // for size_t, uintptr_t, etc. #if defined(_WIN32) +# include + // There's no in Visual Studio 9, so we have to define [u]int*_t. typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; @@ -212,12 +214,13 @@ const size_t kPageSizeBits = 12; const size_t kPageSize = 1UL << kPageSizeBits; #ifndef _WIN32 -#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) -#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) +# define GET_CALLER_PC() \ + (uintptr_t)__builtin_extract_return_address(__builtin_return_address(0)) +# define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) #else -// TODO(timurrrr): implement. -#define GET_CALLER_PC() (uintptr_t)0 -#define GET_CURRENT_FRAME() (uintptr_t)0 +# define GET_CALLER_PC() (uintptr_t)_ReturnAddress() +// TODO(timurrrr): We don't unwind on Windows - do we need this? +# define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF #endif #define GET_BP_PC_SP \ From timurrrr at google.com Mon Feb 6 08:06:38 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Mon, 06 Feb 2012 14:06:38 +0000 Subject: [llvm-commits] [AddressSanitizer] The first version of Windows malloc interceptors (issue 5636049) Message-ID: <20cf300faf25cef51604b84c2b05@google.com> Reviewers: kcc1, Message: Hi Kostya, Can you please review these Windows malloc interceptors? Thanks, Timur Description: [AddressSanitizer] The first version of Windows malloc interceptors Please review this at http://codereview.appspot.com/5636049/ Affected files: A lib/asan/asan_malloc_win.cc Index: lib/asan/asan_malloc_win.cc diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cc new file mode 100644 index 0000000000000000000000000000000000000000..7c521a687bbc2b7f0c2db9abc6eb1b2367cc5543 --- /dev/null +++ b/lib/asan/asan_malloc_win.cc @@ -0,0 +1,57 @@ +//===-- asan_malloc_win.cc ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific malloc interception. +//===----------------------------------------------------------------------===// +#ifdef _WIN32 + +#include "asan_allocator.h" +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_stack.h" + +namespace __asan { +void ReplaceSystemMalloc() { + // TODO(timurrrr): investigate whether any action is needed. +} +} // namespace __asan + +// ---------------------- Replacement functions ---------------- {{{1 +using namespace __asan; // NOLINT + +// TODO(timurrrr): Simply defining functins with the same signature in *.obj +// files overrides the standard functions in *.lib +// This works well for simple helloworld-like tests but might need to be +// revisited in the future. + +extern "C" { +void free(void *ptr) { + GET_STACK_TRACE_HERE_FOR_FREE(ptr); + return asan_free(ptr, &stack); +} + +void *malloc(size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_malloc(size, &stack); +} + +void *calloc(size_t nmemb, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_calloc(nmemb, size, &stack); +} + +void *realloc(void *ptr, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_realloc(ptr, size, &stack); +} +} // extern "C" + +#endif // _WIN32 From peter at pcc.me.uk Mon Feb 6 08:09:13 2012 From: peter at pcc.me.uk (Peter Collingbourne) Date: Mon, 06 Feb 2012 14:09:13 -0000 Subject: [llvm-commits] [llvm] r149867 - /llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp Message-ID: <20120206140913.639742A6C12C@llvm.org> Author: pcc Date: Mon Feb 6 08:09:13 2012 New Revision: 149867 URL: http://llvm.org/viewvc/llvm-project?rev=149867&view=rev Log: Update ExceptionDemo to use ConstantDataArray. Modified: llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp Modified: llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp?rev=149867&r1=149866&r2=149867&view=diff ============================================================================== --- llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp (original) +++ llvm/trunk/examples/ExceptionDemo/ExceptionDemo.cpp Mon Feb 6 08:09:13 2012 @@ -878,7 +878,7 @@ llvm::Value *stringVar; llvm::Constant *stringConstant = - llvm::ConstantArray::get(context, toPrint); + llvm::ConstantDataArray::getString(context, toPrint); if (useGlobal) { // Note: Does not work without allocation @@ -920,7 +920,8 @@ llvm::Value &toPrint, std::string format, bool useGlobal = true) { - llvm::Constant *stringConstant = llvm::ConstantArray::get(context, format); + llvm::Constant *stringConstant = + llvm::ConstantDataArray::getString(context, format); llvm::Value *stringVar; if (useGlobal) { From glider at google.com Mon Feb 6 08:16:45 2012 From: glider at google.com (glider at google.com) Date: Mon, 06 Feb 2012 14:16:45 +0000 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) Message-ID: <20cf3074b182f7332e04b84c4f06@google.com> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode218 lib/asan/asan_internal.h:218: (uintptr_t)__builtin_extract_return_address(__builtin_return_address(0)) On 2012/02/06 13:49:02, timurrrr_at_google_com wrote: > Looks like the __builtin_return_address macro was slightly misused > See http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html This seems to be ok on x86 and ARM. http://codereview.appspot.com/5630065/ From dpatel at apple.com Mon Feb 6 11:49:43 2012 From: dpatel at apple.com (Devang Patel) Date: Mon, 06 Feb 2012 17:49:43 -0000 Subject: [llvm-commits] [llvm] r149874 - in /llvm/trunk: include/llvm/Analysis/DIBuilder.h include/llvm/Analysis/DebugInfo.h lib/Analysis/DIBuilder.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Message-ID: <20120206174943.F41EC2A6C12C@llvm.org> Author: dpatel Date: Mon Feb 6 11:49:43 2012 New Revision: 149874 URL: http://llvm.org/viewvc/llvm-project?rev=149874&view=rev Log: DebugInfo: Provide a new hook to encode relationship between a property and an ivar. Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DIBuilder.cpp llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DIBuilder.h?rev=149874&r1=149873&r2=149874&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DIBuilder.h (original) +++ llvm/trunk/include/llvm/Analysis/DIBuilder.h Mon Feb 6 11:49:43 2012 @@ -191,6 +191,23 @@ StringRef PropertySetterName = StringRef(), unsigned PropertyAttributes = 0); + /// createObjCIVar - Create debugging information entry for Objective-C + /// instance variable. + /// @param Name Member name. + /// @param File File where this member is defined. + /// @param LineNo Line number. + /// @param SizeInBits Member size. + /// @param AlignInBits Member alignment. + /// @param OffsetInBits Member offset. + /// @param Flags Flags to encode member attribute, e.g. private + /// @param Ty Parent type. + /// @param Property Property associated with this ivar. + DIType createObjCIVar(StringRef Name, DIFile File, + unsigned LineNo, uint64_t SizeInBits, + uint64_t AlignInBits, uint64_t OffsetInBits, + unsigned Flags, DIType Ty, + MDNode *PropertyNode); + /// createObjCProperty - Create debugging information entry for Objective-C /// property. /// @param Name Property name. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=149874&r1=149873&r2=149874&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Mon Feb 6 11:49:43 2012 @@ -43,6 +43,7 @@ class DILexicalBlockFile; class DIVariable; class DIType; + class DIObjCProperty; /// DIDescriptor - A thin wraper around MDNode to access encoded debug info. /// This should not be stored in a container, because underly MDNode may @@ -356,6 +357,10 @@ /// return base type size. uint64_t getOriginalTypeSize() const; + /// getObjCProperty - Return property node, if this ivar is + /// associated with one. + MDNode *getObjCProperty() const; + StringRef getObjCPropertyName() const { if (getVersion() > LLVMDebugVersion11) return StringRef(); Modified: llvm/trunk/lib/Analysis/DIBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DIBuilder.cpp?rev=149874&r1=149873&r2=149874&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DIBuilder.cpp (original) +++ llvm/trunk/lib/Analysis/DIBuilder.cpp Mon Feb 6 11:49:43 2012 @@ -359,6 +359,30 @@ return DIType(MDNode::get(VMContext, Elts)); } +/// createObjCIVar - Create debugging information entry for Objective-C +/// instance variable. +DIType DIBuilder::createObjCIVar(StringRef Name, + DIFile File, unsigned LineNumber, + uint64_t SizeInBits, uint64_t AlignInBits, + uint64_t OffsetInBits, unsigned Flags, + DIType Ty, MDNode *PropertyNode) { + // TAG_member is encoded in DIDerivedType format. + Value *Elts[] = { + GetTagConstant(VMContext, dwarf::DW_TAG_member), + getNonCompileUnitScope(File), + MDString::get(VMContext, Name), + File, + ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), + ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), + ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits), + ConstantInt::get(Type::getInt32Ty(VMContext), Flags), + Ty, + PropertyNode + }; + return DIType(MDNode::get(VMContext, Elts)); +} + /// createObjCProperty - Create debugging information entry for Objective-C /// property. DIObjCProperty DIBuilder::createObjCProperty(StringRef Name, Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=149874&r1=149873&r2=149874&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Feb 6 11:49:43 2012 @@ -510,6 +510,13 @@ return getSizeInBits(); } +/// getObjCProperty - Return property node, if this ivar is associated with one. +MDNode *DIDerivedType::getObjCProperty() const { + if (getVersion() <= LLVMDebugVersion11 || DbgNode->getNumOperands() <= 10) + return NULL; + return dyn_cast_or_null(DbgNode->getOperand(10)); +} + /// isInlinedFnArgument - Return true if this variable provides debugging /// information for an inlined function arguments. bool DIVariable::isInlinedFnArgument(const Function *CurFn) { Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=149874&r1=149873&r2=149874&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Mon Feb 6 11:49:43 2012 @@ -851,6 +851,12 @@ if (PropertyAttributes) addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0, PropertyAttributes); + + DIEEntry *Entry = getDIEEntry(Element); + if (!Entry) { + Entry = createDIEEntry(ElemDie); + insertDIEEntry(Element, Entry); + } } else continue; Buffer.addChild(ElemDie); @@ -1455,6 +1461,11 @@ dwarf::DW_VIRTUALITY_virtual); // Objective-C properties. + if (MDNode *PNode = DT.getObjCProperty()) + if (DIEEntry *PropertyDie = getDIEEntry(PNode)) + MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4, + PropertyDie); + // This is only for backward compatibility. StringRef PropertyName = DT.getObjCPropertyName(); if (!PropertyName.empty()) { From kcc at google.com Mon Feb 6 11:56:38 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 06 Feb 2012 17:56:38 -0000 Subject: [llvm-commits] [compiler-rt] r149875 - /compiler-rt/trunk/lib/asan/asan_malloc_win.cc Message-ID: <20120206175638.DDDEC2A6C12C@llvm.org> Author: kcc Date: Mon Feb 6 11:56:38 2012 New Revision: 149875 URL: http://llvm.org/viewvc/llvm-project?rev=149875&view=rev Log: [asan] The first version of Windows malloc interceptors, patch by timurrrr at google.com Added: compiler-rt/trunk/lib/asan/asan_malloc_win.cc Added: compiler-rt/trunk/lib/asan/asan_malloc_win.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_win.cc?rev=149875&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_win.cc (added) +++ compiler-rt/trunk/lib/asan/asan_malloc_win.cc Mon Feb 6 11:56:38 2012 @@ -0,0 +1,57 @@ +//===-- asan_malloc_win.cc --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific malloc interception. +//===----------------------------------------------------------------------===// +#ifdef _WIN32 + +#include "asan_allocator.h" +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_stack.h" + +namespace __asan { +void ReplaceSystemMalloc() { + // FIXME: investigate whether any action is needed. +} +} // namespace __asan + +// ---------------------- Replacement functions ---------------- {{{1 +using namespace __asan; // NOLINT + +// FIXME: Simply defining functions with the same signature in *.obj +// files overrides the standard functions in *.lib +// This works well for simple helloworld-like tests but might need to be +// revisited in the future. + +extern "C" { +void free(void *ptr) { + GET_STACK_TRACE_HERE_FOR_FREE(ptr); + return asan_free(ptr, &stack); +} + +void *malloc(size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_malloc(size, &stack); +} + +void *calloc(size_t nmemb, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_calloc(nmemb, size, &stack); +} + +void *realloc(void *ptr, size_t size) { + GET_STACK_TRACE_HERE_FOR_MALLOC; + return asan_realloc(ptr, size, &stack); +} +} // extern "C" + +#endif // _WIN32 From kcc at google.com Mon Feb 6 12:01:02 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 10:01:02 -0800 Subject: [llvm-commits] [AddressSanitizer] The first version of Windows malloc interceptors (issue 5636049) In-Reply-To: <20cf300faf25cef51604b84c2b05@google.com> References: <20cf300faf25cef51604b84c2b05@google.com> Message-ID: r149875, thanks! On Mon, Feb 6, 2012 at 6:06 AM, wrote: > Reviewers: kcc1, > > Message: > Hi Kostya, > > Can you please review these Windows malloc interceptors? > > Thanks, > Timur > > Description: > [AddressSanitizer] The first version of Windows malloc interceptors > > Please review this at http://codereview.appspot.com/**5636049/ > > Affected files: > A lib/asan/asan_malloc_win.cc > > > Index: lib/asan/asan_malloc_win.cc > diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cc > new file mode 100644 > index 000000000000000000000000000000**0000000000..** > 7c521a687bbc2b7f0c2db9abc6eb1b**2367cc5543 > --- /dev/null > +++ b/lib/asan/asan_malloc_win.cc > @@ -0,0 +1,57 @@ > +//===-- asan_malloc_win.cc ------------------------------**------*- C++ > -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===------------------------**------------------------------** > ----------------===// > +// > +// This file is a part of AddressSanitizer, an address sanity checker. > +// > +// Windows-specific malloc interception. > +//===------------------------**------------------------------** > ----------------===// > +#ifdef _WIN32 > + > +#include "asan_allocator.h" > +#include "asan_interceptors.h" > +#include "asan_internal.h" > +#include "asan_stack.h" > + > +namespace __asan { > +void ReplaceSystemMalloc() { > + // TODO(timurrrr): investigate whether any action is needed. > +} > +} // namespace __asan > + > +// ---------------------- Replacement functions ---------------- {{{1 > +using namespace __asan; // NOLINT > + > +// TODO(timurrrr): Simply defining functins with the same signature in > *.obj > +// files overrides the standard functions in *.lib > +// This works well for simple helloworld-like tests but might need to be > +// revisited in the future. > + > +extern "C" { > +void free(void *ptr) { > + GET_STACK_TRACE_HERE_FOR_FREE(**ptr); > + return asan_free(ptr, &stack); > +} > + > +void *malloc(size_t size) { > + GET_STACK_TRACE_HERE_FOR_**MALLOC; > + return asan_malloc(size, &stack); > +} > + > +void *calloc(size_t nmemb, size_t size) { > + GET_STACK_TRACE_HERE_FOR_**MALLOC; > + return asan_calloc(nmemb, size, &stack); > +} > + > +void *realloc(void *ptr, size_t size) { > + GET_STACK_TRACE_HERE_FOR_**MALLOC; > + return asan_realloc(ptr, size, &stack); > +} > +} // extern "C" > + > +#endif // _WIN32 > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/f75950db/attachment.html From isanbard at gmail.com Mon Feb 6 11:58:35 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 17:58:35 -0000 Subject: [llvm-commits] [llvm] r149876 - /llvm/trunk/docs/LangRef.html Message-ID: <20120206175835.9B0BE2A6C12C@llvm.org> Author: void Date: Mon Feb 6 11:58:34 2012 New Revision: 149876 URL: http://llvm.org/viewvc/llvm-project?rev=149876&view=rev Log: Mention that the 'unwind' instruction is now deprecated. Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=149876&r1=149875&r2=149876&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Feb 6 11:58:34 2012 @@ -3495,6 +3495,9 @@
Overview:
+

N.B. The unwind instruction has been + deprecated and is slated for removal.

+

The 'unwind' instruction unwinds the stack, continuing control flow at the first callee in the dynamic call stack which used an invoke instruction to perform the call. From resistor at mac.com Mon Feb 6 12:19:12 2012 From: resistor at mac.com (Owen Anderson) Date: Mon, 06 Feb 2012 10:19:12 -0800 Subject: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE In-Reply-To: <000c01cce4bc$173fe630$45bfb290$%molloy@arm.com> References: <000c01cce4bc$173fe630$45bfb290$%molloy@arm.com> Message-ID: <9F39D766-682D-4279-8D04-814291A11FBA@mac.com> James, I like the concept of this feature, and it'd be nice if it could help use eliminate more of the hand-written decoding hooks. However, I'm concerned about the impact it will have on LLVM's build time. Have you looked at how much bigger this makes the generated disassembler file? It already takes a very long time to compile, and I'm wage to avoid making it any worse. --Owen On Feb 6, 2012, at 2:42 AM, James Molloy wrote: > Hi, > > ARM has the concept of an ?unpredictable? instruction ? one which is valid (and will be executed) but whose results are not defined. An example of an unpredictable instruction is a load with address increment and writeback where the writeback register is the same as the load destination. > > The MC disassembler has the concept of a ?soft failure? which maps well to unpredictability (coincidentally because it was added for that purpose). However this soft failure can currently only be triggered by manual C++ code such as that in ARMDisassembler.cpp ? it cannot be triggered from tablegen-generated code. > > The attached patch adds this functionality. It adds the ability for the FixedLenDecoderEmitter to take into account a bitfield in a tablegen record called ?SoftFail? that mirrors the ?Inst? field. > > If a bitpattern BP matches the Inst field of an instruction record but differs from Inst in any bits which are set to ?1? in the SoftFail field, then that instruction is matched by the disassembler but the status SoftFail is returned instead of Success. > > For example, this is a modified Thumb BX instruction with unpredictability modelled as per the ARMARM: > > def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>, > T1Special<{1,1,0,?}> { > // A6.2.3 & A8.6.25 > bits<4> Rm; > let Inst{6-3} = Rm; > let Inst{2-0} = 0b000; > // Any of the bottom 3 bits set is unpredictable. > let SoftFail{2-0} = 0b111; > } > > And this is the generated disassembler code (new code bolded): > > if ((Bits & ARM::ModeThumb)) { > if (insn & 0x7) > S = MCDisassembler::SoftFail; > MI.setOpcode(2662); > tmp = fieldFromInstruction16(insn, 3, 4); > if (!Check(S, DecodeGPRRegisterClass(MI, tmp, Address, Decoder))) return MCDisassembler::Fail; > return S; // tBX? > } > > This results in the MC now correctly identifying such an instruction: > > $ echo '0x01 0x47' | ./bin/llvm-mc -triple thumbv7 -disassemble > :1:1: warning: potentially undefined instruction encoding > 0x01 0x47 > ^ > bx r0 > > The patch works by removing any bits that could SoftFail from the set of possible disassembly island values, and emitting an extra test if required in the generated disassembler. If no SoftFail bits are set, no extra code will be emitted. > > In the ARM tablegen files, this patch aliases SoftFail to ?Unpredictable? so it is more recognisable what it is doing in the ARM world. > > Please review! It wires the new functionality up to ?tBX? as a proof of concept and testing codepath, and adds a regression test. > > Cheers, > > James > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/34834cfb/attachment.html From dpatel at apple.com Mon Feb 6 12:18:26 2012 From: dpatel at apple.com (Devang Patel) Date: Mon, 06 Feb 2012 18:18:26 -0000 Subject: [llvm-commits] [llvm] r149879 - /llvm/trunk/docs/SourceLevelDebugging.html Message-ID: <20120206181826.41F252A6C12C@llvm.org> Author: dpatel Date: Mon Feb 6 12:18:25 2012 New Revision: 149879 URL: http://llvm.org/viewvc/llvm-project?rev=149879&view=rev Log: Update docs describing objective-c property encoding. This includes support for properties that are not backed by an ivar. Modified: llvm/trunk/docs/SourceLevelDebugging.html Modified: llvm/trunk/docs/SourceLevelDebugging.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=149879&r1=149878&r2=149879&view=diff ============================================================================== --- llvm/trunk/docs/SourceLevelDebugging.html (original) +++ llvm/trunk/docs/SourceLevelDebugging.html Mon Feb 6 12:18:25 2012 @@ -1861,11 +1861,32 @@

-

Objective C properties are always backed by an instance variable. The -instance variables backing properties are identified using -DW_AT_APPLE_property_name attribute. The instance variables with this -attribute may not have data location attributes. The location of instance -variables is determined by debugger only after consulting Objective C runtime. +

Objective C properties exist separately from class members. A property +can be defined only by "setter" and "getter" selectors, and +be calculated anew on each access. Or a property can just be a direct access +to some declared ivar. Finally it can have an ivar "automatically +synthesized" for it by the compiler, in which case the property can be +referred to in user code directly using the standard C dereference syntax as +well as through the property "dot" syntax, but there is no entry in +the @interface declaration corresponding to this ivar. +

+

+To facilitate debugging, these properties we will add a new DWARF TAG into the +DW_TAG_structure_type definition for the class to hold the description of a +given property, and a set of DWARF attributes that provide said description. +The property tag will also contain the name and declared type of the property. +

+

+If there is a related ivar, there will also be a DWARF property attribute placed +in the DW_TAG_member DIE for that ivar referring back to the property TAG for +that property. And in the case where the compiler synthesizes the ivar directly, +the compiler is expected to generate a DW_TAG_member for that ivar (with the +DW_AT_artificial set to 1), whose name will be the name used to access this +ivar directly in code, and with the property attribute pointing back to the +property it is backing. +

+

+The following examples will serve as illustration for our discussion:

@@ -1874,34 +1895,66 @@ int n2; } - at property p1; - at property p2; + at property int p1; + at property int p2; @end @implementation I1 @synthesize p1; @synthesize p2 = n2; @end + +
+

+This produces the following DWARF (this is a "pseudo dwarfdump" output): +

+
+
+0x00000100:  TAG_structure_type [7] * 
+               AT_APPLE_runtime_class( 0x10 )
+               AT_name( "I1" )
+               AT_decl_file( "Objc_Property.m" ) 
+               AT_decl_line( 3 )
+
+0x00000110    TAG_APPLE_property
+                AT_name ( "p1" )
+                AT_type ( {0x00000150} ( int ) )
+
+0x00000120:   TAG_APPLE_property
+                AT_name ( "p2" )
+                AT_type ( {0x00000150} ( int ) )
+
+0x00000130:   TAG_member [8] 
+                AT_name( "_p1" )
+                AT_APPLE_property ( {0x00000110} "p1" )
+                AT_type( {0x00000150} ( int ) )
+                AT_artificial ( 0x1 )
+
+0x00000140:    TAG_member [8] 
+                 AT_name( "n2" )
+                 AT_APPLE_property ( {0x00000120} "p2" )
+                 AT_type( {0x00000150} ( int ) )
 
-TAG_structure_type [7] * 
-  AT_APPLE_runtime_class( 0x10 )
-  AT_name( "I1" )
-  AT_decl_file( "Objc_Property.m" ) 
-  AT_decl_line( 3 )
-
-  TAG_member [8] 
-    AT_name( "p1" )
-    AT_APPLE_property_name(???p1???) 
-    AT_type( {0x00000147} ( int ) )
-
-  TAG_member [8] 
-    AT_name( "n2" )
-    AT_APPLE_property_name(???p2???) 
-    AT_type( {0x00000147} ( int ) )
+0x00000150:  AT_type( ( int ) )
 
+

Note, the current convention is that the name of the ivar for an +auto-synthesized property is the name of the property from which it derives with +an underscore prepended, as is shown in the example. +But we actually don't need to know this convention, since we are given the name +of the ivar directly. +

+ +

+Also, it is common practice in ObjC to have different property declarations in +the @interface and @implementation - e.g. to provide a read-only property in +the interface,and a read-write interface in the implementation. In that case, +the compiler should emit whichever property declaration will be in force in the +current translation unit. +

+

Developers can decorate a property with attributes which are encoded using DW_AT_APPLE_property_attribute.

@@ -1909,11 +1962,15 @@
 @property (readonly, nonatomic) int pr;
-
-
-TAG_member [8] 
-  AT_name(???pr???) 
-  AT_APPLE_property_name(???pr???) 
+
+
+

+Which produces a property tag: +

+

+
+TAG_APPLE_property [8] 
+  AT_name( "pr" ) 
   AT_type ( {0x00000147} (int) ) 
   AT_APPLE_property_attribute (DW_APPLE_PROPERTY_readonly, DW_APPLE_PROPERTY_nonatomic)
 
@@ -1933,17 +1990,30 @@ @synthesize p3; -(void)myOwnP3Setter:(int)a{ } @end + +
+

+The DWARF for this would be: +

+
+
 0x000003bd: TAG_structure_type [7] * 
               AT_APPLE_runtime_class( 0x10 )
               AT_name( "I1" )
               AT_decl_file( "Objc_Property.m" ) 
               AT_decl_line( 3 )
-0x000003f3: TAG_member [8] 
-              AT_name( "p3" ) 
-              AT_APPLE_property_name(???p3???) 
-              AT_APPLE_property_setter(???myOwnP3Setter:???)
-              AT_type( {0x00000147} ( int ) )
+
+0x000003cd      TAG_APPLE_property
+                  AT_name ( "p3" )
+                  AT_APPLE_property_setter ( "myOwnP3Setter:" )
+                  AT_type( {0x00000147} ( int ) )
+              
+0x000003f3:     TAG_member [8] 
+                  AT_name( "_p3" ) 
+                  AT_type ( {0x00000147} ( int ) )
+                  AT_APPLE_property ( {0x000003cd} )
+                  AT_artificial ( 0x1 )
 
@@ -1951,6 +2021,26 @@

+ New DWARF Tags +

+ + +
+ + + + + + + + + +
TAGValue
DW_TAG_APPLE_property0x4200
+ +
+ + +

New DWARF Attributes

@@ -1963,9 +2053,9 @@ Classes - DW_AT_APPLE_property_name - 0x3fe8 - String + DW_AT_APPLE_property + 0x3fed + Reference DW_AT_APPLE_property_getter From isanbard at gmail.com Mon Feb 6 12:18:47 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 18:18:47 -0000 Subject: [llvm-commits] [llvm] r149880 - /llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll Message-ID: <20120206181847.AB3652A6C12C@llvm.org> Author: void Date: Mon Feb 6 12:18:47 2012 New Revision: 149880 URL: http://llvm.org/viewvc/llvm-project?rev=149880&view=rev Log: The 'unwind' instruction is deprecated and will be removed, making this test obsolete. Removed: llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll Removed: llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll?rev=149879&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll (original) +++ llvm/trunk/test/Transforms/SimplifyCFG/2010-10-24-OnlyUnwindInEntry.ll (removed) @@ -1,6 +0,0 @@ -; RUN: opt %s -simplifycfg -disable-output -; PR8445 - -define void @test() { - unwind -} From slarin at codeaurora.org Mon Feb 6 12:56:48 2012 From: slarin at codeaurora.org (Sergei Larin) Date: Mon, 6 Feb 2012 12:56:48 -0600 Subject: [llvm-commits] Question about /llvm/trunk/lib/CodeGen/MachineScheduler.cpp In-Reply-To: References: <20120204052617.5CAF92A6C12C@llvm.org> Message-ID: <0e7e01cce501$14cd0410$3e670c30$@org> Andrew, This is something between a bug report and a question. I do not provide enough context to reproduce the failure, but hope it is fresh enough in your memory :) In lib/CodeGen/MachineScheduler.cpp In bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {} While iterating over following MBB, for the following fragment ... BB#6: derived from LLVM BB %sw.bb6, ADDRESS TAKEN Predecessors according to CFG: BB#1 %vreg10 = TFRI 1; IntRegs:%vreg10 STrib %vreg1, 0, %vreg10; mem:ST1[%Enum_Ref_Par] IntRegs:%vreg1,%vreg10 JMP Successors according to CFG: BB#8 BB#7: derived from LLVM BB %sw.bb7, ADDRESS TAKEN Predecessors according to CFG: BB#1 %vreg9 = TFRI 2; IntRegs:%vreg9 STrib %vreg1, 0, %vreg9; mem:ST1[%Enum_Ref_Par] IntRegs:%vreg1,%vreg9 Successors according to CFG: BB#8 BB#8: derived from LLVM BB %sw.epilog, ADDRESS TAKEN Predecessors according to CFG: BB#0 BB#1 BB#7 BB#6 BB#5 BB#4 BB#2 JMPR %PC, %R31, %R0 ... BB#7 seems to cause a problem when iterating over it with RegionEnd pointing somewhere wrong. Am I breaking some implicit assumption in BB formation? Want MBB->end() suppose to return for the BB#7? *** Final schedule *** MachineScheduling Proc_6:BB#7 From: %vreg9 = TFRI 2; IntRegs:%vreg9 To: Program received signal SIGSEGV, Segmentation fault. 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ MachineOperand.h:204 204 bool isReg() const { return OpKind == MO_Register; } (gdb) bt #0 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ MachineOperand.h:204 #1 0x00000000021ca720 in llvm::MachineInstr::print (this=0x3e2c9f0, OS=..., TM=0x0) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineIn str.cpp:1462 #2 0x0000000001a970fe in llvm::operator<< (OS=..., MI=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ MachineInstr.h:934 #3 0x00000000022e4c18 in (anonymous namespace)::MachineScheduler::runOnMachineFunction (this=0x3dcc1c0, mf=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineSc heduler.cpp:297 #4 0x00000000021c41e5 in llvm::MachineFunctionPass::runOnFunction (this=0x3dcc1c0, F=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineFu nctionPass.cpp:33 #5 0x0000000002789db6 in llvm::FPPassManager::runOnFunction (this=0x3dcb820, F=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage r.cpp:1498 #6 0x000000000278a001 in llvm::FPPassManager::runOnModule (this=0x3dcb820, M=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage r.cpp:1520 #7 0x000000000278a344 in llvm::MPPassManager::runOnModule (this=0x3dc8ec0, M=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage r.cpp:1574 #8 0x000000000278a85a in llvm::PassManagerImpl::run (this=0x3dc8b70, M=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage r.cpp:1658 #9 0x000000000278ab55 in llvm::PassManager::run (this=0x3d7f140, M=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage r.cpp:1687 #10 0x0000000000c9488d in (anonymous namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fffffffa2e0, Action=clang::Backend_EmitAssembly, OS=0x3d13660) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG en/BackendUtil.cpp:497 #11 0x0000000000c94968 in clang::EmitBackendOutput (Diags=..., CGOpts=..., TOpts=..., LOpts=..., M=0x3d1a3c0, Action=clang::Backend_EmitAssembly, OS=0x3d13660) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG en/BackendUtil.cpp:509 #12 0x0000000000c9042c in clang::BackendConsumer::HandleTranslationUnit (this=0x3d123a0, C=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG en/CodeGenAction.cpp:155 #13 0x0000000000e3cf61 in clang::ParseAST (S=..., PrintStats=false) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Parse /ParseAST.cpp:110 #14 0x0000000000b00725 in clang::ASTFrontendAction::ExecuteAction (this=0x3cf1740) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front end/FrontendAction.cpp:414 #15 0x0000000000c8ef9c in clang::CodeGenAction::ExecuteAction (this=0x3cf1740) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG en/CodeGenAction.cpp:407 #16 0x0000000000b00377 in clang::FrontendAction::Execute (this=0x3cf1740) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front end/FrontendAction.cpp:334 #17 0x0000000000ad8e63 in clang::CompilerInstance::ExecuteAction (this=0x3ced2d0, Act=...) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front end/CompilerInstance.cpp:653 #18 0x0000000000aaa8e4 in clang::ExecuteCompilerInvocation (Clang=0x3ced2d0) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front endTool/ExecuteCompilerInvocation.cpp:175 #19 0x0000000000a99618 in cc1_main (ArgBegin=0x7fffffffaf10, ArgEnd=0x7fffffffb108, Argv0=0x3cebaf8 "/prj/qct/sunray-austin/scratch/slarin/qdsp6_hex/bin/qc/bin/clang", MainAddr=0xaa4654) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/tools/dri ver/cc1_main.cpp:165 #20 0x0000000000aa5e77 in main (argc_=65, argv_=0x7fffffffc058) at /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/tools/dri ver/driver.cpp:353 Thanks. Sergei From dschuff at google.com Mon Feb 6 13:03:04 2012 From: dschuff at google.com (Derek Schuff) Date: Mon, 06 Feb 2012 19:03:04 -0000 Subject: [llvm-commits] [llvm] r149887 - /llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Message-ID: <20120206190304.D92172A6C12C@llvm.org> Author: dschuff Date: Mon Feb 6 13:03:04 2012 New Revision: 149887 URL: http://llvm.org/viewvc/llvm-project?rev=149887&view=rev Log: Test commit; also removes some trailing whitespace Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149887&r1=149886&r2=149887&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 13:03:04 2012 @@ -401,7 +401,7 @@ // The type table size is always specified correctly. if (ID >= TypeList.size()) return 0; - + if (Type *Ty = TypeList[ID]) return Ty; @@ -522,7 +522,7 @@ bool BitcodeReader::ParseTypeTable() { if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) return Error("Malformed block record"); - + return ParseTypeTableBody(); } @@ -534,7 +534,7 @@ unsigned NumRecords = 0; SmallString<64> TypeName; - + // Read all the records for this type table. while (1) { unsigned Code = Stream.ReadCode(); From James.Molloy at arm.com Mon Feb 6 13:14:35 2012 From: James.Molloy at arm.com (James Molloy) Date: Mon, 6 Feb 2012 19:14:35 +0000 Subject: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE In-Reply-To: <9F39D766-682D-4279-8D04-814291A11FBA@mac.com> References: <000c01cce4bc$173fe630$45bfb290$%molloy@arm.com>, <9F39D766-682D-4279-8D04-814291A11FBA@mac.com> Message-ID: Hi Owen, For the generated disassembler it only adds two lines of code and only on instructions that require it. The difference in size before and after this patch is +2 lines, because it is only hooked up to tBX. There is no noticeable build time difference. Cheers, James ________________________________________ From: Owen Anderson [resistor at mac.com] Sent: 06 February 2012 18:19 To: James Molloy Cc: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE James, I like the concept of this feature, and it'd be nice if it could help use eliminate more of the hand-written decoding hooks. However, I'm concerned about the impact it will have on LLVM's build time. Have you looked at how much bigger this makes the generated disassembler file? It already takes a very long time to compile, and I'm wage to avoid making it any worse. --Owen On Feb 6, 2012, at 2:42 AM, James Molloy wrote: Hi, ARM has the concept of an ?unpredictable? instruction ? one which is valid (and will be executed) but whose results are not defined. An example of an unpredictable instruction is a load with address increment and writeback where the writeback register is the same as the load destination. The MC disassembler has the concept of a ?soft failure? which maps well to unpredictability (coincidentally because it was added for that purpose). However this soft failure can currently only be triggered by manual C++ code such as that in ARMDisassembler.cpp ? it cannot be triggered from tablegen-generated code. The attached patch adds this functionality. It adds the ability for the FixedLenDecoderEmitter to take into account a bitfield in a tablegen record called ?SoftFail? that mirrors the ?Inst? field. If a bitpattern BP matches the Inst field of an instruction record but differs from Inst in any bits which are set to ?1? in the SoftFail field, then that instruction is matched by the disassembler but the status SoftFail is returned instead of Success. For example, this is a modified Thumb BX instruction with unpredictability modelled as per the ARMARM: def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>, T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25 bits<4> Rm; let Inst{6-3} = Rm; let Inst{2-0} = 0b000; // Any of the bottom 3 bits set is unpredictable. let SoftFail{2-0} = 0b111; } And this is the generated disassembler code (new code bolded): if ((Bits & ARM::ModeThumb)) { if (insn & 0x7) S = MCDisassembler::SoftFail; MI.setOpcode(2662); tmp = fieldFromInstruction16(insn, 3, 4); if (!Check(S, DecodeGPRRegisterClass(MI, tmp, Address, Decoder))) return MCDisassembler::Fail; return S; // tBX? } This results in the MC now correctly identifying such an instruction: $ echo '0x01 0x47' | ./bin/llvm-mc -triple thumbv7 -disassemble :1:1: warning: potentially undefined instruction encoding 0x01 0x47 ^ bx r0 The patch works by removing any bits that could SoftFail from the set of possible disassembly island values, and emitting an extra test if required in the generated disassembler. If no SoftFail bits are set, no extra code will be emitted. In the ARM tablegen files, this patch aliases SoftFail to ?Unpredictable? so it is more recognisable what it is doing in the ARM world. Please review! It wires the new functionality up to ?tBX? as a proof of concept and testing codepath, and adds a regression test. Cheers, James _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. From konstantin.s.serebryany at gmail.com Mon Feb 6 13:18:31 2012 From: konstantin.s.serebryany at gmail.com (konstantin.s.serebryany at gmail.com) Date: Mon, 06 Feb 2012 19:18:31 +0000 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) Message-ID: <20cf300faf2526e7b504b85087e2@google.com> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 lib/asan/asan_internal.h:24: # include Can we avoid this include in the header? ( I am not sure we can, just asking) http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode218 lib/asan/asan_internal.h:218: (uintptr_t)__builtin_extract_return_address(__builtin_return_address(0)) I'd keep this as as, it works. http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode222 lib/asan/asan_internal.h:222: // TODO(timurrrr): We don't unwind on Windows - do we need this? What do you mean "we don't unwind"? Also, better use FIXME instead of TODO(user) http://codereview.appspot.com/5630065/ From kcc at google.com Mon Feb 6 13:23:38 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 06 Feb 2012 19:23:38 -0000 Subject: [llvm-commits] [compiler-rt] r149892 - /compiler-rt/trunk/lib/asan/asan_linux.cc Message-ID: <20120206192338.C52A52A6C12C@llvm.org> Author: kcc Date: Mon Feb 6 13:23:38 2012 New Revision: 149892 URL: http://llvm.org/viewvc/llvm-project?rev=149892&view=rev Log: [asan] use raw syscalls for open/close on linux to avoid being intercepted Modified: compiler-rt/trunk/lib/asan/asan_linux.cc Modified: compiler-rt/trunk/lib/asan/asan_linux.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=149892&r1=149891&r2=149892&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_linux.cc (original) +++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Feb 6 13:23:38 2012 @@ -118,7 +118,7 @@ } int AsanOpenReadonly(const char* filename) { - return open(filename, O_RDONLY); + return syscall(__NR_open, filename, O_RDONLY); } // Like getenv, but reads env directly from /proc and does not use libc. @@ -154,7 +154,7 @@ } int AsanClose(int fd) { - return close(fd); + return syscall(__NR_close, fd); } AsanProcMaps::AsanProcMaps() { From kcc at google.com Mon Feb 6 13:58:27 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 11:58:27 -0800 Subject: [llvm-commits] Please review: fix conflict between AddressSanitizer and load widening (GVN) Message-ID: Hi, The attached patch resolves the conflict between AddressSanitizer and load widening (GVN). The problem initially reported by Mozilla folks ( http://code.google.com/p/address-sanitizer/issues/detail?id=20), but it also prevents us from enabling LLVM bootstrap with AddressSanitizer. http://codereview.appspot.com/5630068 Thanks, --kcc -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/c9f93bff/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: issue5630068_1.diff Type: text/x-patch Size: 2853 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/c9f93bff/attachment.bin From sebastian.redl at getdesigned.at Mon Feb 6 13:13:14 2012 From: sebastian.redl at getdesigned.at (Sebastian Redl) Date: Mon, 6 Feb 2012 20:13:14 +0100 Subject: [llvm-commits] [compiler-rt] r149875 - /compiler-rt/trunk/lib/asan/asan_malloc_win.cc In-Reply-To: <20120206175638.DDDEC2A6C12C@llvm.org> References: <20120206175638.DDDEC2A6C12C@llvm.org> Message-ID: <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> On 06.02.2012, at 18:56, Kostya Serebryany wrote: > Author: kcc > Date: Mon Feb 6 11:56:38 2012 > New Revision: 149875 > > URL: http://llvm.org/viewvc/llvm-project?rev=149875&view=rev > Log: > [asan] The first version of Windows malloc interceptors, patch by timurrrr at google.com > > +// FIXME: Simply defining functions with the same signature in *.obj > +// files overrides the standard functions in *.lib > +// This works well for simple helloworld-like tests but might need to be > +// revisited in the future. Do you support mixing non-asan modules (DLLs) with asan modules? I can see trouble there, if a module allocates with native malloc and another frees with asan malloc, or vice versa. Sebastian From clattner at apple.com Mon Feb 6 14:35:51 2012 From: clattner at apple.com (Chris Lattner) Date: Mon, 06 Feb 2012 12:35:51 -0800 Subject: [llvm-commits] [llvm] r149876 - /llvm/trunk/docs/LangRef.html In-Reply-To: <20120206175835.9B0BE2A6C12C@llvm.org> References: <20120206175835.9B0BE2A6C12C@llvm.org> Message-ID: On Feb 6, 2012, at 9:58 AM, Bill Wendling wrote: > Author: void > Date: Mon Feb 6 11:58:34 2012 > New Revision: 149876 > > URL: http://llvm.org/viewvc/llvm-project?rev=149876&view=rev > Log: > Mention that the 'unwind' instruction is now deprecated. Hi Bill, We generally don't do this. Just remove it when it's gone. -Chris > > Modified: > llvm/trunk/docs/LangRef.html > > Modified: llvm/trunk/docs/LangRef.html > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=149876&r1=149875&r2=149876&view=diff > ============================================================================== > --- llvm/trunk/docs/LangRef.html (original) > +++ llvm/trunk/docs/LangRef.html Mon Feb 6 11:58:34 2012 > @@ -3495,6 +3495,9 @@ > > >
Overview:
> +

N.B. The unwind instruction has been > + deprecated and is slated for removal.

> + >

The 'unwind' instruction unwinds the stack, continuing control flow > at the first callee in the dynamic call stack which used > an invoke instruction to perform the call. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Mon Feb 6 14:36:10 2012 From: baldrick at free.fr (Duncan Sands) Date: Mon, 06 Feb 2012 21:36:10 +0100 Subject: [llvm-commits] Please review: fix conflict between AddressSanitizer and load widening (GVN) In-Reply-To: References: Message-ID: <4F3039BA.3080905@free.fr> Hi Kostya, + if (LI->getParent()->getParent()->hasFnAttr(Attribute::AddressSafety) && + LIOffs+NewLoadByteSize > MemLocEnd) { How about switching the order of the conditions so that the cheap test (LIOffs+NewLoadByteSize > MemLocEnd) is done first. That way the more expensive test is only done if the cheap test passes, but not if it fails. + // We will be reading past the location accessed by the original program. + // While this is safe in a regular build, Address Safety analysys tools + // may start reporting false warnings. So, do't do widening. do't -> don't Ciao, Duncan. From clattner at apple.com Mon Feb 6 14:39:32 2012 From: clattner at apple.com (Chris Lattner) Date: Mon, 06 Feb 2012 12:39:32 -0800 Subject: [llvm-commits] [llvm] r149876 - /llvm/trunk/docs/LangRef.html In-Reply-To: References: <20120206175835.9B0BE2A6C12C@llvm.org> Message-ID: <28E4815F-619B-473A-9371-928EA61B6653@apple.com> On Feb 6, 2012, at 12:35 PM, Chris Lattner wrote: > > On Feb 6, 2012, at 9:58 AM, Bill Wendling wrote: > >> Author: void >> Date: Mon Feb 6 11:58:34 2012 >> New Revision: 149876 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=149876&view=rev >> Log: >> Mention that the 'unwind' instruction is now deprecated. > > Hi Bill, > > We generally don't do this. Just remove it when it's gone. I'm not asking you to revert this, just sayin' :) -Chris From chandlerc at gmail.com Mon Feb 6 14:46:34 2012 From: chandlerc at gmail.com (Chandler Carruth) Date: Mon, 06 Feb 2012 20:46:34 -0000 Subject: [llvm-commits] [llvm] r149895 - in /llvm/trunk: include/llvm/ADT/Triple.h lib/Support/Triple.cpp unittests/ADT/TripleTest.cpp Message-ID: <20120206204634.7B04C2A6C12C@llvm.org> Author: chandlerc Date: Mon Feb 6 14:46:33 2012 New Revision: 149895 URL: http://llvm.org/viewvc/llvm-project?rev=149895&view=rev Log: Introduce helpers to compute the 32-bit varaints and 64-bit variants of some architectures. These are useful for interacting with multiarch or bi-arch GCC (or GCC-based) toolchains. Modified: llvm/trunk/include/llvm/ADT/Triple.h llvm/trunk/lib/Support/Triple.cpp llvm/trunk/unittests/ADT/TripleTest.cpp Modified: llvm/trunk/include/llvm/ADT/Triple.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/Triple.h?rev=149895&r1=149894&r2=149895&view=diff ============================================================================== --- llvm/trunk/include/llvm/ADT/Triple.h (original) +++ llvm/trunk/include/llvm/ADT/Triple.h Mon Feb 6 14:46:33 2012 @@ -385,6 +385,26 @@ const char *getArchNameForAssembler(); /// @} + /// @name Helpers to build variants of a particular triple. + /// @{ + + /// \brief Form a triple with a 32-bit variant of the current architecture. + /// + /// This can be used to move across "families" of architectures where useful. + /// + /// \returns A new triple with a 32-bit architecture or an unknown + /// architecture if no such variant can be found. + llvm::Triple get32BitArchVariant() const; + + /// \brief Form a triple with a 64-bit variant of the current architecture. + /// + /// This can be used to move across "families" of architectures where useful. + /// + /// \returns A new triple with a 64-bit architecture or an unknown + /// architecture if no such variant can be found. + llvm::Triple get64BitArchVariant() const; + + /// @} /// @name Static helpers for IDs. /// @{ Modified: llvm/trunk/lib/Support/Triple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Triple.cpp?rev=149895&r1=149894&r2=149895&view=diff ============================================================================== --- llvm/trunk/lib/Support/Triple.cpp (original) +++ llvm/trunk/lib/Support/Triple.cpp Mon Feb 6 14:46:33 2012 @@ -753,3 +753,77 @@ bool Triple::isArch16Bit() const { return getArchPointerBitWidth(getArch()) == 16; } + +Triple Triple::get32BitArchVariant() const { + Triple T(*this); + switch (getArch()) { + case Triple::UnknownArch: + case Triple::InvalidArch: + case Triple::msp430: + T.setArch(UnknownArch); + break; + + case Triple::amdil: + case Triple::arm: + case Triple::cellspu: + case Triple::hexagon: + case Triple::le32: + case Triple::mblaze: + case Triple::mips: + case Triple::mipsel: + case Triple::ppc: + case Triple::ptx32: + case Triple::sparc: + case Triple::tce: + case Triple::thumb: + case Triple::x86: + case Triple::xcore: + // Already 32-bit. + break; + + case Triple::mips64: T.setArch(Triple::mips); break; + case Triple::mips64el: T.setArch(Triple::mipsel); break; + case Triple::ppc64: T.setArch(Triple::ppc); break; + case Triple::ptx64: T.setArch(Triple::ptx32); break; + case Triple::sparcv9: T.setArch(Triple::sparc); break; + case Triple::x86_64: T.setArch(Triple::x86); break; + } + return T; +} + +Triple Triple::get64BitArchVariant() const { + Triple T(*this); + switch (getArch()) { + case Triple::InvalidArch: + case Triple::UnknownArch: + case Triple::amdil: + case Triple::arm: + case Triple::cellspu: + case Triple::hexagon: + case Triple::le32: + case Triple::mblaze: + case Triple::msp430: + case Triple::tce: + case Triple::thumb: + case Triple::xcore: + T.setArch(UnknownArch); + break; + + case Triple::mips64: + case Triple::mips64el: + case Triple::ppc64: + case Triple::ptx64: + case Triple::sparcv9: + case Triple::x86_64: + // Already 64-bit. + break; + + case Triple::mips: T.setArch(Triple::mips64); break; + case Triple::mipsel: T.setArch(Triple::mips64el); break; + case Triple::ppc: T.setArch(Triple::ppc64); break; + case Triple::ptx32: T.setArch(Triple::ptx64); break; + case Triple::sparc: T.setArch(Triple::sparcv9); break; + case Triple::x86: T.setArch(Triple::x86_64); break; + } + return T; +} Modified: llvm/trunk/unittests/ADT/TripleTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/TripleTest.cpp?rev=149895&r1=149894&r2=149895&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/TripleTest.cpp (original) +++ llvm/trunk/unittests/ADT/TripleTest.cpp Mon Feb 6 14:46:33 2012 @@ -324,4 +324,66 @@ EXPECT_TRUE(T.isArch64Bit()); } +TEST(TripleTest, BitWidthArchVariants) { + Triple T; + EXPECT_EQ(Triple::UnknownArch, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::UnknownArch); + EXPECT_EQ(Triple::UnknownArch, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::arm); + EXPECT_EQ(Triple::arm, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::UnknownArch, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::mips); + EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::mipsel); + EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::ppc); + EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::ptx32); + EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::sparc); + EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::sparcv9, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::x86); + EXPECT_EQ(Triple::x86, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::mips64); + EXPECT_EQ(Triple::mips, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::mips64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::mips64el); + EXPECT_EQ(Triple::mipsel, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::mips64el, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::ppc64); + EXPECT_EQ(Triple::ppc, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::ppc64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::ptx64); + EXPECT_EQ(Triple::ptx32, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::ptx64, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::sparcv9); + EXPECT_EQ(Triple::sparc, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::sparcv9, T.get64BitArchVariant().getArch()); + + T.setArch(Triple::x86_64); + EXPECT_EQ(Triple::x86, T.get32BitArchVariant().getArch()); + EXPECT_EQ(Triple::x86_64, T.get64BitArchVariant().getArch()); +} + } From isanbard at gmail.com Mon Feb 6 14:52:41 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 6 Feb 2012 12:52:41 -0800 Subject: [llvm-commits] [llvm] r149876 - /llvm/trunk/docs/LangRef.html In-Reply-To: <28E4815F-619B-473A-9371-928EA61B6653@apple.com> References: <20120206175835.9B0BE2A6C12C@llvm.org> <28E4815F-619B-473A-9371-928EA61B6653@apple.com> Message-ID: <3FF16ADB-95F1-4C42-B3FA-8C3EBB67D4E3@gmail.com> On Feb 6, 2012, at 12:39 PM, Chris Lattner wrote: > On Feb 6, 2012, at 12:35 PM, Chris Lattner wrote: > >> On Feb 6, 2012, at 9:58 AM, Bill Wendling wrote: >> >>> Author: void >>> Date: Mon Feb 6 11:58:34 2012 >>> New Revision: 149876 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=149876&view=rev >>> Log: >>> Mention that the 'unwind' instruction is now deprecated. >> >> Hi Bill, >> >> We generally don't do this. Just remove it when it's gone. > > I'm not asking you to revert this, just sayin' :) > Sounds good. :-) I just wanted to give people a bit of a head's up. But to be honest, I don't think anyone is using it anymore. -bw From isanbard at gmail.com Mon Feb 6 14:50:27 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 20:50:27 -0000 Subject: [llvm-commits] [llvm] r149897 - in /llvm/trunk/lib: AsmParser/LLParser.cpp Bitcode/Reader/BitcodeReader.cpp Message-ID: <20120206205027.571CF2A6C12C@llvm.org> Author: void Date: Mon Feb 6 14:50:27 2012 New Revision: 149897 URL: http://llvm.org/viewvc/llvm-project?rev=149897&view=rev Log: [unwind removal] Remove the 'unwind' instruction parsing bits. Modified: llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=149897&r1=149896&r2=149897&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Feb 6 14:50:27 2012 @@ -2883,7 +2883,6 @@ switch (Token) { default: return Error(Loc, "expected instruction opcode"); // Terminator Instructions. - case lltok::kw_unwind: Inst = new UnwindInst(Context); return false; case lltok::kw_unreachable: Inst = new UnreachableInst(Context); return false; case lltok::kw_ret: return ParseRet(Inst, BB, PFS); case lltok::kw_br: return ParseBr(Inst, PFS); Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149897&r1=149896&r2=149897&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 14:50:27 2012 @@ -2384,10 +2384,6 @@ InstructionList.push_back(I); break; } - case bitc::FUNC_CODE_INST_UNWIND: // UNWIND - I = new UnwindInst(Context); - InstructionList.push_back(I); - break; case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE I = new UnreachableInst(Context); InstructionList.push_back(I); From kcc at google.com Mon Feb 6 14:55:16 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 12:55:16 -0800 Subject: [llvm-commits] [compiler-rt] r149875 - /compiler-rt/trunk/lib/asan/asan_malloc_win.cc In-Reply-To: <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> References: <20120206175638.DDDEC2A6C12C@llvm.org> <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> Message-ID: On Mon, Feb 6, 2012 at 11:13 AM, Sebastian Redl < sebastian.redl at getdesigned.at> wrote: > > On 06.02.2012, at 18:56, Kostya Serebryany wrote: > > > Author: kcc > > Date: Mon Feb 6 11:56:38 2012 > > New Revision: 149875 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=149875&view=rev > > Log: > > [asan] The first version of Windows malloc interceptors, patch by > timurrrr at google.com > > > > +// FIXME: Simply defining functions with the same signature in *.obj > > +// files overrides the standard functions in *.lib > > +// This works well for simple helloworld-like tests but might need to be > > +// revisited in the future. > > Do you support mixing non-asan modules (DLLs) with asan modules? If you mean modules instrumented with asan compiler module vs non-instrumented modules -- yes. (although we had at least one bug in the past related to this case) > I can see trouble there, if a module allocates with native malloc and > another frees with asan malloc, or vice versa. > There is only one malloc in the process. Usually. If you do end up with two mallocs in the process and they are mixed as you describe -- you will be in trouble. (The question is not related to this particular change, right?) --kcc > > Sebastian > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/5a07ceb1/attachment.html From isanbard at gmail.com Mon Feb 6 15:02:44 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:02:44 -0000 Subject: [llvm-commits] [llvm] r149898 - in /llvm/trunk/lib/AsmParser: LLLexer.cpp LLToken.h Message-ID: <20120206210244.3F32B2A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:02:43 2012 New Revision: 149898 URL: http://llvm.org/viewvc/llvm-project?rev=149898&view=rev Log: 'unwind' is a keyword, not an instruction. Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp llvm/trunk/lib/AsmParser/LLToken.h Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=149898&r1=149897&r2=149898&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLLexer.cpp (original) +++ llvm/trunk/lib/AsmParser/LLLexer.cpp Mon Feb 6 15:02:43 2012 @@ -481,6 +481,7 @@ KEYWORD(tail); KEYWORD(target); KEYWORD(triple); + KEYWORD(unwind); KEYWORD(deplibs); KEYWORD(datalayout); KEYWORD(volatile); @@ -622,7 +623,6 @@ INSTKEYWORD(indirectbr, IndirectBr); INSTKEYWORD(invoke, Invoke); INSTKEYWORD(resume, Resume); - INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); INSTKEYWORD(alloca, Alloca); Modified: llvm/trunk/lib/AsmParser/LLToken.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLToken.h?rev=149898&r1=149897&r2=149898&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLToken.h (original) +++ llvm/trunk/lib/AsmParser/LLToken.h Mon Feb 6 15:02:43 2012 @@ -50,6 +50,7 @@ kw_tail, kw_target, kw_triple, + kw_unwind, kw_deplibs, kw_datalayout, kw_volatile, @@ -127,7 +128,7 @@ kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter, - kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume, + kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_resume, kw_unreachable, kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw, From timurrrr at google.com Mon Feb 6 15:08:01 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Tue, 7 Feb 2012 01:08:01 +0400 Subject: [llvm-commits] [compiler-rt] r149875 - /compiler-rt/trunk/lib/asan/asan_malloc_win.cc In-Reply-To: <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> References: <20120206175638.DDDEC2A6C12C@llvm.org> <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> Message-ID: Hi Sebastian, ASan/Win has just started growing and only works on very small tests without DLLs. We'll be researching the intercepting mechanism soon and that's what the FIXME is about. Suggestions are welcome! :) Thanks, Timur 07.02.2012 0:33 ???????????? "Sebastian Redl" ???????: > > On 06.02.2012, at 18:56, Kostya Serebryany wrote: > > > Author: kcc > > Date: Mon Feb 6 11:56:38 2012 > > New Revision: 149875 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=149875&view=rev > > Log: > > [asan] The first version of Windows malloc interceptors, patch by > timurrrr at google.com > > > > +// FIXME: Simply defining functions with the same signature in *.obj > > +// files overrides the standard functions in *.lib > > +// This works well for simple helloworld-like tests but might need to be > > +// revisited in the future. > > Do you support mixing non-asan modules (DLLs) with asan modules? I can see > trouble there, if a module allocates with native malloc and another frees > with asan malloc, or vice versa. > > Sebastian > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/c4cb5629/attachment.html From timurrrr at google.com Mon Feb 6 15:08:23 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Tue, 7 Feb 2012 01:08:23 +0400 Subject: [llvm-commits] [compiler-rt] r149875 - /compiler-rt/trunk/lib/asan/asan_malloc_win.cc In-Reply-To: References: <20120206175638.DDDEC2A6C12C@llvm.org> <283178BE-2DE2-45FA-947F-D5D04AE8F042@getdesigned.at> Message-ID: And test cases in C too! 07.02.2012 1:08 ???????????? "Timur Iskhodzhanov" ???????: > Hi Sebastian, > > ASan/Win has just started growing and only works on very small tests > without DLLs. > We'll be researching the intercepting mechanism soon and that's what the > FIXME is about. > Suggestions are welcome! :) > > Thanks, > Timur > 07.02.2012 0:33 ???????????? "Sebastian Redl" < > sebastian.redl at getdesigned.at> ???????: > >> >> On 06.02.2012, at 18:56, Kostya Serebryany wrote: >> >> > Author: kcc >> > Date: Mon Feb 6 11:56:38 2012 >> > New Revision: 149875 >> > >> > URL: http://llvm.org/viewvc/llvm-project?rev=149875&view=rev >> > Log: >> > [asan] The first version of Windows malloc interceptors, patch by >> timurrrr at google.com >> > >> > +// FIXME: Simply defining functions with the same signature in *.obj >> > +// files overrides the standard functions in *.lib >> > +// This works well for simple helloworld-like tests but might need to >> be >> > +// revisited in the future. >> >> Do you support mixing non-asan modules (DLLs) with asan modules? I can >> see trouble there, if a module allocates with native malloc and another >> frees with asan malloc, or vice versa. >> >> Sebastian >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/98fcefa7/attachment.html From kcc at google.com Mon Feb 6 15:18:57 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 13:18:57 -0800 Subject: [llvm-commits] Please review: fix conflict between AddressSanitizer and load widening (GVN) In-Reply-To: <4F3039BA.3080905@free.fr> References: <4F3039BA.3080905@free.fr> Message-ID: Fixed both. --kcc On Mon, Feb 6, 2012 at 12:36 PM, Duncan Sands wrote: > Hi Kostya, > > + if (LI->getParent()->getParent()->hasFnAttr(Attribute::AddressSafety) > && > + LIOffs+NewLoadByteSize > MemLocEnd) { > > How about switching the order of the conditions so that the cheap test > (LIOffs+NewLoadByteSize > MemLocEnd) is done first. That way the more > expensive test is only done if the cheap test passes, but not if it fails. > > + // We will be reading past the location accessed by the original > program. > + // While this is safe in a regular build, Address Safety analysys > tools > + // may start reporting false warnings. So, do't do widening. > > do't -> don't > > Ciao, Duncan. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/cb85d366/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: issue5630068_2001.diff Type: text/x-patch Size: 2854 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/cb85d366/attachment.bin From isanbard at gmail.com Mon Feb 6 15:16:41 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:16:41 -0000 Subject: [llvm-commits] [llvm] r149901 - in /llvm/trunk/lib: Analysis/PathNumbering.cpp CodeGen/ShadowStackGC.cpp ExecutionEngine/Interpreter/Execution.cpp ExecutionEngine/Interpreter/Interpreter.h Target/CBackend/CBackend.cpp Target/CppBackend/CPPBackend.cpp Transforms/IPO/PruneEH.cpp Transforms/InstCombine/InstCombineCalls.cpp Transforms/Utils/LowerInvoke.cpp Transforms/Utils/SimplifyCFG.cpp Transforms/Utils/UnifyFunctionExitNodes.cpp Message-ID: <20120206211642.0C5132A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:16:41 2012 New Revision: 149901 URL: http://llvm.org/viewvc/llvm-project?rev=149901&view=rev Log: [unwind removal] We no longer have 'unwind' instructions being generated, so remove the code that handles them. Modified: llvm/trunk/lib/Analysis/PathNumbering.cpp llvm/trunk/lib/CodeGen/ShadowStackGC.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h llvm/trunk/lib/Target/CBackend/CBackend.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Transforms/IPO/PruneEH.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Modified: llvm/trunk/lib/Analysis/PathNumbering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/PathNumbering.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/PathNumbering.cpp (original) +++ llvm/trunk/lib/Analysis/PathNumbering.cpp Mon Feb 6 15:16:41 2012 @@ -386,8 +386,8 @@ } TerminatorInst* terminator = currentNode->getBlock()->getTerminator(); - if(isa(terminator) || isa(terminator) - || isa(terminator) || isa(terminator)) + if(isa(terminator) || isa(terminator) || + isa(terminator)) addEdge(currentNode, getExit(),0); currentNode->setColor(BallLarusNode::GRAY); Modified: llvm/trunk/lib/CodeGen/ShadowStackGC.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShadowStackGC.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ShadowStackGC.cpp (original) +++ llvm/trunk/lib/CodeGen/ShadowStackGC.cpp Mon Feb 6 15:16:41 2012 @@ -116,8 +116,7 @@ // Branches and invokes do not escape, only unwind, resume, and return // do. TerminatorInst *TI = CurBB->getTerminator(); - if (!isa(TI) && !isa(TI) && - !isa(TI)) + if (!isa(TI) && !isa(TI)) continue; Builder.SetInsertPoint(TI->getParent(), TI); Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Execution.cpp Mon Feb 6 15:16:41 2012 @@ -625,24 +625,6 @@ popStackAndReturnValueToCaller(RetTy, Result); } -void Interpreter::visitUnwindInst(UnwindInst &I) { - // Unwind stack - Instruction *Inst; - do { - ECStack.pop_back(); - if (ECStack.empty()) - report_fatal_error("Empty stack during unwind!"); - Inst = ECStack.back().Caller.getInstruction(); - } while (!(Inst && isa(Inst))); - - // Return from invoke - ExecutionContext &InvokingSF = ECStack.back(); - InvokingSF.Caller = CallSite(); - - // Go to exceptional destination BB of invoke instruction - SwitchToNewBasicBlock(cast(Inst)->getUnwindDest(), InvokingSF); -} - void Interpreter::visitUnreachableInst(UnreachableInst &I) { report_fatal_error("Program executed an 'unreachable' instruction!"); } Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h (original) +++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h Mon Feb 6 15:16:41 2012 @@ -171,7 +171,6 @@ void visitCallSite(CallSite CS); void visitCallInst(CallInst &I) { visitCallSite (CallSite (&I)); } void visitInvokeInst(InvokeInst &I) { visitCallSite (CallSite (&I)); } - void visitUnwindInst(UnwindInst &I); void visitUnreachableInst(UnreachableInst &I); void visitShl(BinaryOperator &I); Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original) +++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Mon Feb 6 15:16:41 2012 @@ -290,9 +290,6 @@ void visitInvokeInst(InvokeInst &I) { llvm_unreachable("Lowerinvoke pass didn't work!"); } - void visitUnwindInst(UnwindInst &I) { - llvm_unreachable("Lowerinvoke pass didn't work!"); - } void visitResumeInst(ResumeInst &I) { llvm_unreachable("DwarfEHPrepare pass didn't work!"); } Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Feb 6 15:16:41 2012 @@ -1142,11 +1142,6 @@ nl(Out); break; } - case Instruction::Unwind: { - Out << "new UnwindInst(" - << bbname << ");"; - break; - } case Instruction::Unreachable: { Out << "new UnreachableInst(" << "mod->getContext(), " Modified: llvm/trunk/lib/Transforms/IPO/PruneEH.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/PruneEH.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/PruneEH.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/PruneEH.cpp Mon Feb 6 15:16:41 2012 @@ -101,8 +101,7 @@ // Check to see if this function performs an unwind or calls an // unwinding function. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { - if (CheckUnwind && (isa(BB->getTerminator()) || - isa(BB->getTerminator()))) { + if (CheckUnwind && isa(BB->getTerminator())) { // Uses unwind / resume! SCCMightUnwind = true; } else if (CheckReturn && isa(BB->getTerminator())) { Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp Mon Feb 6 15:16:41 2012 @@ -737,8 +737,7 @@ // If the stack restore is in a return, resume, or unwind block and if there // are no allocas or calls between the restore and the return, nuke the // restore. - if (!CannotRemove && (isa(TI) || isa(TI) || - isa(TI))) + if (!CannotRemove && (isa(TI) || isa(TI))) return EraseInstFromFunction(CI); break; } Modified: llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/LowerInvoke.cpp Mon Feb 6 15:16:41 2012 @@ -54,7 +54,6 @@ using namespace llvm; STATISTIC(NumInvokes, "Number of invokes replaced"); -STATISTIC(NumUnwinds, "Number of unwinds replaced"); STATISTIC(NumSpilled, "Number of registers live across unwind edges"); static cl::opt ExpensiveEHSupport("enable-correct-eh-support", @@ -193,20 +192,6 @@ BB->getInstList().erase(II); ++NumInvokes; Changed = true; - } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - // Insert a call to abort() - CallInst::Create(AbortFn, "", UI)->setTailCall(); - - // Insert a return instruction. This really should be a "barrier", as it - // is unreachable. - ReturnInst::Create(F.getContext(), - F.getReturnType()->isVoidTy() ? - 0 : Constant::getNullValue(F.getReturnType()), UI); - - // Remove the unwind instruction now. - BB->getInstList().erase(UI); - - ++NumUnwinds; Changed = true; } return Changed; } @@ -404,7 +389,6 @@ bool LowerInvoke::insertExpensiveEHSupport(Function &F) { SmallVector Returns; - SmallVector Unwinds; SmallVector Invokes; UnreachableInst* UnreachablePlaceholder = 0; @@ -415,14 +399,11 @@ Returns.push_back(RI); } else if (InvokeInst *II = dyn_cast(BB->getTerminator())) { Invokes.push_back(II); - } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - Unwinds.push_back(UI); } - if (Unwinds.empty() && Invokes.empty()) return false; + if (Invokes.empty()) return false; NumInvokes += Invokes.size(); - NumUnwinds += Unwinds.size(); // TODO: This is not an optimal way to do this. In particular, this always // inserts setjmp calls into the entries of functions with invoke instructions @@ -572,13 +553,6 @@ CallInst::Create(AbortFn, "", TermBlock->getTerminator())->setTailCall(); - - // Replace all unwinds with a branch to the unwind handler. - for (unsigned i = 0, e = Unwinds.size(); i != e; ++i) { - BranchInst::Create(UnwindHandler, Unwinds[i]); - Unwinds[i]->eraseFromParent(); - } - // Replace the inserted unreachable with a branch to the unwind handler. if (UnreachablePlaceholder) { BranchInst::Create(UnwindHandler, UnreachablePlaceholder); Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Mon Feb 6 15:16:41 2012 @@ -67,9 +67,8 @@ bool FoldValueComparisonIntoPredecessors(TerminatorInst *TI, IRBuilder<> &Builder); - bool SimplifyResume(ResumeInst *RI, IRBuilder<> &Builder); bool SimplifyReturn(ReturnInst *RI, IRBuilder<> &Builder); - bool SimplifyUnwind(UnwindInst *UI, IRBuilder<> &Builder); + bool SimplifyResume(ResumeInst *RI, IRBuilder<> &Builder); bool SimplifyUnreachable(UnreachableInst *UI); bool SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder); bool SimplifyIndirectBr(IndirectBrInst *IBI); @@ -2353,52 +2352,6 @@ return false; } -bool SimplifyCFGOpt::SimplifyUnwind(UnwindInst *UI, IRBuilder<> &Builder) { - // Check to see if the first instruction in this block is just an unwind. - // If so, replace any invoke instructions which use this as an exception - // destination with call instructions. - BasicBlock *BB = UI->getParent(); - if (!BB->getFirstNonPHIOrDbg()->isTerminator()) return false; - - bool Changed = false; - SmallVector Preds(pred_begin(BB), pred_end(BB)); - while (!Preds.empty()) { - BasicBlock *Pred = Preds.back(); - InvokeInst *II = dyn_cast(Pred->getTerminator()); - if (II && II->getUnwindDest() == BB) { - // Insert a new branch instruction before the invoke, because this - // is now a fall through. - Builder.SetInsertPoint(II); - BranchInst *BI = Builder.CreateBr(II->getNormalDest()); - Pred->getInstList().remove(II); // Take out of symbol table - - // Insert the call now. - SmallVector Args(II->op_begin(), II->op_end()-3); - Builder.SetInsertPoint(BI); - CallInst *CI = Builder.CreateCall(II->getCalledValue(), - Args, II->getName()); - CI->setCallingConv(II->getCallingConv()); - CI->setAttributes(II->getAttributes()); - // If the invoke produced a value, the Call now does instead. - II->replaceAllUsesWith(CI); - delete II; - Changed = true; - } - - Preds.pop_back(); - } - - // If this block is now dead (and isn't the entry block), remove it. - if (pred_begin(BB) == pred_end(BB) && - BB != &BB->getParent()->getEntryBlock()) { - // We know there are no successors, so just nuke the block. - BB->eraseFromParent(); - return true; - } - - return Changed; -} - bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) { BasicBlock *BB = UI->getParent(); @@ -3003,17 +2956,15 @@ } else { if (SimplifyCondBranch(BI, Builder)) return true; } - } else if (ResumeInst *RI = dyn_cast(BB->getTerminator())) { - if (SimplifyResume(RI, Builder)) return true; } else if (ReturnInst *RI = dyn_cast(BB->getTerminator())) { if (SimplifyReturn(RI, Builder)) return true; + } else if (ResumeInst *RI = dyn_cast(BB->getTerminator())) { + if (SimplifyResume(RI, Builder)) return true; } else if (SwitchInst *SI = dyn_cast(BB->getTerminator())) { if (SimplifySwitch(SI, Builder)) return true; } else if (UnreachableInst *UI = dyn_cast(BB->getTerminator())) { if (SimplifyUnreachable(UI)) return true; - } else if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - if (SimplifyUnwind(UI, Builder)) return true; } else if (IndirectBrInst *IBI = dyn_cast(BB->getTerminator())) { if (SimplifyIndirectBr(IBI)) return true; Modified: llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp?rev=149901&r1=149900&r2=149901&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Mon Feb 6 15:16:41 2012 @@ -50,33 +50,13 @@ // return. // std::vector ReturningBlocks; - std::vector UnwindingBlocks; std::vector UnreachableBlocks; for(Function::iterator I = F.begin(), E = F.end(); I != E; ++I) if (isa(I->getTerminator())) ReturningBlocks.push_back(I); - else if (isa(I->getTerminator())) - UnwindingBlocks.push_back(I); else if (isa(I->getTerminator())) UnreachableBlocks.push_back(I); - // Handle unwinding blocks first. - if (UnwindingBlocks.empty()) { - UnwindBlock = 0; - } else if (UnwindingBlocks.size() == 1) { - UnwindBlock = UnwindingBlocks.front(); - } else { - UnwindBlock = BasicBlock::Create(F.getContext(), "UnifiedUnwindBlock", &F); - new UnwindInst(F.getContext(), UnwindBlock); - - for (std::vector::iterator I = UnwindingBlocks.begin(), - E = UnwindingBlocks.end(); I != E; ++I) { - BasicBlock *BB = *I; - BB->getInstList().pop_back(); // Remove the unwind insn - BranchInst::Create(UnwindBlock, BB); - } - } - // Then unreachable blocks. if (UnreachableBlocks.empty()) { UnreachableBlock = 0; From isanbard at gmail.com Mon Feb 6 15:30:37 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:30:37 -0000 Subject: [llvm-commits] [llvm] r149905 - /llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Message-ID: <20120206213037.526062A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:30:37 2012 New Revision: 149905 URL: http://llvm.org/viewvc/llvm-project?rev=149905&view=rev Log: [unwind removal] Don't write out the dead 'unwind' instruction. Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149905&r1=149904&r2=149905&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 6 15:30:37 2012 @@ -1184,9 +1184,6 @@ Code = bitc::FUNC_CODE_INST_RESUME; PushValueAndType(I.getOperand(0), InstID, Vals, VE); break; - case Instruction::Unwind: - Code = bitc::FUNC_CODE_INST_UNWIND; - break; case Instruction::Unreachable: Code = bitc::FUNC_CODE_INST_UNREACHABLE; AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; From isanbard at gmail.com Mon Feb 6 15:44:22 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:44:22 -0000 Subject: [llvm-commits] [llvm] r149906 - in /llvm/trunk: include/llvm-c/Core.h include/llvm/Instruction.def include/llvm/Instructions.h include/llvm/Support/InstVisitor.h include/llvm/Transforms/Utils/Cloning.h lib/Analysis/ValueTracking.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp lib/Transforms/Utils/CloneFunction.cpp lib/Transforms/Utils/InlineFunction.cpp lib/VMCore/Instruction.cpp lib/VMCore/Instructions.cpp Message-ID: <20120206214423.0D7212A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:44:22 2012 New Revision: 149906 URL: http://llvm.org/viewvc/llvm-project?rev=149906&view=rev Log: [unwind removal] Remove all of the code for the dead 'unwind' instruction. There were no 'unwind' instructions being generated before this, so this is in effect a no-op. Modified: llvm/trunk/include/llvm-c/Core.h llvm/trunk/include/llvm/Instruction.def llvm/trunk/include/llvm/Instructions.h llvm/trunk/include/llvm/Support/InstVisitor.h llvm/trunk/include/llvm/Transforms/Utils/Cloning.h llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp llvm/trunk/lib/VMCore/Instruction.cpp llvm/trunk/lib/VMCore/Instructions.cpp Modified: llvm/trunk/include/llvm-c/Core.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm-c/Core.h?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/include/llvm-c/Core.h (original) +++ llvm/trunk/include/llvm-c/Core.h Mon Feb 6 15:44:22 2012 @@ -200,9 +200,7 @@ /* Exception Handling Operators */ LLVMResume = 58, - LLVMLandingPad = 59, - LLVMUnwind = 60 - + LLVMLandingPad = 59 } LLVMOpcode; Modified: llvm/trunk/include/llvm/Instruction.def URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instruction.def (original) +++ llvm/trunk/include/llvm/Instruction.def Mon Feb 6 15:44:22 2012 @@ -99,81 +99,80 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst) HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) HANDLE_TERM_INST ( 5, Invoke , InvokeInst) -HANDLE_TERM_INST ( 6, Unwind , UnwindInst) -HANDLE_TERM_INST ( 7, Resume , ResumeInst) -HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst) - LAST_TERM_INST ( 8) +HANDLE_TERM_INST ( 6, Resume , ResumeInst) +HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) + LAST_TERM_INST ( 7) // Standard binary operators... - FIRST_BINARY_INST( 9) -HANDLE_BINARY_INST( 9, Add , BinaryOperator) -HANDLE_BINARY_INST(10, FAdd , BinaryOperator) -HANDLE_BINARY_INST(11, Sub , BinaryOperator) -HANDLE_BINARY_INST(12, FSub , BinaryOperator) -HANDLE_BINARY_INST(13, Mul , BinaryOperator) -HANDLE_BINARY_INST(14, FMul , BinaryOperator) -HANDLE_BINARY_INST(15, UDiv , BinaryOperator) -HANDLE_BINARY_INST(16, SDiv , BinaryOperator) -HANDLE_BINARY_INST(17, FDiv , BinaryOperator) -HANDLE_BINARY_INST(18, URem , BinaryOperator) -HANDLE_BINARY_INST(19, SRem , BinaryOperator) -HANDLE_BINARY_INST(20, FRem , BinaryOperator) + FIRST_BINARY_INST( 8) +HANDLE_BINARY_INST( 8, Add , BinaryOperator) +HANDLE_BINARY_INST( 9, FAdd , BinaryOperator) +HANDLE_BINARY_INST(10, Sub , BinaryOperator) +HANDLE_BINARY_INST(11, FSub , BinaryOperator) +HANDLE_BINARY_INST(12, Mul , BinaryOperator) +HANDLE_BINARY_INST(13, FMul , BinaryOperator) +HANDLE_BINARY_INST(14, UDiv , BinaryOperator) +HANDLE_BINARY_INST(15, SDiv , BinaryOperator) +HANDLE_BINARY_INST(16, FDiv , BinaryOperator) +HANDLE_BINARY_INST(17, URem , BinaryOperator) +HANDLE_BINARY_INST(18, SRem , BinaryOperator) +HANDLE_BINARY_INST(19, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(21, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(24, And , BinaryOperator) -HANDLE_BINARY_INST(25, Or , BinaryOperator) -HANDLE_BINARY_INST(26, Xor , BinaryOperator) - LAST_BINARY_INST(26) +HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(23, And , BinaryOperator) +HANDLE_BINARY_INST(24, Or , BinaryOperator) +HANDLE_BINARY_INST(25, Xor , BinaryOperator) + LAST_BINARY_INST(25) // Memory operators... - FIRST_MEMORY_INST(27) -HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(29, Store , StoreInst ) -HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst) -HANDLE_MEMORY_INST(31, Fence , FenceInst ) -HANDLE_MEMORY_INST(32, AtomicCmpXchg , AtomicCmpXchgInst ) -HANDLE_MEMORY_INST(33, AtomicRMW , AtomicRMWInst ) - LAST_MEMORY_INST(33) + FIRST_MEMORY_INST(26) +HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(28, Store , StoreInst ) +HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(30, Fence , FenceInst ) +HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst ) +HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst ) + LAST_MEMORY_INST(32) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair // NOTE: (see Instructions.cpp) encodes a table based on this ordering. - FIRST_CAST_INST(34) -HANDLE_CAST_INST(34, Trunc , TruncInst ) // Truncate integers -HANDLE_CAST_INST(35, ZExt , ZExtInst ) // Zero extend integers -HANDLE_CAST_INST(36, SExt , SExtInst ) // Sign extend integers -HANDLE_CAST_INST(37, FPToUI , FPToUIInst ) // floating point -> UInt -HANDLE_CAST_INST(38, FPToSI , FPToSIInst ) // floating point -> SInt -HANDLE_CAST_INST(39, UIToFP , UIToFPInst ) // UInt -> floating point -HANDLE_CAST_INST(40, SIToFP , SIToFPInst ) // SInt -> floating point -HANDLE_CAST_INST(41, FPTrunc , FPTruncInst ) // Truncate floating point -HANDLE_CAST_INST(42, FPExt , FPExtInst ) // Extend floating point -HANDLE_CAST_INST(43, PtrToInt, PtrToIntInst) // Pointer -> Integer -HANDLE_CAST_INST(44, IntToPtr, IntToPtrInst) // Integer -> Pointer -HANDLE_CAST_INST(45, BitCast , BitCastInst ) // Type cast - LAST_CAST_INST(45) + FIRST_CAST_INST(33) +HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers +HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers +HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers +HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt +HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt +HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point +HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point +HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point +HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point +HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer +HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer +HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast + LAST_CAST_INST(44) // Other operators... - FIRST_OTHER_INST(46) -HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction -HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr. -HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction -HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function -HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction -HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass -HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only -HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction -HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector -HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector -HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. -HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate -HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate -HANDLE_OTHER_INST(59, LandingPad, LandingPadInst) // Landing pad instruction. - LAST_OTHER_INST(59) + FIRST_OTHER_INST(45) +HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction +HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr. +HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction +HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function +HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction +HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass +HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only +HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction +HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector +HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector +HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. +HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate +HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate +HANDLE_OTHER_INST(58, LandingPad, LandingPadInst) // Landing pad instruction. + LAST_OTHER_INST(58) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST Modified: llvm/trunk/include/llvm/Instructions.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/include/llvm/Instructions.h (original) +++ llvm/trunk/include/llvm/Instructions.h Mon Feb 6 15:44:22 2012 @@ -2973,42 +2973,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InvokeInst, Value) //===----------------------------------------------------------------------===// -// UnwindInst Class -//===----------------------------------------------------------------------===// - -//===--------------------------------------------------------------------------- -/// UnwindInst - Immediately exit the current function, unwinding the stack -/// until an invoke instruction is found. -/// -class UnwindInst : public TerminatorInst { - void *operator new(size_t, unsigned); // DO NOT IMPLEMENT -protected: - virtual UnwindInst *clone_impl() const; -public: - // allocate space for exactly zero operands - void *operator new(size_t s) { - return User::operator new(s, 0); - } - explicit UnwindInst(LLVMContext &C, Instruction *InsertBefore = 0); - explicit UnwindInst(LLVMContext &C, BasicBlock *InsertAtEnd); - - unsigned getNumSuccessors() const { return 0; } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UnwindInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::Unwind; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -private: - virtual BasicBlock *getSuccessorV(unsigned idx) const; - virtual unsigned getNumSuccessorsV() const; - virtual void setSuccessorV(unsigned idx, BasicBlock *B); -}; - -//===----------------------------------------------------------------------===// // ResumeInst Class //===----------------------------------------------------------------------===// Modified: llvm/trunk/include/llvm/Support/InstVisitor.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/InstVisitor.h (original) +++ llvm/trunk/include/llvm/Support/InstVisitor.h Mon Feb 6 15:44:22 2012 @@ -162,7 +162,6 @@ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);} RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} - RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} Modified: llvm/trunk/include/llvm/Transforms/Utils/Cloning.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/Cloning.h?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/include/llvm/Transforms/Utils/Cloning.h (original) +++ llvm/trunk/include/llvm/Transforms/Utils/Cloning.h Mon Feb 6 15:44:22 2012 @@ -56,21 +56,13 @@ /// call instruction. bool ContainsCalls; - /// ContainsUnwinds - This is set to true if the cloned code contains an - /// unwind instruction. - bool ContainsUnwinds; - /// ContainsDynamicAllocas - This is set to true if the cloned code contains /// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in /// the entry block or they are in the entry block but are not a constant /// size. bool ContainsDynamicAllocas; - ClonedCodeInfo() { - ContainsCalls = false; - ContainsUnwinds = false; - ContainsDynamicAllocas = false; - } + ClonedCodeInfo() : ContainsCalls(false), ContainsDynamicAllocas(false) {} }; Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Feb 6 15:44:22 2012 @@ -1869,7 +1869,6 @@ case Instruction::Br: case Instruction::IndirectBr: case Instruction::Switch: - case Instruction::Unwind: case Instruction::Unreachable: case Instruction::Fence: case Instruction::LandingPad: Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Mon Feb 6 15:44:22 2012 @@ -1839,9 +1839,6 @@ DAG.getBasicBlock(Return))); } -void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) { -} - void SelectionDAGBuilder::visitResume(const ResumeInst &RI) { llvm_unreachable("SelectionDAGBuilder shouldn't visit resume instructions!"); } Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Mon Feb 6 15:44:22 2012 @@ -72,7 +72,6 @@ class TruncInst; class UIToFPInst; class UnreachableInst; -class UnwindInst; class VAArgInst; class ZExtInst; @@ -475,7 +474,6 @@ // These all get lowered before this pass. void visitInvoke(const InvokeInst &I); void visitResume(const ResumeInst &I); - void visitUnwind(const UnwindInst &I); void visitBinary(const User &I, unsigned OpCode); void visitShift(const User &I, unsigned Opcode); Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original) +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Mon Feb 6 15:44:22 2012 @@ -74,7 +74,6 @@ STATISTIC(NumFastIselFailIndirectBr,"Fast isel fails on IndirectBr"); STATISTIC(NumFastIselFailInvoke,"Fast isel fails on Invoke"); STATISTIC(NumFastIselFailResume,"Fast isel fails on Resume"); -STATISTIC(NumFastIselFailUnwind,"Fast isel fails on Unwind"); STATISTIC(NumFastIselFailUnreachable,"Fast isel fails on Unreachable"); // Standard binary operators... @@ -895,7 +894,6 @@ case Instruction::IndirectBr: NumFastIselFailIndirectBr++; return; case Instruction::Invoke: NumFastIselFailInvoke++; return; case Instruction::Resume: NumFastIselFailResume++; return; - case Instruction::Unwind: NumFastIselFailUnwind++; return; case Instruction::Unreachable: NumFastIselFailUnreachable++; return; // Standard binary operators... Modified: llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CloneFunction.cpp Mon Feb 6 15:44:22 2012 @@ -60,7 +60,6 @@ if (CodeInfo) { CodeInfo->ContainsCalls |= hasCalls; - CodeInfo->ContainsUnwinds |= isa(BB->getTerminator()); CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas; CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas && BB != &BB->getParent()->getEntryBlock(); @@ -337,7 +336,6 @@ if (CodeInfo) { CodeInfo->ContainsCalls |= hasCalls; - CodeInfo->ContainsUnwinds |= isa(OldTI); CodeInfo->ContainsDynamicAllocas |= hasDynamicAllocas; CodeInfo->ContainsDynamicAllocas |= hasStaticAllocas && BB != &BB->getParent()->front(); Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Mon Feb 6 15:44:22 2012 @@ -214,8 +214,7 @@ } /// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls -/// in the body of the inlined function into invokes and turn unwind -/// instructions into branches to the invoke unwind dest. +/// in the body of the inlined function into invokes. /// /// II is the invoke instruction being inlined. FirstNewBlock is the first /// block of the inlined code (the last block is the end of the function), @@ -230,7 +229,7 @@ // start of the inlined code to its end, checking for stuff we need to // rewrite. If the code doesn't have calls or unwinds, we know there is // nothing to rewrite. - if (!InlinedCodeInfo.ContainsCalls && !InlinedCodeInfo.ContainsUnwinds) { + if (!InlinedCodeInfo.ContainsCalls) { // Now that everything is happy, we have one final detail. The PHI nodes in // the exception destination block still have entries due to the original // invoke instruction. Eliminate these entries (which might even delete the @@ -244,27 +243,11 @@ for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB){ if (InlinedCodeInfo.ContainsCalls) if (HandleCallsInBlockInlinedThroughInvoke(BB, Invoke)) { - // Honor a request to skip the next block. We don't need to - // consider UnwindInsts in this case either. + // Honor a request to skip the next block. ++BB; continue; } - if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - // An UnwindInst requires special handling when it gets inlined into an - // invoke site. Once this happens, we know that the unwind would cause - // a control transfer to the invoke exception destination, so we can - // transform it into a direct branch to the exception destination. - BranchInst::Create(InvokeDest, UI); - - // Delete the unwind instruction! - UI->eraseFromParent(); - - // Update any PHI nodes in the exceptional block to indicate that - // there is now a new entry in them. - Invoke.addIncomingPHIValuesFor(BB); - } - if (ResumeInst *RI = dyn_cast(BB->getTerminator())) Invoke.forwardResume(RI); } @@ -503,7 +486,6 @@ /// function by one level. bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) { Instruction *TheCall = CS.getInstruction(); - LLVMContext &Context = TheCall->getContext(); assert(TheCall->getParent() && TheCall->getParent()->getParent() && "Instruction not in function!"); @@ -708,20 +690,6 @@ for (unsigned i = 0, e = Returns.size(); i != e; ++i) { IRBuilder<>(Returns[i]).CreateCall(StackRestore, SavedPtr); } - - // Count the number of StackRestore calls we insert. - unsigned NumStackRestores = Returns.size(); - - // If we are inlining an invoke instruction, insert restores before each - // unwind. These unwinds will be rewritten into branches later. - if (InlinedFunctionInfo.ContainsUnwinds && isa(TheCall)) { - for (Function::iterator BB = FirstNewBlock, E = Caller->end(); - BB != E; ++BB) - if (UnwindInst *UI = dyn_cast(BB->getTerminator())) { - IRBuilder<>(UI).CreateCall(StackRestore, SavedPtr); - ++NumStackRestores; - } - } } // If we are inlining tail call instruction through a call site that isn't @@ -741,21 +709,8 @@ } } - // If we are inlining through a 'nounwind' call site then any inlined 'unwind' - // instructions are unreachable. - if (InlinedFunctionInfo.ContainsUnwinds && MarkNoUnwind) - for (Function::iterator BB = FirstNewBlock, E = Caller->end(); - BB != E; ++BB) { - TerminatorInst *Term = BB->getTerminator(); - if (isa(Term)) { - new UnreachableInst(Context, Term); - BB->getInstList().erase(Term); - } - } - // If we are inlining for an invoke instruction, we must make sure to rewrite - // any inlined 'unwind' instructions into branches to the invoke exception - // destination, and call instructions into invoke instructions. + // any call instructions into invoke instructions. if (InvokeInst *II = dyn_cast(TheCall)) HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo); Modified: llvm/trunk/lib/VMCore/Instruction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instruction.cpp (original) +++ llvm/trunk/lib/VMCore/Instruction.cpp Mon Feb 6 15:44:22 2012 @@ -102,7 +102,6 @@ case IndirectBr: return "indirectbr"; case Invoke: return "invoke"; case Resume: return "resume"; - case Unwind: return "unwind"; case Unreachable: return "unreachable"; // Standard binary operators... Modified: llvm/trunk/lib/VMCore/Instructions.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=149906&r1=149905&r2=149906&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Instructions.cpp (original) +++ llvm/trunk/lib/VMCore/Instructions.cpp Mon Feb 6 15:44:22 2012 @@ -631,32 +631,6 @@ } //===----------------------------------------------------------------------===// -// UnwindInst Implementation -//===----------------------------------------------------------------------===// - -UnwindInst::UnwindInst(LLVMContext &Context, Instruction *InsertBefore) - : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, - 0, 0, InsertBefore) { -} -UnwindInst::UnwindInst(LLVMContext &Context, BasicBlock *InsertAtEnd) - : TerminatorInst(Type::getVoidTy(Context), Instruction::Unwind, - 0, 0, InsertAtEnd) { -} - - -unsigned UnwindInst::getNumSuccessorsV() const { - return getNumSuccessors(); -} - -void UnwindInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - llvm_unreachable("UnwindInst has no successors!"); -} - -BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const { - llvm_unreachable("UnwindInst has no successors!"); -} - -//===----------------------------------------------------------------------===// // ResumeInst Implementation //===----------------------------------------------------------------------===// @@ -709,11 +683,11 @@ } void UnreachableInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) { - llvm_unreachable("UnwindInst has no successors!"); + llvm_unreachable("UnreachableInst has no successors!"); } BasicBlock *UnreachableInst::getSuccessorV(unsigned idx) const { - llvm_unreachable("UnwindInst has no successors!"); + llvm_unreachable("UnreachableInst has no successors!"); } //===----------------------------------------------------------------------===// @@ -3516,11 +3490,6 @@ return new(1) ResumeInst(*this); } -UnwindInst *UnwindInst::clone_impl() const { - LLVMContext &Context = getContext(); - return new UnwindInst(Context); -} - UnreachableInst *UnreachableInst::clone_impl() const { LLVMContext &Context = getContext(); return new UnreachableInst(Context); From stoklund at 2pi.dk Mon Feb 6 15:52:19 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 06 Feb 2012 21:52:19 -0000 Subject: [llvm-commits] [llvm] r149910 - /llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Message-ID: <20120206215219.19E622A6C12C@llvm.org> Author: stoklund Date: Mon Feb 6 15:52:18 2012 New Revision: 149910 URL: http://llvm.org/viewvc/llvm-project?rev=149910&view=rev Log: Make sure a reserved register has a live interval before merging. Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=149910&r1=149909&r2=149910&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original) +++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Mon Feb 6 15:52:18 2012 @@ -1414,8 +1414,12 @@ // Deny any overlapping intervals. This depends on all the reserved // register live ranges to look like dead defs. for (const unsigned *AS = TRI->getOverlaps(CP.getDstReg()); *AS; ++AS) { - if (!LIS->hasInterval(*AS)) + if (!LIS->hasInterval(*AS)) { + // Make sure at least DstReg itself exists before attempting a join. + if (*AS == CP.getDstReg()) + LIS->getOrCreateInterval(CP.getDstReg()); continue; + } if (RHS.overlaps(LIS->getInterval(*AS))) { DEBUG(dbgs() << "\t\tInterference: " << PrintReg(*AS, TRI) << '\n'); return false; From isanbard at gmail.com Mon Feb 6 15:55:36 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:55:36 -0000 Subject: [llvm-commits] [llvm] r149911 - in /llvm/trunk: include/llvm/Bitcode/LLVMBitCodes.h tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Message-ID: <20120206215536.2A3882A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:55:35 2012 New Revision: 149911 URL: http://llvm.org/viewvc/llvm-project?rev=149911&view=rev Log: [unwind removal] Remove a the obsolete 'unwind' enum value. Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=149911&r1=149910&r2=149911&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original) +++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Mon Feb 6 15:55:35 2012 @@ -272,7 +272,7 @@ FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#] FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, op0, op1, ...] FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...] - FUNC_CODE_INST_UNWIND = 14, // UNWIND + // 14 is unused. FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149911&r1=149910&r2=149911&view=diff ============================================================================== --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb 6 15:55:35 2012 @@ -230,7 +230,6 @@ case bitc::FUNC_CODE_INST_BR: return "INST_BR"; case bitc::FUNC_CODE_INST_SWITCH: return "INST_SWITCH"; case bitc::FUNC_CODE_INST_INVOKE: return "INST_INVOKE"; - case bitc::FUNC_CODE_INST_UNWIND: return "INST_UNWIND"; case bitc::FUNC_CODE_INST_UNREACHABLE: return "INST_UNREACHABLE"; case bitc::FUNC_CODE_INST_PHI: return "INST_PHI"; From sabre at nondot.org Mon Feb 6 15:56:39 2012 From: sabre at nondot.org (Chris Lattner) Date: Mon, 06 Feb 2012 21:56:39 -0000 Subject: [llvm-commits] [llvm] r149912 - in /llvm/trunk: include/llvm/Support/PatternMatch.h lib/Analysis/ConstantFolding.cpp lib/Analysis/ValueTracking.cpp lib/Target/TargetLoweringObjectFile.cpp lib/Target/X86/X86ISelLowering.cpp lib/Transforms/InstCombine/InstCombineCasts.cpp lib/Transforms/InstCombine/InstCombineMulDivRem.cpp lib/Transforms/InstCombine/InstructionCombining.cpp lib/VMCore/ConstantFold.cpp Message-ID: <20120206215639.944492A6C12C@llvm.org> Author: lattner Date: Mon Feb 6 15:56:39 2012 New Revision: 149912 URL: http://llvm.org/viewvc/llvm-project?rev=149912&view=rev Log: Remove some dead code and tidy things up now that vectors use ConstantDataVector instead of always using ConstantVector. Modified: llvm/trunk/include/llvm/Support/PatternMatch.h llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/ValueTracking.cpp llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp llvm/trunk/lib/VMCore/ConstantFold.cpp Modified: llvm/trunk/include/llvm/Support/PatternMatch.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/PatternMatch.h?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/PatternMatch.h (original) +++ llvm/trunk/include/llvm/Support/PatternMatch.h Mon Feb 6 15:56:39 2012 @@ -98,13 +98,6 @@ Res = &CI->getValue(); return true; } - // FIXME: Remove this. - if (ConstantVector *CV = dyn_cast(V)) - if (ConstantInt *CI = - dyn_cast_or_null(CV->getSplatValue())) { - Res = &CI->getValue(); - return true; - } if (ConstantDataVector *CV = dyn_cast(V)) if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) { @@ -151,10 +144,6 @@ bool match(ITy *V) { if (const ConstantInt *CI = dyn_cast(V)) return this->isValue(CI->getValue()); - // FIXME: Remove this. - if (const ConstantVector *CV = dyn_cast(V)) - if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) - return this->isValue(CI->getValue()); if (const ConstantDataVector *CV = dyn_cast(V)) if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) return this->isValue(CI->getValue()); @@ -176,14 +165,6 @@ return true; } - // FIXME: remove. - if (const ConstantVector *CV = dyn_cast(V)) - if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) - if (this->isValue(CI->getValue())) { - Res = &CI->getValue(); - return true; - } - if (const ConstantDataVector *CV = dyn_cast(V)) if (ConstantInt *CI = dyn_cast_or_null(CV->getSplatValue())) if (this->isValue(CI->getValue())) { @@ -632,9 +613,7 @@ } private: bool matchIfNot(Value *LHS, Value *RHS) { - return (isa(RHS) || isa(RHS) || - // FIXME: Remove CV. - isa(RHS)) && + return (isa(RHS) || isa(RHS)) && cast(RHS)->isAllOnesValue() && L.match(LHS); } Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Mon Feb 6 15:56:39 2012 @@ -54,37 +54,35 @@ // Handle a vector->integer cast. if (IntegerType *IT = dyn_cast(DestTy)) { - // FIXME: Remove ConstantVector support. - if ((!isa(C) && !isa(C)) || - // TODO: Handle big endian someday. - !TD.isLittleEndian()) + ConstantDataVector *CDV = dyn_cast(C); + if (CDV == 0) return ConstantExpr::getBitCast(C, DestTy); - unsigned NumSrcElts = C->getType()->getVectorNumElements(); + unsigned NumSrcElts = CDV->getType()->getNumElements(); + + Type *SrcEltTy = CDV->getType()->getElementType(); // If the vector is a vector of floating point, convert it to vector of int // to simplify things. - if (C->getType()->getVectorElementType()->isFloatingPointTy()) { - unsigned FPWidth = - C->getType()->getVectorElementType()->getPrimitiveSizeInBits(); + if (SrcEltTy->isFloatingPointTy()) { + unsigned FPWidth = SrcEltTy->getPrimitiveSizeInBits(); Type *SrcIVTy = VectorType::get(IntegerType::get(C->getContext(), FPWidth), NumSrcElts); // Ask VMCore to do the conversion now that #elts line up. C = ConstantExpr::getBitCast(C, SrcIVTy); + CDV = cast(C); } // Now that we know that the input value is a vector of integers, just shift // and insert them into our result. - unsigned BitShift = - TD.getTypeAllocSizeInBits(C->getType()->getVectorElementType()); + unsigned BitShift = TD.getTypeAllocSizeInBits(SrcEltTy); APInt Result(IT->getBitWidth(), 0); for (unsigned i = 0; i != NumSrcElts; ++i) { - // FIXME: Rework when we have ConstantDataVector. - ConstantInt *Elt=dyn_cast_or_null(C->getAggregateElement(i)); - if (Elt == 0) // Elt must be a constant expr or something. - return ConstantExpr::getBitCast(C, DestTy); - - Result |= Elt->getValue().zextOrSelf(IT->getBitWidth()) << i*BitShift; + Result <<= BitShift; + if (TD.isLittleEndian()) + Result |= CDV->getElementAsInteger(NumSrcElts-i-1); + else + Result |= CDV->getElementAsInteger(i); } return ConstantInt::get(IT, Result); @@ -103,7 +101,6 @@ } // If this is a bitcast from constant vector -> vector, fold it. - // FIXME: Remove ConstantVector support. if (!isa(C) && !isa(C)) return ConstantExpr::getBitCast(C, DestTy); @@ -350,7 +347,6 @@ // not reached. } - // FIXME: Remove ConstantVector if (isa(C) || isa(C) || isa(C)) { Type *EltTy = cast(C->getType())->getElementType(); Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ValueTracking.cpp (original) +++ llvm/trunk/lib/Analysis/ValueTracking.cpp Mon Feb 6 15:56:39 2012 @@ -88,19 +88,8 @@ return; } // Handle a constant vector by taking the intersection of the known bits of - // each element. - // FIXME: Remove. - if (ConstantVector *CV = dyn_cast(V)) { - KnownZero.setAllBits(); KnownOne.setAllBits(); - for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i) { - APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0); - ComputeMaskedBits(CV->getOperand(i), Mask, KnownZero2, KnownOne2, - TD, Depth); - KnownZero &= KnownZero2; - KnownOne &= KnownOne2; - } - return; - } + // each element. There is no real need to handle ConstantVector here, because + // we don't handle undef in any particularly useful way. if (ConstantDataSequential *CDS = dyn_cast(V)) { // We know that CDS must be a vector of integers. Take the intersection of // each element. Modified: llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp (original) +++ llvm/trunk/lib/Target/TargetLoweringObjectFile.cpp Mon Feb 6 15:56:39 2012 @@ -77,23 +77,6 @@ /// than ConstantDataSequential::isString because we allow 2 & 4 byte strings. static bool IsNullTerminatedString(const Constant *C) { // First check: is we have constant array terminated with zero - if (const ConstantArray *CVA = dyn_cast(C)) { - ArrayType *ATy = cast(C->getType()); - if (ATy->getNumElements() == 0) return false; - - ConstantInt *Null = - dyn_cast(CVA->getOperand(ATy->getNumElements()-1)); - if (Null == 0 || !Null->isZero()) - return false; // Not null terminated. - - // Verify that the null doesn't occur anywhere else in the string. - for (unsigned i = 0, e = ATy->getNumElements()-1; i != e; ++i) - // Reject constantexpr elements etc. - if (!isa(CVA->getOperand(i)) || - CVA->getOperand(i) == Null) - return false; - return true; - } if (const ConstantDataSequential *CDS = dyn_cast(C)) { unsigned NumElts = CDS->getNumElements(); assert(NumElts != 0 && "Can't have an empty CDS"); Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Mon Feb 6 15:56:39 2012 @@ -7527,12 +7527,8 @@ LLVMContext *Context = DAG.getContext(); // Build some magic constants. - SmallVector CV0; - CV0.push_back(ConstantInt::get(*Context, APInt(32, 0x43300000))); - CV0.push_back(ConstantInt::get(*Context, APInt(32, 0x45300000))); - CV0.push_back(ConstantInt::get(*Context, APInt(32, 0))); - CV0.push_back(ConstantInt::get(*Context, APInt(32, 0))); - Constant *C0 = ConstantVector::get(CV0); + const uint32_t CV0[] = { 0x43300000, 0x45300000, 0, 0 }; + Constant *C0 = ConstantDataVector::get(*Context, CV0); SDValue CPIdx0 = DAG.getConstantPool(C0, getPointerTy(), 16); SmallVector CV1; @@ -10249,8 +10245,8 @@ Op = DAG.getNode(X86ISD::VSHLI, dl, VT, Op.getOperand(1), DAG.getConstant(23, MVT::i32)); - ConstantInt *CI = ConstantInt::get(*Context, APInt(32, 0x3f800000U)); - Constant *C = ConstantVector::getSplat(4, CI); + const uint32_t CV[] = { 0x3f800000U, 0x3f800000U, 0x3f800000U, 0x3f800000U}; + Constant *C = ConstantDataVector::get(*Context, CV); SDValue CPIdx = DAG.getConstantPool(C, getPointerTy(), 16); SDValue Addend = DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, MachinePointerInfo::getConstantPool(), Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCasts.cpp Mon Feb 6 15:56:39 2012 @@ -1421,16 +1421,15 @@ // Now that the element types match, get the shuffle mask and RHS of the // shuffle to use, which depends on whether we're increasing or decreasing the // size of the input. - SmallVector ShuffleMask; + SmallVector ShuffleMask; Value *V2; - IntegerType *Int32Ty = Type::getInt32Ty(SrcTy->getContext()); if (SrcTy->getNumElements() > DestTy->getNumElements()) { // If we're shrinking the number of elements, just shuffle in the low // elements from the input and use undef as the second shuffle input. V2 = UndefValue::get(SrcTy); for (unsigned i = 0, e = DestTy->getNumElements(); i != e; ++i) - ShuffleMask.push_back(ConstantInt::get(Int32Ty, i)); + ShuffleMask.push_back(i); } else { // If we're increasing the number of elements, shuffle in all of the @@ -1439,14 +1438,16 @@ V2 = Constant::getNullValue(SrcTy); unsigned SrcElts = SrcTy->getNumElements(); for (unsigned i = 0, e = SrcElts; i != e; ++i) - ShuffleMask.push_back(ConstantInt::get(Int32Ty, i)); + ShuffleMask.push_back(i); // The excess elements reference the first element of the zero input. - ShuffleMask.append(DestTy->getNumElements()-SrcElts, - ConstantInt::get(Int32Ty, SrcElts)); + for (unsigned i = 0, e = DestTy->getNumElements()-SrcElts; i != e; ++i) + ShuffleMask.push_back(SrcElts); } - return new ShuffleVectorInst(InVal, V2, ConstantVector::get(ShuffleMask)); + return new ShuffleVectorInst(InVal, V2, + ConstantDataVector::get(V2->getContext(), + ShuffleMask)); } static bool isMultipleOfTypeSize(unsigned Value, Type *Ty) { Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp Mon Feb 6 15:56:39 2012 @@ -256,31 +256,18 @@ bool Changed = SimplifyAssociativeOrCommutative(I); Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1); - // Simplify mul instructions with a constant RHS... + // Simplify mul instructions with a constant RHS. if (Constant *Op1C = dyn_cast(Op1)) { if (ConstantFP *Op1F = dyn_cast(Op1C)) { // "In IEEE floating point, x*1 is not equivalent to x for nans. However, // ANSI says we can drop signals, so we can do this anyway." (from GCC) if (Op1F->isExactlyValue(1.0)) return ReplaceInstUsesWith(I, Op0); // Eliminate 'fmul double %X, 1.0' - } else if (Op1C->getType()->isVectorTy()) { - // FIXME: Remove. - if (ConstantVector *Op1V = dyn_cast(Op1C)) { - // As above, vector X*splat(1.0) -> X in all defined cases. - if (Constant *Splat = Op1V->getSplatValue()) { - if (ConstantFP *F = dyn_cast(Splat)) - if (F->isExactlyValue(1.0)) - return ReplaceInstUsesWith(I, Op0); - } - } - if (ConstantDataVector *Op1V = dyn_cast(Op1C)) { - // As above, vector X*splat(1.0) -> X in all defined cases. - if (Constant *Splat = Op1V->getSplatValue()) { - if (ConstantFP *F = dyn_cast(Splat)) - if (F->isExactlyValue(1.0)) - return ReplaceInstUsesWith(I, Op0); - } - } + } else if (ConstantDataVector *Op1V = dyn_cast(Op1C)) { + // As above, vector X*splat(1.0) -> X in all defined cases. + if (ConstantFP *F = dyn_cast_or_null(Op1V->getSplatValue())) + if (F->isExactlyValue(1.0)) + return ReplaceInstUsesWith(I, Op0); } // Try to fold constant mul into select arguments. @@ -718,7 +705,7 @@ if (hasNegative && !hasMissing) { SmallVector Elts(VWidth); for (unsigned i = 0; i != VWidth; ++i) { - Elts[i] = C->getAggregateElement(i); + Elts[i] = C->getAggregateElement(i); // Handle undef, etc. if (ConstantInt *RHS = dyn_cast(Elts[i])) { if (RHS->isNegative()) Elts[i] = cast(ConstantExpr::getNeg(RHS)); Modified: llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstructionCombining.cpp Mon Feb 6 15:56:39 2012 @@ -495,10 +495,8 @@ if (ConstantInt *C = dyn_cast(V)) return ConstantExpr::getNeg(C); - if (Constant *C = dyn_cast(V)) - // FIXME: Remove ConstantVector - if ((isa(C) || isa(C)) && - C->getType()->getVectorElementType()->isIntegerTy()) + if (ConstantDataVector *C = dyn_cast(V)) + if (C->getType()->getElementType()->isIntegerTy()) return ConstantExpr::getNeg(C); return 0; @@ -516,10 +514,8 @@ if (ConstantFP *C = dyn_cast(V)) return ConstantExpr::getFNeg(C); - if (Constant *C = dyn_cast(V)) - // FIXME: Remove ConstantVector - if ((isa(C) || isa(C)) && - C->getType()->getVectorElementType()->isFloatingPointTy()) + if (ConstantDataVector *C = dyn_cast(V)) + if (C->getType()->getElementType()->isFloatingPointTy()) return ConstantExpr::getFNeg(C); return 0; Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=149912&r1=149911&r2=149912&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/ConstantFold.cpp (original) +++ llvm/trunk/lib/VMCore/ConstantFold.cpp Mon Feb 6 15:56:39 2012 @@ -693,7 +693,6 @@ if (Cond->isNullValue()) return V2; if (Cond->isAllOnesValue()) return V1; - // FIXME: Remove ConstantVector // If the condition is a vector constant, fold the result elementwise. if (ConstantVector *CondV = dyn_cast(Cond)) { SmallVector Result; @@ -710,21 +709,6 @@ if (Result.size() == V1->getType()->getVectorNumElements()) return ConstantVector::get(Result); } - if (ConstantDataVector *CondV = dyn_cast(Cond)) { - SmallVector Result; - for (unsigned i = 0, e = V1->getType()->getVectorNumElements(); i != e;++i){ - uint64_t Cond = CondV->getElementAsInteger(i); - - Constant *Res = (Cond ? V2 : V1)->getAggregateElement(i); - if (Res == 0) break; - Result.push_back(Res); - } - - // If we were able to build the vector, return it. - if (Result.size() == V1->getType()->getVectorNumElements()) - return ConstantVector::get(Result); - } - if (isa(Cond)) { if (isa(V1)) return V1; From isanbard at gmail.com Mon Feb 6 15:57:33 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:57:33 -0000 Subject: [llvm-commits] [llvm] r149913 - /llvm/trunk/docs/LangRef.html Message-ID: <20120206215734.133722A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:57:33 2012 New Revision: 149913 URL: http://llvm.org/viewvc/llvm-project?rev=149913&view=rev Log: [unwind removal] Remove any mention of the 'unwind' instruction. What was that instruction anyway?! Modified: llvm/trunk/docs/LangRef.html Modified: llvm/trunk/docs/LangRef.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.html?rev=149913&r1=149912&r2=149913&view=diff ============================================================================== --- llvm/trunk/docs/LangRef.html (original) +++ llvm/trunk/docs/LangRef.html Mon Feb 6 15:57:33 2012 @@ -128,7 +128,6 @@

  • 'switch' Instruction
  • 'indirectbr' Instruction
  • 'invoke' Instruction
  • -
  • 'unwind' Instruction
  • 'resume' Instruction
  • 'unreachable' Instruction
  • @@ -1206,8 +1205,7 @@ It does not write through any pointer arguments (including byval arguments) and never changes any state visible to callers. This means that it cannot unwind - exceptions by calling the C++ exception throwing methods, but - could use the unwind instruction. + exceptions by calling the C++ exception throwing methods.
    readonly
    This attribute indicates that the function does not write through any @@ -1217,8 +1215,7 @@ and read state that may be set in the caller. A readonly function always returns the same value (or unwinds an exception identically) when called with the same set of arguments and global state. It cannot unwind an - exception by calling the C++ exception throwing methods, but may - use the unwind instruction.
    + exception by calling the C++ exception throwing methods.
    returns_twice
    This attribute indicates that this function can return twice. The @@ -2543,7 +2540,7 @@ control back to them.
  • Invoke instructions depend on the - ret, unwind, + ret, resume, or exception-throwing call instructions that dynamically transfer control back to them.
  • @@ -3180,7 +3177,6 @@ 'switch', 'indirectbr', 'invoke', - 'unwind', 'resume', and 'unreachable'.

    @@ -3400,9 +3396,9 @@ 'normal' label or the 'exception' label. If the callee function returns with the "ret" instruction, control flow will return to the "normal" label. If the callee (or any - indirect callees) returns with the "unwind" - instruction, control is interrupted and continued at the dynamically nearest - "exception" label.

    + indirect callees) returns via the "resume" + instruction or other exception handling mechanism, control is interrupted and + continued at the dynamically nearest "exception" label.

    The 'exception' label is a landing pad for the @@ -3444,8 +3440,9 @@

  • 'normal label': the label reached when the called function executes a 'ret' instruction.
  • -
  • 'exception label': the label reached when a callee returns with - the unwind instruction.
  • +
  • 'exception label': the label reached when a callee returns via + the resume instruction or other exception + handling mechanism.
  • The optional function attributes list. Only 'noreturn', 'nounwind', 'readonly' and @@ -3468,9 +3465,6 @@ block to the "normal" label. If the callee unwinds then no return value is available.

    -

    Note that the code generator does not yet completely support unwind, and -that the invoke/unwind semantics are likely to change in future versions.

    -
    Example:
       %retval = invoke i32 @Test(i32 15) to label %Continue
    @@ -3481,41 +3475,6 @@
     
     
  • - - -

    - 'unwind' Instruction -

    - -
    - -
    Syntax:
    -
    -  unwind
    -
    - -
    Overview:
    -

    N.B. The unwind instruction has been - deprecated and is slated for removal.

    - -

    The 'unwind' instruction unwinds the stack, continuing control flow - at the first callee in the dynamic call stack which used - an invoke instruction to perform the call. - This is primarily used to implement exception handling.

    - -
    Semantics:
    -

    The 'unwind' instruction causes execution of the current function to - immediately halt. The dynamic call stack is then searched for the - first invoke instruction on the call stack. - Once found, execution continues at the "exceptional" destination block - specified by the invoke instruction. If there is no invoke - instruction in the dynamic call chain, undefined behavior results.

    - -

    Note that the code generator does not yet completely support unwind, and -that the invoke/unwind semantics are likely to change in future versions.

    - -
    -

    @@ -4700,7 +4659,7 @@ 'alloca' instruction is commonly used to represent automatic variables that must have an address available. When the function returns (either with the ret - or unwind instructions), the memory is + or resume instructions), the memory is reclaimed. Allocating zero bytes is legal, but the result is undefined.

    Example:
    From isanbard at gmail.com Mon Feb 6 15:59:44 2012 From: isanbard at gmail.com (Bill Wendling) Date: Mon, 06 Feb 2012 21:59:44 -0000 Subject: [llvm-commits] [llvm] r149914 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <20120206215944.E84D72A6C12C@llvm.org> Author: void Date: Mon Feb 6 15:59:44 2012 New Revision: 149914 URL: http://llvm.org/viewvc/llvm-project?rev=149914&view=rev Log: Document the 'unwind' removal. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=149914&r1=149913&r2=149914&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Mon Feb 6 15:59:44 2012 @@ -285,7 +285,10 @@
    • IR support for half float
    • -
    • IR support for vectors of pointers, including vector GEPs.
    • +
    • IR support for vectors of pointers, including vector GEPs.
    • +
    • The unwind instruction is now gone. It has been replaced by + the landingpad/resume exception handling + mechanisms.
    • ....
    From dschuff at google.com Mon Feb 6 16:30:30 2012 From: dschuff at google.com (Derek Schuff) Date: Mon, 06 Feb 2012 22:30:30 -0000 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ lib/Target/X86/Disassembler/ tools/llvm-bcanalyzer/ tools/llvm-dis/ tools/llvm-mc/ tools/llvm-objdump/ Message-ID: <20120206223030.ECC142A6C12C@llvm.org> Author: dschuff Date: Mon Feb 6 16:30:29 2012 New Revision: 149918 URL: http://llvm.org/viewvc/llvm-project?rev=149918&view=rev Log: Enable streaming of bitcode This CL delays reading of function bodies from initial parse until materialization, allowing overlap of compilation with bitcode download. Added: llvm/trunk/include/llvm/Support/DataStream.h llvm/trunk/include/llvm/Support/StreamableMemoryObject.h llvm/trunk/lib/Support/DataStream.cpp llvm/trunk/lib/Support/StreamableMemoryObject.cpp Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h llvm/trunk/include/llvm/Bitcode/ReaderWriter.h llvm/trunk/include/llvm/MC/MCDisassembler.h llvm/trunk/include/llvm/Support/MemoryObject.h llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp llvm/trunk/lib/Support/CMakeLists.txt llvm/trunk/lib/Support/MemoryObject.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp llvm/trunk/tools/llvm-dis/llvm-dis.cpp llvm/trunk/tools/llvm-mc/Disassembler.cpp llvm/trunk/tools/llvm-objdump/MCFunction.cpp llvm/trunk/tools/llvm-objdump/MCFunction.h llvm/trunk/tools/llvm-objdump/llvm-objdump.h Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb 6 16:30:29 2012 @@ -15,10 +15,12 @@ #ifndef BITSTREAM_READER_H #define BITSTREAM_READER_H +#include "llvm/ADT/OwningPtr.h" #include "llvm/Bitcode/BitCodes.h" #include #include #include +#include "llvm/Support/StreamableMemoryObject.h" namespace llvm { @@ -36,9 +38,7 @@ std::vector > RecordNames; }; private: - /// FirstChar/LastChar - This remembers the first and last bytes of the - /// stream. - const unsigned char *FirstChar, *LastChar; + OwningPtr BitcodeBytes; std::vector BlockInfoRecords; @@ -47,10 +47,10 @@ /// uses this. bool IgnoreBlockInfoNames; - BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED - void operator=(const BitstreamReader&); // NOT IMPLEMENTED + BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT + void operator=(const BitstreamReader&); // DO NOT IMPLEMENT public: - BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { + BitstreamReader() : IgnoreBlockInfoNames(true) { } BitstreamReader(const unsigned char *Start, const unsigned char *End) { @@ -58,12 +58,17 @@ init(Start, End); } + BitstreamReader(StreamableMemoryObject *bytes) { + BitcodeBytes.reset(bytes); + } + void init(const unsigned char *Start, const unsigned char *End) { - FirstChar = Start; - LastChar = End; assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); + BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); } + StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } + ~BitstreamReader() { // Free the BlockInfoRecords. while (!BlockInfoRecords.empty()) { @@ -75,9 +80,6 @@ BlockInfoRecords.pop_back(); } } - - const unsigned char *getFirstChar() const { return FirstChar; } - const unsigned char *getLastChar() const { return LastChar; } /// CollectBlockInfoNames - This is called by clients that want block/record /// name information. @@ -122,7 +124,7 @@ class BitstreamCursor { friend class Deserializer; BitstreamReader *BitStream; - const unsigned char *NextChar; + size_t NextChar; /// CurWord - This is the current data we have pulled from the stream but have /// not returned to the client. @@ -156,8 +158,7 @@ } explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { - NextChar = R.getFirstChar(); - assert(NextChar && "Bitstream not initialized yet"); + NextChar = 0; CurWord = 0; BitsInCurWord = 0; CurCodeSize = 2; @@ -167,8 +168,7 @@ freeState(); BitStream = &R; - NextChar = R.getFirstChar(); - assert(NextChar && "Bitstream not initialized yet"); + NextChar = 0; CurWord = 0; BitsInCurWord = 0; CurCodeSize = 2; @@ -225,13 +225,38 @@ /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. unsigned GetAbbrevIDWidth() const { return CurCodeSize; } - bool AtEndOfStream() const { - return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; + bool isEndPos(size_t pos) { + return BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos)); + } + + bool canSkipToPos(size_t pos) const { + // pos can be skipped to if it is a valid address or one byte past the end. + return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( + static_cast(pos - 1)); + } + + unsigned char getByte(size_t pos) { + uint8_t byte = -1; + BitStream->getBitcodeBytes().readByte(pos, &byte); + return byte; + } + + uint32_t getWord(size_t pos) { + uint32_t word = -1; + BitStream->getBitcodeBytes().readBytes(pos, + sizeof(word), + reinterpret_cast(&word), + NULL); + return word; + } + + bool AtEndOfStream() { + return isEndPos(NextChar) && BitsInCurWord == 0; } /// GetCurrentBitNo - Return the bit # of the bit we are reading. uint64_t GetCurrentBitNo() const { - return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; + return NextChar*CHAR_BIT - BitsInCurWord; } BitstreamReader *getBitStreamReader() { @@ -246,12 +271,10 @@ void JumpToBit(uint64_t BitNo) { uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; uintptr_t WordBitNo = uintptr_t(BitNo) & 31; - assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- - BitStream->getFirstChar()) && - "Invalid location"); + assert(canSkipToPos(ByteNo) && "Invalid location"); // Move the cursor to the right word. - NextChar = BitStream->getFirstChar()+ByteNo; + NextChar = ByteNo; BitsInCurWord = 0; CurWord = 0; @@ -272,7 +295,7 @@ } // If we run out of data, stop at the end of the stream. - if (NextChar == BitStream->getLastChar()) { + if (isEndPos(NextChar)) { CurWord = 0; BitsInCurWord = 0; return 0; @@ -281,8 +304,7 @@ unsigned R = CurWord; // Read the next word from the stream. - CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | - (NextChar[2] << 16) | (NextChar[3] << 24); + CurWord = getWord(NextChar); NextChar += 4; // Extract NumBits-BitsInCurWord from what we just read. @@ -376,9 +398,8 @@ // Check that the block wasn't partially defined, and that the offset isn't // bogus. - const unsigned char *const SkipTo = NextChar + NumWords*4; - if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || - SkipTo < BitStream->getFirstChar()) + size_t SkipTo = NextChar + NumWords*4; + if (AtEndOfStream() || !canSkipToPos(SkipTo)) return true; NextChar = SkipTo; @@ -409,8 +430,7 @@ if (NumWordsP) *NumWordsP = NumWords; // Validate that this block is sane. - if (CurCodeSize == 0 || AtEndOfStream() || - NextChar+NumWords*4 > BitStream->getLastChar()) + if (CurCodeSize == 0 || AtEndOfStream()) return true; return false; @@ -512,24 +532,25 @@ SkipToWord(); // 32-bit alignment // Figure out where the end of this blob will be including tail padding. - const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); + size_t NewEnd = NextChar+((NumElts+3)&~3); // If this would read off the end of the bitcode file, just set the // record to empty and return. - if (NewEnd > BitStream->getLastChar()) { + if (!canSkipToPos(NewEnd)) { Vals.append(NumElts, 0); - NextChar = BitStream->getLastChar(); + NextChar = BitStream->getBitcodeBytes().getExtent(); break; } // Otherwise, read the number of bytes. If we can return a reference to // the data, do so to avoid copying it. if (BlobStart) { - *BlobStart = (const char*)NextChar; + *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer( + NextChar, NumElts); *BlobLen = NumElts; } else { for (; NumElts; ++NextChar, --NumElts) - Vals.push_back(*NextChar); + Vals.push_back(getByte(NextChar)); } // Skip over tail padding. NextChar = NewEnd; Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Feb 6 16:30:29 2012 @@ -17,35 +17,45 @@ #include namespace llvm { - class Module; - class MemoryBuffer; - class ModulePass; class BitstreamWriter; + class MemoryBuffer; + class DataStreamer; class LLVMContext; + class Module; + class ModulePass; class raw_ostream; - + /// getLazyBitcodeModule - Read the header of the specified bitcode buffer /// and prepare for lazy deserialization of function bodies. If successful, /// this takes ownership of 'buffer' and returns a non-null pointer. On /// error, this returns null, *does not* take ownership of Buffer, and fills /// in *ErrMsg with an error description if ErrMsg is non-null. Module *getLazyBitcodeModule(MemoryBuffer *Buffer, - LLVMContext& Context, + LLVMContext &Context, std::string *ErrMsg = 0); + /// getStreamedBitcodeModule - Read the header of the specified stream + /// and prepare for lazy deserialization and streaming of function bodies. + /// On error, this returns null, and fills in *ErrMsg with an error + /// description if ErrMsg is non-null. + Module *getStreamedBitcodeModule(const std::string &name, + DataStreamer *streamer, + LLVMContext &Context, + std::string *ErrMsg = 0); + /// getBitcodeTargetTriple - Read the header of the specified bitcode /// buffer and extract just the triple information. If successful, /// this returns a string and *does not* take ownership /// of 'buffer'. On error, this returns "", and fills in *ErrMsg /// if ErrMsg is non-null. std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, - LLVMContext& Context, + LLVMContext &Context, std::string *ErrMsg = 0); /// ParseBitcodeFile - Read the specified bitcode file, returning the module. /// If an error occurs, this returns null and fills in *ErrMsg if it is /// non-null. This method *never* takes ownership of Buffer. - Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, + Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context, std::string *ErrMsg = 0); /// WriteBitcodeToFile - Write the specified module to the specified @@ -60,8 +70,8 @@ /// createBitcodeWriterPass - Create and return a pass that writes the module /// to the specified ostream. ModulePass *createBitcodeWriterPass(raw_ostream &Str); - - + + /// isBitcodeWrapper - Return true if the given bytes are the magic bytes /// for an LLVM IR bitcode wrapper. /// @@ -109,21 +119,24 @@ /// uint32_t BitcodeSize; // Size of traditional bitcode file. /// ... potentially other gunk ... /// }; - /// + /// /// This function is called when we find a file with a matching magic number. /// In this case, skip down to the subsection of the file that is actually a /// BC file. - static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr, - unsigned char *&BufEnd) { + /// If 'VerifyBufferSize' is true, check that the buffer is large enough to + /// contain the whole bitcode file. + static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, + const unsigned char *&BufEnd, + bool VerifyBufferSize) { enum { KnownHeaderSize = 4*4, // Size of header we read. OffsetField = 2*4, // Offset in bytes to Offset field. SizeField = 3*4 // Offset in bytes to Size field. }; - + // Must contain the header! if (BufEnd-BufPtr < KnownHeaderSize) return true; - + unsigned Offset = ( BufPtr[OffsetField ] | (BufPtr[OffsetField+1] << 8) | (BufPtr[OffsetField+2] << 16) | @@ -132,9 +145,9 @@ (BufPtr[SizeField +1] << 8) | (BufPtr[SizeField +2] << 16) | (BufPtr[SizeField +3] << 24)); - + // Verify that Offset+Size fits in the file. - if (Offset+Size > unsigned(BufEnd-BufPtr)) + if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) return true; BufPtr += Offset; BufEnd = BufPtr+Size; Modified: llvm/trunk/include/llvm/MC/MCDisassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCDisassembler.h (original) +++ llvm/trunk/include/llvm/MC/MCDisassembler.h Mon Feb 6 16:30:29 2012 @@ -79,7 +79,7 @@ /// MCDisassembler::Fail if the instruction was invalid. virtual DecodeStatus getInstruction(MCInst& instr, uint64_t& size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const = 0; Added: llvm/trunk/include/llvm/Support/DataStream.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149918&view=auto ============================================================================== --- llvm/trunk/include/llvm/Support/DataStream.h (added) +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb 6 16:30:29 2012 @@ -0,0 +1,38 @@ +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header defines DataStreamer, which fetches bytes of data from +// a stream source. It provides support for streaming (lazy reading) of +// data, e.g. bitcode +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_SUPPORT_DATASTREAM_H_ +#define LLVM_SUPPORT_DATASTREAM_H_ + +#include + +namespace llvm { + +class DataStreamer { +public: + /// Fetch bytes [start-end) from the stream, and write them to the + /// buffer pointed to by buf. Returns the number of bytes actually written. + virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; + + virtual ~DataStreamer(); +}; + +DataStreamer *getDataFileStreamer(const std::string &Filename, + std::string *Err); + +} + +#endif // LLVM_SUPPORT_DATASTREAM_H_ Modified: llvm/trunk/include/llvm/Support/MemoryObject.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryObject.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/MemoryObject.h (original) +++ llvm/trunk/include/llvm/Support/MemoryObject.h Mon Feb 6 16:30:29 2012 @@ -34,7 +34,7 @@ /// is getBase() + getExtent() - 1). /// /// @result - The size of the region. - virtual uint64_t getExtent() const = 0; + virtual uint64_t getExtent() = 0; /// readByte - Tries to read a single byte from the region. /// @@ -42,7 +42,7 @@ /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. /// @result - 0 if successful; -1 if not. Failure may be due to a /// bounds violation or an implementation-specific error. - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; /// readBytes - Tries to read a contiguous range of bytes from the /// region, up to the end of the region. @@ -61,7 +61,7 @@ virtual int readBytes(uint64_t address, uint64_t size, uint8_t* buf, - uint64_t* copied) const; + uint64_t* copied); }; } Added: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149918&view=auto ============================================================================== --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (added) +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb 6 16:30:29 2012 @@ -0,0 +1,181 @@ +//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef STREAMABLEMEMORYOBJECT_H_ +#define STREAMABLEMEMORYOBJECT_H_ + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/MemoryObject.h" +#include "llvm/Support/DataStream.h" +#include + +namespace llvm { + +/// StreamableMemoryObject - Interface to data which might be streamed. +/// Streamability has 2 important implications/restrictions. First, the data +/// might not yet exist in memory when the request is made. This just means +/// that readByte/readBytes might have to block or do some work to get it. +/// More significantly, the exact size of the object might not be known until +/// it has all been fetched. This means that to return the right result, +/// getExtent must also wait for all the data to arrive; therefore it should +/// not be called on objects which are actually streamed (this would defeat +/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be +/// used to test addresses without knowing the exact size of the stream. +/// Finally, getPointer can be used instead of readBytes to avoid extra copying. +class StreamableMemoryObject : public MemoryObject { + public: + /// Destructor - Override as necessary. + virtual ~StreamableMemoryObject(); + + /// getBase - Returns the lowest valid address in the region. + /// + /// @result - The lowest valid address. + virtual uint64_t getBase() const = 0; + + /// getExtent - Returns the size of the region in bytes. (The region is + /// contiguous, so the highest valid address of the region + /// is getBase() + getExtent() - 1). + /// May block until all bytes in the stream have been read + /// + /// @result - The size of the region. + virtual uint64_t getExtent() = 0; + + /// readByte - Tries to read a single byte from the region. + /// May block until (address - base) bytes have been read + /// @param address - The address of the byte, in the same space as getBase(). + /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. + /// @result - 0 if successful; -1 if not. Failure may be due to a + /// bounds violation or an implementation-specific error. + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; + + /// readBytes - Tries to read a contiguous range of bytes from the + /// region, up to the end of the region. + /// May block until (address - base + size) bytes have + /// been read. Additionally, StreamableMemoryObjects will + /// not do partial reads - if size bytes cannot be read, + /// readBytes will fail. + /// + /// @param address - The address of the first byte, in the same space as + /// getBase(). + /// @param size - The maximum number of bytes to copy. + /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL + /// and large enough to hold size bytes. + /// @param copied - A pointer to a nunber that is filled in with the number + /// of bytes actually read. May be NULL. + /// @result - 0 if successful; -1 if not. Failure may be due to a + /// bounds violation or an implementation-specific error. + virtual int readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied) = 0; + + /// getPointer - Ensures that the requested data is in memory, and returns + /// A pointer to it. More efficient than using readBytes if the + /// data is already in memory. + /// May block until (address - base + size) bytes have been read + /// @param address - address of the byte, in the same space as getBase() + /// @param size - amount of data that must be available on return + /// @result - valid pointer to the requested data + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) = 0; + + /// isValidAddress - Returns true if the address is within the object + /// (i.e. between base and base + extent - 1 inclusive) + /// May block until (address - base) bytes have been read + /// @param address - address of the byte, in the same space as getBase() + /// @result - true if the address may be read with readByte() + virtual bool isValidAddress(uint64_t address) = 0; + + /// isObjectEnd - Returns true if the address is one past the end of the + /// object (i.e. if it is equal to base + extent) + /// May block until (address - base) bytes have been read + /// @param address - address of the byte, in the same space as getBase() + /// @result - true if the address is equal to base + extent + virtual bool isObjectEnd(uint64_t address) = 0; +}; + +/// StreamingMemoryObject - interface to data which is actually streamed from +/// a DataStreamer. In addition to inherited members, it has the +/// dropLeadingBytes and setKnownObjectSize methods which are not applicable +/// to non-streamed objects. +class StreamingMemoryObject : public StreamableMemoryObject { +public: + StreamingMemoryObject(DataStreamer *streamer); + virtual uint64_t getBase() const { return 0; } + virtual uint64_t getExtent(); + virtual int readByte(uint64_t address, uint8_t* ptr); + virtual int readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied); + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) { + // This could be fixed by ensuring the bytes are fetched and making a copy, + // requiring that the bitcode size be known, or otherwise ensuring that + // the memory doesn't go away/get reallocated, but it's + // not currently necessary. Users that need the pointer don't stream. + assert(0 && "getPointer in streaming memory objects not allowed"); + return NULL; + } + virtual bool isValidAddress(uint64_t address); + virtual bool isObjectEnd(uint64_t address); + + /// Drop s bytes from the front of the stream, pushing the positions of the + /// remaining bytes down by s. This is used to skip past the bitcode header, + /// since we don't know a priori if it's present, and we can't put bytes + /// back into the stream once we've read them. + bool dropLeadingBytes(size_t s); + + /// If the data object size is known in advance, many of the operations can + /// be made more efficient, so this method should be called before reading + /// starts (although it can be called anytime). + void setKnownObjectSize(size_t size); + +private: + const static uint32_t kChunkSize = 4096 * 4; + std::vector Bytes; + OwningPtr Streamer; + size_t BytesRead; // Bytes read from stream + size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) + size_t ObjectSize; // 0 if unknown, set if wrapper was seen or EOF reached + bool EOFReached; + + // Fetch enough bytes such that Pos can be read or EOF is reached + // (i.e. BytesRead > Pos). Return true if Pos can be read. + // Unlike most of the functions in BitcodeReader, returns true on success. + // Most of the requests will be small, but we fetch at kChunkSize bytes + // at a time to avoid making too many potentially expensive GetBytes calls + bool fetchToPos(size_t Pos) { + if (EOFReached) return Pos < ObjectSize; + while (Pos >= BytesRead) { + Bytes.resize(BytesRead + kChunkSize); + size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], + kChunkSize); + BytesRead += bytes; + if (bytes < kChunkSize) { + if (ObjectSize && BytesRead < Pos) + assert(0 && "Unexpected short read fetching bitcode"); + if (BytesRead <= Pos) { // reached EOF/ran out of bytes + ObjectSize = BytesRead; + EOFReached = true; + return false; + } + } + } + return true; + } + + StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT + void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT +}; + +StreamableMemoryObject *getNonStreamedMemoryObject( + const unsigned char *Start, const unsigned char *End); + +} +#endif // STREAMABLEMEMORYOBJECT_H_ Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 16:30:29 2012 @@ -22,6 +22,7 @@ #include "llvm/AutoUpgrade.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataStream.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/OperandTraits.h" @@ -1409,8 +1410,36 @@ return false; } -bool BitcodeReader::ParseModule() { - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) +bool BitcodeReader::GlobalCleanup() { + // Patch the initializers for globals and aliases up. + ResolveGlobalAndAliasInits(); + if (!GlobalInits.empty() || !AliasInits.empty()) + return Error("Malformed global initializer set"); + + // Look for intrinsic functions which need to be upgraded at some point + for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); + FI != FE; ++FI) { + Function *NewFn; + if (UpgradeIntrinsicFunction(FI, NewFn)) + UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); + } + + // Look for global variables which need to be renamed. + for (Module::global_iterator + GI = TheModule->global_begin(), GE = TheModule->global_end(); + GI != GE; ++GI) + UpgradeGlobalVariable(GI); + // Force deallocation of memory for these vectors to favor the client that + // want lazy deserialization. + std::vector >().swap(GlobalInits); + std::vector >().swap(AliasInits); + return false; +} + +bool BitcodeReader::ParseModule(bool Resume) { + if (Resume) + Stream.JumpToBit(NextUnreadBit); + else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return Error("Malformed block record"); SmallVector Record; @@ -1424,33 +1453,7 @@ if (Stream.ReadBlockEnd()) return Error("Error at end of module block"); - // Patch the initializers for globals and aliases up. - ResolveGlobalAndAliasInits(); - if (!GlobalInits.empty() || !AliasInits.empty()) - return Error("Malformed global initializer set"); - if (!FunctionsWithBodies.empty()) - return Error("Too few function bodies found"); - - // Look for intrinsic functions which need to be upgraded at some point - for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); - FI != FE; ++FI) { - Function* NewFn; - if (UpgradeIntrinsicFunction(FI, NewFn)) - UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); - } - - // Look for global variables which need to be renamed. - for (Module::global_iterator - GI = TheModule->global_begin(), GE = TheModule->global_end(); - GI != GE; ++GI) - UpgradeGlobalVariable(GI); - - // Force deallocation of memory for these vectors to favor the client that - // want lazy deserialization. - std::vector >().swap(GlobalInits); - std::vector >().swap(AliasInits); - std::vector().swap(FunctionsWithBodies); - return false; + return GlobalCleanup(); } if (Code == bitc::ENTER_SUBBLOCK) { @@ -1474,6 +1477,7 @@ case bitc::VALUE_SYMTAB_BLOCK_ID: if (ParseValueSymbolTable()) return true; + SeenValueSymbolTable = true; break; case bitc::CONSTANTS_BLOCK_ID: if (ParseConstants() || ResolveGlobalAndAliasInits()) @@ -1486,13 +1490,25 @@ case bitc::FUNCTION_BLOCK_ID: // If this is the first function body we've seen, reverse the // FunctionsWithBodies list. - if (!HasReversedFunctionsWithBodies) { + if (!SeenFirstFunctionBody) { std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); - HasReversedFunctionsWithBodies = true; + if (GlobalCleanup()) + return true; + SeenFirstFunctionBody = true; } if (RememberAndSkipFunctionBody()) return true; + // For streaming bitcode, suspend parsing when we reach the function + // bodies. Subsequent materialization calls will resume it when + // necessary. For streaming, the function bodies must be at the end of + // the bitcode. If the bitcode file is old, the symbol table will be + // at the end instead and will not have been seen yet. In this case, + // just finish the parse now. + if (LazyStreamer && SeenValueSymbolTable) { + NextUnreadBit = Stream.GetCurrentBitNo(); + return false; + } break; case bitc::USELIST_BLOCK_ID: if (ParseUseLists()) @@ -1651,8 +1667,10 @@ // If this is a function with a body, remember the prototype we are // creating now, so that we can match up the body with them later. - if (!isProto) + if (!isProto) { FunctionsWithBodies.push_back(Func); + if (LazyStreamer) DeferredFunctionInfo[Func] = 0; + } break; } // ALIAS: [alias type, aliasee val#, linkage] @@ -1691,24 +1709,7 @@ bool BitcodeReader::ParseBitcodeInto(Module *M) { TheModule = 0; - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); - - if (Buffer->getBufferSize() & 3) { - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) - return Error("Invalid bitcode signature"); - else - return Error("Bitcode stream should be a multiple of 4 bytes in length"); - } - - // If we have a wrapper header, parse it and ignore the non-bc file contents. - // The magic number is 0x0B17C0DE stored in little endian. - if (isBitcodeWrapper(BufPtr, BufEnd)) - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) - return Error("Invalid bitcode wrapper header"); - - StreamFile.init(BufPtr, BufEnd); - Stream.init(StreamFile); + if (InitStream()) return true; // Sniff for the signature. if (Stream.Read(8) != 'B' || @@ -1750,8 +1751,9 @@ if (TheModule) return Error("Multiple MODULE_BLOCKs in same stream"); TheModule = M; - if (ParseModule()) + if (ParseModule(false)) return true; + if (LazyStreamer) return false; break; default: if (Stream.SkipBlock()) @@ -1819,20 +1821,7 @@ } bool BitcodeReader::ParseTriple(std::string &Triple) { - if (Buffer->getBufferSize() & 3) - return Error("Bitcode stream should be a multiple of 4 bytes in length"); - - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); - - // If we have a wrapper header, parse it and ignore the non-bc file contents. - // The magic number is 0x0B17C0DE stored in little endian. - if (isBitcodeWrapper(BufPtr, BufEnd)) - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) - return Error("Invalid bitcode wrapper header"); - - StreamFile.init(BufPtr, BufEnd); - Stream.init(StreamFile); + if (InitStream()) return true; // Sniff for the signature. if (Stream.Read(8) != 'B' || @@ -2708,6 +2697,19 @@ return false; } +/// FindFunctionInStream - Find the function body in the bitcode stream +bool BitcodeReader::FindFunctionInStream(Function *F, + DenseMap::iterator DeferredFunctionInfoIterator) { + while (DeferredFunctionInfoIterator->second == 0) { + if (Stream.AtEndOfStream()) + return Error("Could not find Function in stream"); + // ParseModule will parse the next body in the stream and set its + // position in the DeferredFunctionInfo map. + if (ParseModule(true)) return true; + } + return false; +} + //===----------------------------------------------------------------------===// // GVMaterializer implementation //===----------------------------------------------------------------------===// @@ -2728,6 +2730,10 @@ DenseMap::iterator DFII = DeferredFunctionInfo.find(F); assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); + // If its position is recorded as 0, its body is somewhere in the stream + // but we haven't seen it yet. + if (DFII->second == 0) + if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; // Move the bit stream to the saved position of the deferred function body. Stream.JumpToBit(DFII->second); @@ -2805,6 +2811,57 @@ return false; } +bool BitcodeReader::InitStream() { + if (LazyStreamer) return InitLazyStream(); + return InitStreamFromBuffer(); +} + +bool BitcodeReader::InitStreamFromBuffer() { + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); + + if (Buffer->getBufferSize() & 3) { + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) + return Error("Invalid bitcode signature"); + else + return Error("Bitcode stream should be a multiple of 4 bytes in length"); + } + + // If we have a wrapper header, parse it and ignore the non-bc file contents. + // The magic number is 0x0B17C0DE stored in little endian. + if (isBitcodeWrapper(BufPtr, BufEnd)) + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) + return Error("Invalid bitcode wrapper header"); + + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); + Stream.init(*StreamFile); + + return false; +} + +bool BitcodeReader::InitLazyStream() { + // Check and strip off the bitcode wrapper; BitstreamReader expects never to + // see it. + StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); + StreamFile.reset(new BitstreamReader(Bytes)); + Stream.init(*StreamFile); + + unsigned char buf[16]; + if (Bytes->readBytes(0, 16, buf, NULL) == -1) + return Error("Bitcode stream must be at least 16 bytes in length"); + + if (!isBitcode(buf, buf + 16)) + return Error("Invalid bitcode signature"); + + if (isBitcodeWrapper(buf, buf + 4)) { + const unsigned char *bitcodeStart = buf; + const unsigned char *bitcodeEnd = buf + 16; + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); + Bytes->dropLeadingBytes(bitcodeStart - buf); + Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); + } + return false; +} //===----------------------------------------------------------------------===// // External interface @@ -2833,6 +2890,24 @@ return M; } + +Module *llvm::getStreamedBitcodeModule(const std::string &name, + DataStreamer *streamer, + LLVMContext &Context, + std::string *ErrMsg) { + Module *M = new Module(name, Context); + BitcodeReader *R = new BitcodeReader(streamer, Context); + M->setMaterializer(R); + if (R->ParseBitcodeInto(M)) { + if (ErrMsg) + *ErrMsg = R->getErrorString(); + delete M; // Also deletes R. + return 0; + } + R->setBufferOwned(false); // no buffer to delete + return M; +} + /// ParseBitcodeFile - Read the specified bitcode file, returning the module. /// If an error occurs, return null and fill in *ErrMsg if non-null. Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Mon Feb 6 16:30:29 2012 @@ -126,8 +126,11 @@ Module *TheModule; MemoryBuffer *Buffer; bool BufferOwned; - BitstreamReader StreamFile; + OwningPtr StreamFile; BitstreamCursor Stream; + DataStreamer *LazyStreamer; + uint64_t NextUnreadBit; + bool SeenValueSymbolTable; const char *ErrorString; @@ -161,9 +164,10 @@ // Map the bitcode's custom MDKind ID to the Module's MDKind ID. DenseMap MDKindMap; - // After the module header has been read, the FunctionsWithBodies list is - // reversed. This keeps track of whether we've done this yet. - bool HasReversedFunctionsWithBodies; + // Several operations happen after the module header has been read, but + // before function bodies are processed. This keeps track of whether + // we've done this yet. + bool SeenFirstFunctionBody; /// DeferredFunctionInfo - When function bodies are initially scanned, this /// map contains info about where to find deferred function body in the @@ -178,8 +182,13 @@ public: explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), - ErrorString(0), ValueList(C), MDValueList(C) { - HasReversedFunctionsWithBodies = false; + LazyStreamer(0), SeenValueSymbolTable(false), ErrorString(0), + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { + } + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) + : Context(C), TheModule(0), Buffer(0), BufferOwned(false), + LazyStreamer(streamer), SeenValueSymbolTable(false), ErrorString(0), + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { } ~BitcodeReader() { FreeState(); @@ -258,7 +267,7 @@ } - bool ParseModule(); + bool ParseModule(bool Resume); bool ParseAttributeBlock(); bool ParseTypeTable(); bool ParseTypeTableBody(); @@ -267,11 +276,17 @@ bool ParseConstants(); bool RememberAndSkipFunctionBody(); bool ParseFunctionBody(Function *F); + bool GlobalCleanup(); bool ResolveGlobalAndAliasInits(); bool ParseMetadata(); bool ParseMetadataAttachment(); bool ParseModuleTriple(std::string &Triple); bool ParseUseLists(); + bool InitStream(); + bool InitStreamFromBuffer(); + bool InitLazyStream(); + bool FindFunctionInStream(Function *F, + DenseMap::iterator DeferredFunctionInfoIterator); }; } // End llvm namespace Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 6 16:30:29 2012 @@ -1738,11 +1738,6 @@ // Emit metadata. WriteModuleMetadata(M, VE, Stream); - // Emit function bodies. - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) - if (!F->isDeclaration()) - WriteFunction(*F, VE, Stream); - // Emit metadata. WriteModuleMetadataStore(M, Stream); @@ -1753,6 +1748,11 @@ if (EnablePreserveUseListOrdering) WriteModuleUseLists(M, VE, Stream); + // Emit function bodies. + for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) + if (!F->isDeclaration()) + WriteFunction(*F, VE, Stream); + Stream.ExitBlock(); } Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Feb 6 16:30:29 2012 @@ -100,9 +100,9 @@ Bytes(bytes), Size(size), BasePC(basePC) {} uint64_t getBase() const { return BasePC; } - uint64_t getExtent() const { return Size; } + uint64_t getExtent() { return Size; } - int readByte(uint64_t Addr, uint8_t *Byte) const { + int readByte(uint64_t Addr, uint8_t *Byte) { if (Addr - BasePC >= Size) return -1; *Byte = Bytes[Addr - BasePC]; Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Mon Feb 6 16:30:29 2012 @@ -207,8 +207,8 @@ void *arg) : Callback(callback), Arg(arg) { } ~EDMemoryObject() { } uint64_t getBase() const { return 0x0; } - uint64_t getExtent() const { return (uint64_t)-1; } - int readByte(uint64_t address, uint8_t *ptr) const { + uint64_t getExtent() { return (uint64_t)-1; } + int readByte(uint64_t address, uint8_t *ptr) { if (!Callback) return -1; Modified: llvm/trunk/lib/Support/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Support/CMakeLists.txt (original) +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Feb 6 16:30:29 2012 @@ -16,6 +16,7 @@ ConstantRange.cpp CrashRecoveryContext.cpp DataExtractor.cpp + DataStream.cpp Debug.cpp DeltaAlgorithm.cpp DAGDeltaAlgorithm.cpp @@ -42,6 +43,7 @@ SmallVector.cpp SourceMgr.cpp Statistic.cpp + StreamableMemoryObject.cpp StringExtras.cpp StringMap.cpp StringPool.cpp Added: llvm/trunk/lib/Support/DataStream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149918&view=auto ============================================================================== --- llvm/trunk/lib/Support/DataStream.cpp (added) +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 16:30:29 2012 @@ -0,0 +1,96 @@ +//===--- llvm/Support/DataStream.cpp - Lazy streamed Data ---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements DataStreamer, which fetches bytes of Data from +// a stream source. It provides support for streaming (lazy reading) of +// bitcode. An example implementation of streaming from a file or stdin +// is included. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "Data-stream" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/DataStream.h" +#include "llvm/Support/system_error.h" +#include +#include +#include +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include +#else +#include +#endif +#include +using namespace llvm; + +// Interface goals: +// * StreamableMemoryObject doesn't care about complexities like using +// threads/async callbacks to actually overlap download+compile +// * Don't want to duplicate Data in memory +// * Don't need to know total Data len in advance +// Non-goals: +// StreamableMemoryObject already has random access so this interface only does +// in-order streaming (no arbitrary seeking, else we'd have to buffer all the +// Data here in addition to MemoryObject). This also means that if we want +// to be able to to free Data, BitstreamBytes/BitcodeReader will implement it + +STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); + +namespace llvm { +DataStreamer::~DataStreamer() {} +} + +namespace { + +const static error_code success; + +// Very simple stream backed by a file. Mostly useful for stdin and debugging; +// actual file access is probably still best done with mmap. +class DataFileStreamer : public DataStreamer { + int Fd; +public: + DataFileStreamer() : Fd(0) {} + virtual ~DataFileStreamer() { + close(Fd); + } + virtual size_t GetBytes(unsigned char *buf, size_t len) { + NumStreamFetches++; + return read(Fd, buf, len); + } + + error_code OpenFile(const std::string &Filename) { + int OpenFlags = O_RDONLY; +#ifdef O_BINARY + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. +#endif + if (Filename == "-") + Fd = 0; + else + Fd = ::open(Filename.c_str(), OpenFlags); + if (Fd == -1) return error_code(errno, posix_category()); + return success; + } +}; + +} + +namespace llvm { +DataStreamer *getDataFileStreamer(const std::string &Filename, + std::string *StrError) { + DataFileStreamer *s = new DataFileStreamer(); + error_code e = s->OpenFile(Filename); + if (e != success) { + *StrError = std::string("Could not open ") + Filename + ": " + + e.message() + "\n"; + return NULL; + } + return s; +} + +} Modified: llvm/trunk/lib/Support/MemoryObject.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryObject.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryObject.cpp (original) +++ llvm/trunk/lib/Support/MemoryObject.cpp Mon Feb 6 16:30:29 2012 @@ -16,7 +16,7 @@ int MemoryObject::readBytes(uint64_t address, uint64_t size, uint8_t* buf, - uint64_t* copied) const { + uint64_t* copied) { uint64_t current = address; uint64_t limit = getBase() + getExtent(); Added: llvm/trunk/lib/Support/StreamableMemoryObject.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149918&view=auto ============================================================================== --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (added) +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb 6 16:30:29 2012 @@ -0,0 +1,137 @@ +//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/StreamableMemoryObject.h" +#include +#include + + +using namespace llvm; + +namespace { + +class RawMemoryObject : public StreamableMemoryObject { +public: + RawMemoryObject(const unsigned char *Start, const unsigned char *End) : + FirstChar(Start), LastChar(End) { + assert(LastChar > FirstChar && "Invalid start/end range"); + } + + virtual uint64_t getBase() const { return 0; } + virtual uint64_t getExtent() { return LastChar - FirstChar; } + virtual int readByte(uint64_t address, uint8_t* ptr); + virtual int readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied); + virtual const uint8_t *getPointer(uint64_t address, uint64_t size); + virtual bool isValidAddress(uint64_t address) {return validAddress(address);} + virtual bool isObjectEnd(uint64_t address) {return objectEnd(address);} + +private: + const uint8_t* const FirstChar; + const uint8_t* const LastChar; + + // These are implemented as inline functions here to avoid multiple virtual + // calls per public function + bool validAddress(uint64_t address) { + return static_cast(address) < LastChar - FirstChar; + } + bool objectEnd(uint64_t address) { + return static_cast(address) == LastChar - FirstChar; + } + + RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT + void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT +}; + +int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) { + if (!validAddress(address)) return -1; + *ptr = *((uint8_t *)(uintptr_t)(address + FirstChar)); + return 0; +} + +int RawMemoryObject::readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied) { + if (!validAddress(address) || !validAddress(address + size - 1)) return -1; + memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); + if (copied) *copied = size; + return size; +} + +const uint8_t *RawMemoryObject::getPointer(uint64_t address, uint64_t size) { + return FirstChar + address; +} +} // anonymous namespace + +namespace llvm { +// If the bitcode has a header, then its size is known, and we don't have to +// block until we actually want to read it. +bool StreamingMemoryObject::isValidAddress(uint64_t address) { + if (ObjectSize && address < ObjectSize) return true; + return fetchToPos(address); +} + +bool StreamingMemoryObject::isObjectEnd(uint64_t address) { + if (ObjectSize) return address == ObjectSize; + fetchToPos(address); + return address == ObjectSize && address != 0; +} + +uint64_t StreamingMemoryObject::getExtent() { + if (ObjectSize) return ObjectSize; + size_t pos = BytesRead + kChunkSize; + // keep fetching until we run out of bytes + while (fetchToPos(pos)) pos += kChunkSize; + return ObjectSize; +} + +int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) { + if (!fetchToPos(address)) return -1; + *ptr = Bytes[address + BytesSkipped]; + return 0; +} + +int StreamingMemoryObject::readBytes(uint64_t address, + uint64_t size, + uint8_t* buf, + uint64_t* copied) { + if (!fetchToPos(address + size - 1)) return -1; + memcpy(buf, &Bytes[address + BytesSkipped], size); + if (copied) *copied = size; + return 0; +} + +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { + if (BytesRead < s) return true; + BytesSkipped = s; + BytesRead -= s; + return false; +} + +void StreamingMemoryObject::setKnownObjectSize(size_t size) { + ObjectSize = size; + Bytes.reserve(size); +} + +StreamableMemoryObject *getNonStreamedMemoryObject( + const unsigned char *Start, const unsigned char *End) { + return new RawMemoryObject(Start, End); +} + +StreamableMemoryObject::~StreamableMemoryObject() { } + +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : + Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), + ObjectSize(0), EOFReached(false) { + BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); +} +} Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb 6 16:30:29 2012 @@ -46,7 +46,7 @@ /// getInstruction - See MCDisassembler. DecodeStatus getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const; @@ -71,7 +71,7 @@ /// getInstruction - See MCDisassembler. DecodeStatus getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const; @@ -341,7 +341,7 @@ } DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, - const MemoryObject &Region, + MemoryObject &Region, uint64_t Address, raw_ostream &os, raw_ostream &cs) const { @@ -691,7 +691,7 @@ } DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, - const MemoryObject &Region, + MemoryObject &Region, uint64_t Address, raw_ostream &os, raw_ostream &cs) const { Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon Feb 6 16:30:29 2012 @@ -502,7 +502,7 @@ MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const { Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h (original) +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h Mon Feb 6 16:30:29 2012 @@ -40,7 +40,7 @@ /// getInstruction - See MCDisassembler. MCDisassembler::DecodeStatus getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const; Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Feb 6 16:30:29 2012 @@ -112,7 +112,7 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const { Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Mon Feb 6 16:30:29 2012 @@ -114,7 +114,7 @@ /// getInstruction - See MCDisassembler. DecodeStatus getInstruction(MCInst &instr, uint64_t &size, - const MemoryObject ®ion, + MemoryObject ®ion, uint64_t address, raw_ostream &vStream, raw_ostream &cStream) const; Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb 6 16:30:29 2012 @@ -483,13 +483,13 @@ if (MemBuf->getBufferSize() & 3) return Error("Bitcode stream should be a multiple of 4 bytes in length"); - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); + const unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); + const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); // If we have a wrapper header, parse it and ignore the non-bc file contents. // The magic number is 0x0B17C0DE stored in little endian. if (isBitcodeWrapper(BufPtr, EndBufPtr)) - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) return Error("Invalid bitcode wrapper header"); BitstreamReader StreamFile(BufPtr, EndBufPtr); Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Feb 6 16:30:29 2012 @@ -24,6 +24,7 @@ #include "llvm/Analysis/DebugInfo.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/DataStream.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -126,12 +127,19 @@ std::string ErrorMessage; std::auto_ptr M; - { - OwningPtr BufferPtr; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) - ErrorMessage = ec.message(); + // Use the bitcode streaming interface + DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); + if (streamer) { + std::string DisplayFilename; + if (InputFilename == "-") + DisplayFilename = ""; else - M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); + DisplayFilename = InputFilename; + M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, + &ErrorMessage)); + if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { + M.reset(); + } } if (M.get() == 0) { @@ -183,4 +191,3 @@ return 0; } - Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Mon Feb 6 16:30:29 2012 @@ -42,9 +42,9 @@ VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} uint64_t getBase() const { return 0; } - uint64_t getExtent() const { return Bytes.size(); } + uint64_t getExtent() { return Bytes.size(); } - int readByte(uint64_t Addr, uint8_t *Byte) const { + int readByte(uint64_t Addr, uint8_t *Byte) { if (Addr >= getExtent()) return -1; *Byte = Bytes[Addr].first; Modified: llvm/trunk/tools/llvm-objdump/MCFunction.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.cpp?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-objdump/MCFunction.cpp (original) +++ llvm/trunk/tools/llvm-objdump/MCFunction.cpp Mon Feb 6 16:30:29 2012 @@ -28,7 +28,7 @@ MCFunction MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, - const MemoryObject &Region, uint64_t Start, + MemoryObject &Region, uint64_t Start, uint64_t End, const MCInstrAnalysis *Ana, raw_ostream &DebugOut, SmallVectorImpl &Calls) { Modified: llvm/trunk/tools/llvm-objdump/MCFunction.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-objdump/MCFunction.h (original) +++ llvm/trunk/tools/llvm-objdump/MCFunction.h Mon Feb 6 16:30:29 2012 @@ -79,7 +79,7 @@ // Create an MCFunction from a region of binary machine code. static MCFunction createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, - const MemoryObject &Region, uint64_t Start, uint64_t End, + MemoryObject &Region, uint64_t Start, uint64_t End, const MCInstrAnalysis *Ana, raw_ostream &DebugOut, SmallVectorImpl &Calls); Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=149918&r1=149917&r2=149918&view=diff ============================================================================== --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original) +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb 6 16:30:29 2012 @@ -31,9 +31,9 @@ StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} uint64_t getBase() const { return 0; } - uint64_t getExtent() const { return Bytes.size(); } + uint64_t getExtent() { return Bytes.size(); } - int readByte(uint64_t Addr, uint8_t *Byte) const { + int readByte(uint64_t Addr, uint8_t *Byte) { if (Addr >= getExtent()) return -1; *Byte = Bytes[Addr]; From nlewycky at google.com Mon Feb 6 16:35:53 2012 From: nlewycky at google.com (Nick Lewycky) Date: Mon, 6 Feb 2012 14:35:53 -0800 Subject: [llvm-commits] ThreadSanitizer, first patch. Please review. In-Reply-To: References: Message-ID: On 30 January 2012 09:45, Kostya Serebryany wrote: > Any feedback? --- test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) +++ test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) @@ -0,0 +1,17 @@ +; RUN: opt < %s -tsan -S | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @read_4_bytes(i32* %a) { +entry: + %tmp1 = load i32* %a, align 4 + ret i32 %tmp1 +} +; CHECK: @read_4_bytes +; CHECK-NOT: ret i32 +; CHECK: __tsan_func_entry +; CHECK: __tsan_read4 +; CHECK: __tsan_func_exit +; CHECK: ret i32 +; CHECK: __tsan_init I'm not a fan of this pile of CHECK statements. You could actually write out the IR that you expect to get out and preserve the order using CHECK-NEXT. Even if you don't want the matches to be too specific, it would still be clearer to see "CHECK-NEXT: call {{.*}} @__tsan_func_entry". Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp =================================================================== --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) @@ -0,0 +1,149 @@ +//===-- ThreadSanitizer.cpp - race detector ---------------------*- C++ -*-===// Hey hey, this ruler is 81 characters long. :) +bool ThreadSanitizer::runOnModule(Module &M) { + bool Res = false; + CurrentModule = &M; + TD = getAnalysisIfAvailable(); + if (!TD) + return false; + + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { + if (F->isDeclaration()) continue; + Res |= handleFunction(M, *F); + } + // We instrumented at least one function. Insert a call to __tsan_init(). + if (Res) { + IRBuilder<> IRB(M.getContext()); + Value *TsanInit = M.getOrInsertFunction("__tsan_init", + IRB.getVoidTy(), NULL); + appendToGlobalCtors(M, cast(TsanInit), 0); + } + return Res; +} You could write this as a FunctionPass; create the __tsan_... methods in doInitialization() (and store the necessary pointers in your object so that you needn't look them up each time you instrument a function), then do the instrumentation per-function, then in doFinalization either add the call to __tsan_init or clean up declarations you created in doInitialization(). + else if (isa(BI)) + HasCalls = true; What about invokes? + // Instrument memory accesses. + for (size_t i = 0, n = LoadsAndStores.size(); i < n; ++i) { + Res |= instrumentLoadOrStore(LoadsAndStores[i]); + } Why not just call instrumentLoadOrStore as you encounter them? It seems that the vector is just overhead. Nick > --kcc > > > > On Wed, Jan 18, 2012 at 11:38 AM, Kostya Serebryany wrote: > >> Hello, >> >> The proposed patch is the first step towards race detection built into >> LLVM/Clang. >> The tool will be similar to AddressSanitizer in the way it works: >> 1. A simple instrumentation module >> in lib/Transforms/Instrumentation/ThreadSanitizer.cpp (this patch) >> 2. -fthread-sanitizer flag in clang (next patch) >> 3. A run-time library in projects/compiler-rt/lib/tsan (patches will >> follow). >> >> The patch: http://codereview.appspot.com/5545054/ (also attached). >> >> Here are some links about the previous versions of ThreadSanitizer >> - http://code.google.com/p/data-race-test/ -- main project page >> - http://code.google.com/p/data-race-test/wiki/CompileTimeInstrumentation - description >> of the LLVM-based prototype (we are not going to reuse that code, but will >> reuse the ideas). >> - http://code.google.com/p/data-race-test/wiki/GccInstrumentation - >> description of the GCC-based prototype. >> - >> http://dev.chromium.org/developers/how-tos/using-valgrind/threadsanitizer - >> ThreadSanitizer for Chromium >> - http://data-race-test.googlecode.com/files/ThreadSanitizer.pdf -- >> paper about Valgrind-based tool published at WBIA'09 >> - http://data-race-test.googlecode.com/files/ThreadSanitizerLLVM.pdf -- >> paper about LLVM-based tool published at RV'2011 >> >> Thanks, >> >> --kcc >> > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/f0774ebb/attachment.html From nlewycky at google.com Mon Feb 6 16:37:19 2012 From: nlewycky at google.com (Nick Lewycky) Date: Mon, 6 Feb 2012 14:37:19 -0800 Subject: [llvm-commits] fix conflict between AddressSanitizer and load widening (GVN) (issue 5630068) In-Reply-To: <20cf300faf2563e8f104b8534398@google.com> References: <20cf300faf2563e8f104b8534398@google.com> Message-ID: [+llvm-commits, silly codereview.] On 6 February 2012 14:34, wrote: > Reviewers: nlewycky1, > > Message: > > On 2012/02/06 22:20:28, nlewycky1 wrote: > >> Go ahead and commit once you've resolved the comments Duncan and I >> > made. > > > http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** > MemoryDependenceAnalysis.cpp > >> File lib/Analysis/**MemoryDependenceAnalysis.cpp (right): >> > > > http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** > MemoryDependenceAnalysis.cpp#**newcode327 > >> lib/Analysis/**MemoryDependenceAnalysis.cpp:**327: >> LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety)) { >> LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety) is >> a >> loop-invariant, please hoist it into "bool MayWidenPastEnd = ...". >> > > Hm? > This is a loop invariant, but it is not computed on every iteration. > Sometimes it is never computed. > If I move it outside of the loop it is likely to be computed more often. Oops, you're right. Short-circuiting and all. :) Please commit. Nick > > > > > > http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** > MemoryDependenceAnalysis.cpp#**newcode329 > >> lib/Analysis/**MemoryDependenceAnalysis.cpp:**329: // While this is safe >> > in a > >> regular build, Address Safety analysys tools >> "analysis" >> > ok > > > > > > Please review this at http://codereview.appspot.com/**5630068/ > > Affected files: > M lib/Analysis/**MemoryDependenceAnalysis.cpp > A test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll > > > Index: test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll > ==============================**==============================**======= > --- test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll > (revision 0) > +++ test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll > (revision 0) > @@ -0,0 +1,43 @@ > +; RUN: opt < %s -basicaa -gvn -asan -S | FileCheck %s > +; ASAN conflicts with load widening iff the widened load accesses data > out of bounds > +; (while the original unwidened loads do not). > +; http://code.google.com/p/**address-sanitizer/issues/**detail?id=20#c1 > + > + > +; 32-bit little endian target. > +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-** > i16:16:16-i32:32:32-i64:32:64-**f32:32:32-f64:32:64-v64:64:64-** > v128:128:128-a0:0:64-f80:128:**128-n8:16:32" > + > +%struct_of_7_bytes_4_aligned = type { i32, i8, i8, i8} > + > + at f = global %struct_of_7_bytes_4_aligned zeroinitializer, align 4 > + > +; Accessing bytes 4 and 6, not ok to widen to i32 if address_safety is > set. > + > +define i32 @test_widening_bad(i8* %P) nounwind ssp noredzone > address_safety { > +entry: > + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* > @f, i64 0, i32 1), align 4 > + %conv = zext i8 %tmp to i32 > + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* > @f, i64 0, i32 3), align 1 > + %conv2 = zext i8 %tmp1 to i32 > + %add = add nsw i32 %conv, %conv2 > + ret i32 %add > +; CHECK: @test_widening_bad > +; CHECK: __asan_report_load1 > +; CHECK: __asan_report_load1 > +; CHECK-ret i32 > +} > + > +;; Accessing byets 4 and 5. Ok to widen to i16. > + > +define i32 @test_widening_ok(i8* %P) nounwind ssp noredzone > address_safety { > +entry: > + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* > @f, i64 0, i32 1), align 4 > + %conv = zext i8 %tmp to i32 > + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* > @f, i64 0, i32 2), align 1 > + %conv2 = zext i8 %tmp1 to i32 > + %add = add nsw i32 %conv, %conv2 > + ret i32 %add > +; CHECK: @test_widening_ok > +; CHECK: __asan_report_load1 > +; CHECK-ret i32 > +} > Index: lib/Analysis/**MemoryDependenceAnalysis.cpp > ==============================**==============================**======= > --- lib/Analysis/**MemoryDependenceAnalysis.cpp (revision 149872) > +++ lib/Analysis/**MemoryDependenceAnalysis.cpp (working copy) > @@ -323,6 +323,14 @@ > !TD.fitsInLegalInteger(**NewLoadByteSize*8)) > return 0; > > + if (LIOffs+NewLoadByteSize > MemLocEnd && > + LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety)) > { > + // We will be reading past the location accessed by the original > program. > > + // While this is safe in a regular build, Address Safety analysys > tools > + // may start reporting false warnings. So, don't do widening. > + return 0; > + } > + > // If a load of this width would include all of MemLoc, then we > succeed. > if (LIOffs+NewLoadByteSize >= MemLocEnd) > return NewLoadByteSize; > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/3f57b044/attachment-0001.html From nicholas at mxc.ca Mon Feb 6 16:36:39 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 06 Feb 2012 22:36:39 -0000 Subject: [llvm-commits] [llvm] r149919 - /llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Message-ID: <20120206223639.52E812A6C12C@llvm.org> Author: nicholas Date: Mon Feb 6 16:36:39 2012 New Revision: 149919 URL: http://llvm.org/viewvc/llvm-project?rev=149919&view=rev Log: System headers after llvm headers. Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149919&r1=149918&r2=149919&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb 6 16:36:39 2012 @@ -17,10 +17,10 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/Bitcode/BitCodes.h" +#include "llvm/Support/StreamableMemoryObject.h" #include #include #include -#include "llvm/Support/StreamableMemoryObject.h" namespace llvm { From stoklund at 2pi.dk Mon Feb 6 16:37:56 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 06 Feb 2012 22:37:56 -0000 Subject: [llvm-commits] [llvm] r149920 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Message-ID: <20120206223756.516B82A6C12C@llvm.org> Author: stoklund Date: Mon Feb 6 16:37:56 2012 New Revision: 149920 URL: http://llvm.org/viewvc/llvm-project?rev=149920&view=rev Log: Don't explicitly renumber slot indices. We have automatic local renumbering now. Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=149920&r1=149919&r2=149920&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original) +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Mon Feb 6 16:37:56 2012 @@ -394,8 +394,6 @@ LastUse->setIsKill(true); } - LI->renumber(); - Allocator.Reset(); RegNodeMap.clear(); PHISrcDefs.clear(); From stoklund at 2pi.dk Mon Feb 6 16:37:58 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 06 Feb 2012 22:37:58 -0000 Subject: [llvm-commits] [llvm] r149921 - /llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Message-ID: <20120206223758.F02602A6C12C@llvm.org> Author: stoklund Date: Mon Feb 6 16:37:58 2012 New Revision: 149921 URL: http://llvm.org/viewvc/llvm-project?rev=149921&view=rev Log: Remove some unused functions. LiveIntervalAnalysis has a number of functions that simply forward to SlotIndexes. Since SlotIndexes is a stand-alone analysis now, clients should really refer to it directly. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=149921&r1=149920&r2=149921&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Mon Feb 6 16:37:58 2012 @@ -192,21 +192,11 @@ return li.liveAt(getMBBStartIdx(mbb)); } - LiveRange* findEnteringRange(LiveInterval &li, - const MachineBasicBlock *mbb) { - return li.getLiveRangeContaining(getMBBStartIdx(mbb)); - } - bool isLiveOutOfMBB(const LiveInterval &li, const MachineBasicBlock *mbb) const { return li.liveAt(getMBBEndIdx(mbb).getPrevSlot()); } - LiveRange* findExitingRange(LiveInterval &li, - const MachineBasicBlock *mbb) { - return li.getLiveRangeContaining(getMBBEndIdx(mbb).getPrevSlot()); - } - MachineBasicBlock* getMBBFromIndex(SlotIndex index) const { return indexes_->getMBBFromIndex(index); } @@ -223,19 +213,11 @@ indexes_->replaceMachineInstrInMaps(MI, NewMI); } - void InsertMBBInMaps(MachineBasicBlock *MBB) { - indexes_->insertMBBInMaps(MBB); - } - bool findLiveInMBBs(SlotIndex Start, SlotIndex End, SmallVectorImpl &MBBs) const { return indexes_->findLiveInMBBs(Start, End, MBBs); } - void renumber() { - indexes_->renumberIndexes(); - } - VNInfo::Allocator& getVNInfoAllocator() { return VNInfoAllocator; } virtual void getAnalysisUsage(AnalysisUsage &AU) const; From nicholas at mxc.ca Mon Feb 6 16:41:47 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 06 Feb 2012 22:41:47 -0000 Subject: [llvm-commits] [llvm] r149922 - in /llvm/trunk: include/llvm/Support/DataStream.h include/llvm/Support/StreamableMemoryObject.h lib/Support/DataStream.cpp lib/Support/StreamableMemoryObject.cpp Message-ID: <20120206224147.C41302A6C12C@llvm.org> Author: nicholas Date: Mon Feb 6 16:41:47 2012 New Revision: 149922 URL: http://llvm.org/viewvc/llvm-project?rev=149922&view=rev Log: Fix comment-rulers. Modified: llvm/trunk/include/llvm/Support/DataStream.h llvm/trunk/include/llvm/Support/StreamableMemoryObject.h llvm/trunk/lib/Support/DataStream.cpp llvm/trunk/lib/Support/StreamableMemoryObject.cpp Modified: llvm/trunk/include/llvm/Support/DataStream.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149922&r1=149921&r2=149922&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/DataStream.h (original) +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb 6 16:41:47 2012 @@ -1,4 +1,4 @@ -//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ -*-===// +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149922&r1=149921&r2=149922&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (original) +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb 6 16:41:47 2012 @@ -1,4 +1,4 @@ -//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ -*-===// +//===- StreamableMemoryObject.h - Streamable data interface -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Support/DataStream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149922&r1=149921&r2=149922&view=diff ============================================================================== --- llvm/trunk/lib/Support/DataStream.cpp (original) +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 16:41:47 2012 @@ -1,4 +1,4 @@ -//===--- llvm/Support/DataStream.cpp - Lazy streamed Data ---===// +//===--- llvm/Support/DataStream.cpp - Lazy streamed data -----------------===// // // The LLVM Compiler Infrastructure // Modified: llvm/trunk/lib/Support/StreamableMemoryObject.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149922&r1=149921&r2=149922&view=diff ============================================================================== --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (original) +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb 6 16:41:47 2012 @@ -1,4 +1,4 @@ -//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ -*-===// +//===- StreamableMemoryObject.cpp - Streamable data interface -------------===// // // The LLVM Compiler Infrastructure // From kcc at google.com Mon Feb 6 16:48:56 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 06 Feb 2012 22:48:56 -0000 Subject: [llvm-commits] [llvm] r149925 - in /llvm/trunk: lib/Analysis/MemoryDependenceAnalysis.cpp test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll Message-ID: <20120206224856.C832B2A6C12C@llvm.org> Author: kcc Date: Mon Feb 6 16:48:56 2012 New Revision: 149925 URL: http://llvm.org/viewvc/llvm-project?rev=149925&view=rev Log: The patch resolves the conflict between AddressSanitizer and load widening (GVN). The problem initially reported by Mozilla folks (http://code.google.com/p/address-sanitizer/issues/detail?id=20), but it also prevents us from enabling LLVM bootstrap with AddressSanitizer. Added: llvm/trunk/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Modified: llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp?rev=149925&r1=149924&r2=149925&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp (original) +++ llvm/trunk/lib/Analysis/MemoryDependenceAnalysis.cpp Mon Feb 6 16:48:56 2012 @@ -323,6 +323,14 @@ !TD.fitsInLegalInteger(NewLoadByteSize*8)) return 0; + if (LIOffs+NewLoadByteSize > MemLocEnd && + LI->getParent()->getParent()->hasFnAttr(Attribute::AddressSafety)) { + // We will be reading past the location accessed by the original program. + // While this is safe in a regular build, Address Safety analysis tools + // may start reporting false warnings. So, don't do widening. + return 0; + } + // If a load of this width would include all of MemLoc, then we succeed. if (LIOffs+NewLoadByteSize >= MemLocEnd) return NewLoadByteSize; Added: llvm/trunk/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll?rev=149925&view=auto ============================================================================== --- llvm/trunk/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll (added) +++ llvm/trunk/test/Instrumentation/AddressSanitizer/asan-vs-gvn.ll Mon Feb 6 16:48:56 2012 @@ -0,0 +1,43 @@ +; RUN: opt < %s -basicaa -gvn -asan -S | FileCheck %s +; ASAN conflicts with load widening iff the widened load accesses data out of bounds +; (while the original unwidened loads do not). +; http://code.google.com/p/address-sanitizer/issues/detail?id=20#c1 + + +; 32-bit little endian target. +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n8:16:32" + +%struct_of_7_bytes_4_aligned = type { i32, i8, i8, i8} + + at f = global %struct_of_7_bytes_4_aligned zeroinitializer, align 4 + +; Accessing bytes 4 and 6, not ok to widen to i32 if address_safety is set. + +define i32 @test_widening_bad(i8* %P) nounwind ssp noredzone address_safety { +entry: + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* @f, i64 0, i32 1), align 4 + %conv = zext i8 %tmp to i32 + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* @f, i64 0, i32 3), align 1 + %conv2 = zext i8 %tmp1 to i32 + %add = add nsw i32 %conv, %conv2 + ret i32 %add +; CHECK: @test_widening_bad +; CHECK: __asan_report_load1 +; CHECK: __asan_report_load1 +; CHECK-ret i32 +} + +;; Accessing byets 4 and 5. Ok to widen to i16. + +define i32 @test_widening_ok(i8* %P) nounwind ssp noredzone address_safety { +entry: + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* @f, i64 0, i32 1), align 4 + %conv = zext i8 %tmp to i32 + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* @f, i64 0, i32 2), align 1 + %conv2 = zext i8 %tmp1 to i32 + %add = add nsw i32 %conv, %conv2 + ret i32 %add +; CHECK: @test_widening_ok +; CHECK: __asan_report_load1 +; CHECK-ret i32 +} From kcc at google.com Mon Feb 6 16:53:43 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 14:53:43 -0800 Subject: [llvm-commits] fix conflict between AddressSanitizer and load widening (GVN) (issue 5630068) In-Reply-To: References: <20cf300faf2563e8f104b8534398@google.com> Message-ID: On Mon, Feb 6, 2012 at 2:37 PM, Nick Lewycky wrote: > [+llvm-commits, silly codereview.] > > On 6 February 2012 14:34, wrote: > >> Reviewers: nlewycky1, >> >> Message: >> >> On 2012/02/06 22:20:28, nlewycky1 wrote: >> >>> Go ahead and commit once you've resolved the comments Duncan and I >>> >> made. >> >> >> http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** >> MemoryDependenceAnalysis.cpp >> >>> File lib/Analysis/**MemoryDependenceAnalysis.cpp (right): >>> >> >> >> http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** >> MemoryDependenceAnalysis.cpp#**newcode327 >> >>> lib/Analysis/**MemoryDependenceAnalysis.cpp:**327: >>> LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety)) { >>> LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety) >>> is a >>> loop-invariant, please hoist it into "bool MayWidenPastEnd = ...". >>> >> >> Hm? >> This is a loop invariant, but it is not computed on every iteration. >> Sometimes it is never computed. >> If I move it outside of the loop it is likely to be computed more often. > > > Oops, you're right. Short-circuiting and all. :) > > Please commit. > r149925, thanks! > > Nick > > >> >> >> >> >> >> http://codereview.appspot.com/**5630068/diff/2001/lib/**Analysis/** >> MemoryDependenceAnalysis.cpp#**newcode329 >> >>> lib/Analysis/**MemoryDependenceAnalysis.cpp:**329: // While this is safe >>> >> in a >> >>> regular build, Address Safety analysys tools >>> "analysis" >>> >> ok >> >> >> >> >> >> Please review this at http://codereview.appspot.com/**5630068/ >> >> Affected files: >> M lib/Analysis/**MemoryDependenceAnalysis.cpp >> A test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll >> >> >> Index: test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll >> ==============================**==============================**======= >> --- test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll >> (revision 0) >> +++ test/Instrumentation/**AddressSanitizer/asan-vs-gvn.**ll >> (revision 0) >> @@ -0,0 +1,43 @@ >> +; RUN: opt < %s -basicaa -gvn -asan -S | FileCheck %s >> +; ASAN conflicts with load widening iff the widened load accesses data >> out of bounds >> +; (while the original unwidened loads do not). >> +; http://code.google.com/p/**address-sanitizer/issues/**detail?id=20#c1 >> + >> + >> +; 32-bit little endian target. >> +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-** >> i16:16:16-i32:32:32-i64:32:64-**f32:32:32-f64:32:64-v64:64:64-** >> v128:128:128-a0:0:64-f80:128:**128-n8:16:32" >> + >> +%struct_of_7_bytes_4_aligned = type { i32, i8, i8, i8} >> + >> + at f = global %struct_of_7_bytes_4_aligned zeroinitializer, align 4 >> + >> +; Accessing bytes 4 and 6, not ok to widen to i32 if address_safety is >> set. >> + >> +define i32 @test_widening_bad(i8* %P) nounwind ssp noredzone >> address_safety { >> +entry: >> + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* >> @f, i64 0, i32 1), align 4 >> + %conv = zext i8 %tmp to i32 >> + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* >> @f, i64 0, i32 3), align 1 >> + %conv2 = zext i8 %tmp1 to i32 >> + %add = add nsw i32 %conv, %conv2 >> + ret i32 %add >> +; CHECK: @test_widening_bad >> +; CHECK: __asan_report_load1 >> +; CHECK: __asan_report_load1 >> +; CHECK-ret i32 >> +} >> + >> +;; Accessing byets 4 and 5. Ok to widen to i16. >> + >> +define i32 @test_widening_ok(i8* %P) nounwind ssp noredzone >> address_safety { >> +entry: >> + %tmp = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* >> @f, i64 0, i32 1), align 4 >> + %conv = zext i8 %tmp to i32 >> + %tmp1 = load i8* getelementptr inbounds (%struct_of_7_bytes_4_aligned* >> @f, i64 0, i32 2), align 1 >> + %conv2 = zext i8 %tmp1 to i32 >> + %add = add nsw i32 %conv, %conv2 >> + ret i32 %add >> +; CHECK: @test_widening_ok >> +; CHECK: __asan_report_load1 >> +; CHECK-ret i32 >> +} >> Index: lib/Analysis/**MemoryDependenceAnalysis.cpp >> ==============================**==============================**======= >> --- lib/Analysis/**MemoryDependenceAnalysis.cpp (revision 149872) >> +++ lib/Analysis/**MemoryDependenceAnalysis.cpp (working copy) >> @@ -323,6 +323,14 @@ >> !TD.fitsInLegalInteger(**NewLoadByteSize*8)) >> return 0; >> >> + if (LIOffs+NewLoadByteSize > MemLocEnd && >> + LI->getParent()->getParent()->**hasFnAttr(Attribute::**AddressSafety)) >> { >> + // We will be reading past the location accessed by the original >> program. >> >> + // While this is safe in a regular build, Address Safety analysys >> tools >> + // may start reporting false warnings. So, don't do widening. >> + return 0; >> + } >> + >> // If a load of this width would include all of MemLoc, then we >> succeed. >> if (LIOffs+NewLoadByteSize >= MemLocEnd) >> return NewLoadByteSize; >> >> >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/54c8af68/attachment.html From atrick at apple.com Mon Feb 6 16:51:19 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 22:51:19 -0000 Subject: [llvm-commits] [llvm] r149927 - in /llvm/trunk/lib/CodeGen: PrologEpilogInserter.cpp ShrinkWrapping.cpp Message-ID: <20120206225119.353CF2A6C12D@llvm.org> Author: atrick Date: Mon Feb 6 16:51:18 2012 New Revision: 149927 URL: http://llvm.org/viewvc/llvm-project?rev=149927&view=rev Log: Expose TargetPassConfig to PEI Pass Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/CodeGen/ShrinkWrapping.cpp Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=149927&r1=149926&r2=149927&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Mon Feb 6 16:51:18 2012 @@ -50,6 +50,7 @@ "Prologue/Epilogue Insertion", false, false) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) +INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_END(PEI, "prologepilog", "Prologue/Epilogue Insertion", false, false) Modified: llvm/trunk/lib/CodeGen/ShrinkWrapping.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ShrinkWrapping.cpp?rev=149927&r1=149926&r2=149927&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ShrinkWrapping.cpp (original) +++ llvm/trunk/lib/CodeGen/ShrinkWrapping.cpp Mon Feb 6 16:51:18 2012 @@ -93,6 +93,7 @@ } AU.addPreserved(); AU.addPreserved(); + AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } From atrick at apple.com Mon Feb 6 16:51:16 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 22:51:16 -0000 Subject: [llvm-commits] [llvm] r149926 - in /llvm/trunk/lib: CodeGen/LLVMTargetMachine.cpp Target/PTX/PTXTargetMachine.cpp Message-ID: <20120206225116.163742A6C12C@llvm.org> Author: atrick Date: Mon Feb 6 16:51:15 2012 New Revision: 149926 URL: http://llvm.org/viewvc/llvm-project?rev=149926&view=rev Log: Add TargetPassConfig to the PassManager for use inside passes Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=149926&r1=149925&r2=149926&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Mon Feb 6 16:51:15 2012 @@ -116,6 +116,8 @@ // Set PassConfig options provided by TargetMachine. PassConfig->setDisableVerify(DisableVerify); + PM.add(PassConfig); + PassConfig->addIRPasses(); addPassesToHandleExceptions(TM, PM); @@ -145,8 +147,6 @@ PassConfig->addMachinePasses(); - delete PassConfig; - return Context; } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=149926&r1=149925&r2=149926&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Mon Feb 6 16:51:15 2012 @@ -105,7 +105,7 @@ : PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) { } -namespace { +namespace llvm { /// PTX Code Generator Pass Configuration Options. class PTXPassConfig : public TargetPassConfig { public: @@ -147,11 +147,13 @@ MCContext *Context = 0; // FIXME: soon this will be converted to use the exposed TargetPassConfig API. - OwningPtr PassConfig( - static_cast(createPassConfig(PM))); + PTXPassConfig *PassConfig = + static_cast(createPassConfig(PM)); PassConfig->setDisableVerify(DisableVerify); + PM.add(PassConfig); + if (PassConfig->addCodeGenPasses(Context)) return true; assert(Context != 0 && "Failed to get MCContext"); From stoklund at 2pi.dk Mon Feb 6 17:01:04 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 06 Feb 2012 15:01:04 -0800 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: References: <4ebd9343c592547977b041f93d7ee7160da178e7.1328050160.git.dag@cray.com> Message-ID: <86294DCD-DBAD-4949-B054-1E5D5CF4C329@2pi.dk> On Feb 6, 2012, at 8:57 AM, David A. Greene wrote: >> When resubmitting, please squash everything into one patch. > > Are you sure? Yes. > Incremental development is the preferred approach. You misunderstand the concept. It does not mean you should dump your git branch on the mailing list. It means you should get your changes reviewed and committed incrementally. I think it is explained quite well here: http://llvm.org/docs/DeveloperPolicy.html#newwork http://llvm.org/docs/DeveloperPolicy.html#incremental /jakob From spande at codeaurora.org Mon Feb 6 17:00:47 2012 From: spande at codeaurora.org (Sirish Pande) Date: Mon, 06 Feb 2012 17:00:47 -0600 Subject: [llvm-commits] Use of TSFlag in Hexagon Message-ID: <4F305B9F.5040102@codeaurora.org> I have attached a patch that replaces a big switch-case statement with a bit in TSFlag. This is very specific to Hexagon, and it won't affect any other target. This patch essentially replaces the huge body of a function in HexagonInstrInfo.cpp with a use of the TSFlag. Sirish -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Use-TSFlag-isPredicated.patch Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/bfcf7ef9/attachment-0001.pl From atrick at apple.com Mon Feb 6 17:32:14 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 15:32:14 -0800 Subject: [llvm-commits] Question about /llvm/trunk/lib/CodeGen/MachineScheduler.cpp In-Reply-To: <0e7e01cce501$14cd0410$3e670c30$@org> References: <20120204052617.5CAF92A6C12C@llvm.org> <0e7e01cce501$14cd0410$3e670c30$@org> Message-ID: <414D1DAF-22FF-4ACB-9C9D-FFBBF2BA3A19@apple.com> Hi Sergei, Please make sure you run with assertions enabled and look at -debug-only=misched output. -verify-machineinstrs may also be useful. I'm not sure what the problem is, but crashing is bad. If there are any implicit assumptions, then they should be made explicit. I'm not sure I understand the CFG output. A block should end in a terminator. BB#7 claims to have a successor, but I don't know what it's terminator is. -Andy On Feb 6, 2012, at 10:56 AM, Sergei Larin wrote: > > Andrew, > > This is something between a bug report and a question. I do not provide > enough context to reproduce the failure, but hope it is fresh enough in your > memory :) > > In lib/CodeGen/MachineScheduler.cpp > > In bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) {} > > While iterating over following MBB, for the following fragment > ... > BB#6: derived from LLVM BB %sw.bb6, ADDRESS TAKEN > Predecessors according to CFG: BB#1 > %vreg10 = TFRI 1; IntRegs:%vreg10 > STrib %vreg1, 0, %vreg10; mem:ST1[%Enum_Ref_Par] > IntRegs:%vreg1,%vreg10 > JMP > Successors according to CFG: BB#8 > > BB#7: derived from LLVM BB %sw.bb7, ADDRESS TAKEN > Predecessors according to CFG: BB#1 > %vreg9 = TFRI 2; IntRegs:%vreg9 > STrib %vreg1, 0, %vreg9; mem:ST1[%Enum_Ref_Par] > IntRegs:%vreg1,%vreg9 > Successors according to CFG: BB#8 > > BB#8: derived from LLVM BB %sw.epilog, ADDRESS TAKEN > Predecessors according to CFG: BB#0 BB#1 BB#7 BB#6 BB#5 BB#4 BB#2 > JMPR %PC, %R31, %R0 > ... > > BB#7 seems to cause a problem when iterating over it with RegionEnd pointing > somewhere wrong. Am I breaking some implicit assumption in BB formation? > Want MBB->end() suppose to return for the BB#7? > > *** Final schedule *** > > MachineScheduling Proc_6:BB#7 > From: %vreg9 = TFRI 2; IntRegs:%vreg9 > To: > Program received signal SIGSEGV, Segmentation fault. > 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ > MachineOperand.h:204 > 204 bool isReg() const { return OpKind == MO_Register; } > (gdb) bt > #0 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ > MachineOperand.h:204 > #1 0x00000000021ca720 in llvm::MachineInstr::print (this=0x3e2c9f0, OS=..., > TM=0x0) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineIn > str.cpp:1462 > #2 0x0000000001a970fe in llvm::operator<< (OS=..., MI=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/include/llvm/CodeGen/ > MachineInstr.h:934 > #3 0x00000000022e4c18 in (anonymous > namespace)::MachineScheduler::runOnMachineFunction (this=0x3dcc1c0, mf=...) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineSc > heduler.cpp:297 > #4 0x00000000021c41e5 in llvm::MachineFunctionPass::runOnFunction > (this=0x3dcc1c0, F=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/CodeGen/MachineFu > nctionPass.cpp:33 > #5 0x0000000002789db6 in llvm::FPPassManager::runOnFunction > (this=0x3dcb820, F=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage > r.cpp:1498 > #6 0x000000000278a001 in llvm::FPPassManager::runOnModule (this=0x3dcb820, > M=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage > r.cpp:1520 > #7 0x000000000278a344 in llvm::MPPassManager::runOnModule (this=0x3dc8ec0, > M=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage > r.cpp:1574 > #8 0x000000000278a85a in llvm::PassManagerImpl::run (this=0x3dc8b70, M=...) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage > r.cpp:1658 > #9 0x000000000278ab55 in llvm::PassManager::run (this=0x3d7f140, M=...) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/lib/VMCore/PassManage > r.cpp:1687 > #10 0x0000000000c9488d in (anonymous > namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fffffffa2e0, > Action=clang::Backend_EmitAssembly, OS=0x3d13660) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG > en/BackendUtil.cpp:497 > #11 0x0000000000c94968 in clang::EmitBackendOutput (Diags=..., CGOpts=..., > TOpts=..., LOpts=..., M=0x3d1a3c0, Action=clang::Backend_EmitAssembly, > OS=0x3d13660) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG > en/BackendUtil.cpp:509 > #12 0x0000000000c9042c in clang::BackendConsumer::HandleTranslationUnit > (this=0x3d123a0, C=...) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG > en/CodeGenAction.cpp:155 > #13 0x0000000000e3cf61 in clang::ParseAST (S=..., PrintStats=false) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Parse > /ParseAST.cpp:110 > #14 0x0000000000b00725 in clang::ASTFrontendAction::ExecuteAction > (this=0x3cf1740) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front > end/FrontendAction.cpp:414 > #15 0x0000000000c8ef9c in clang::CodeGenAction::ExecuteAction > (this=0x3cf1740) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/CodeG > en/CodeGenAction.cpp:407 > #16 0x0000000000b00377 in clang::FrontendAction::Execute (this=0x3cf1740) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front > end/FrontendAction.cpp:334 > #17 0x0000000000ad8e63 in clang::CompilerInstance::ExecuteAction > (this=0x3ced2d0, Act=...) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front > end/CompilerInstance.cpp:653 > #18 0x0000000000aaa8e4 in clang::ExecuteCompilerInvocation (Clang=0x3ced2d0) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/lib/Front > endTool/ExecuteCompilerInvocation.cpp:175 > #19 0x0000000000a99618 in cc1_main (ArgBegin=0x7fffffffaf10, > ArgEnd=0x7fffffffb108, Argv0=0x3cebaf8 > "/prj/qct/sunray-austin/scratch/slarin/qdsp6_hex/bin/qc/bin/clang", > MainAddr=0xaa4654) > at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/tools/dri > ver/cc1_main.cpp:165 > #20 0x0000000000aa5e77 in main (argc_=65, argv_=0x7fffffffc058) at > /local/mnt/workspace/slarin/tools/llvm-mainline-merged/tools/clang/tools/dri > ver/driver.cpp:353 > > > Thanks. > > Sergei > From atrick at apple.com Mon Feb 6 17:34:53 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 23:34:53 -0000 Subject: [llvm-commits] [llvm] r149932 - in /llvm/trunk/utils/lit/lit: LitConfig.py TestingConfig.py Message-ID: <20120206233453.341D12A6C12C@llvm.org> Author: atrick Date: Mon Feb 6 17:34:52 2012 New Revision: 149932 URL: http://llvm.org/viewvc/llvm-project?rev=149932&view=rev Log: This is a small patch with a couple of improvements for running lit with --debug: 1. Added a status note when a config file is loaded directly with load_config. This helps notice loads of lit.cfg from lit.site.cfg 2. Added a status note on the result of a config load. Previously, it was just notifying that it tries to load a config file. Now it will also say whether the load succeeded or the file wasn't found The two changes give better visibility into which config files were actually loaded by lit. The effect is only on --debug runs. Patch by Eli Bendersky! Modified: llvm/trunk/utils/lit/lit/LitConfig.py llvm/trunk/utils/lit/lit/TestingConfig.py Modified: llvm/trunk/utils/lit/lit/LitConfig.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/LitConfig.py?rev=149932&r1=149931&r2=149932&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/LitConfig.py (original) +++ llvm/trunk/utils/lit/lit/LitConfig.py Mon Feb 6 17:34:52 2012 @@ -61,6 +61,8 @@ """load_config(config, path) - Load a config object from an alternate path.""" from TestingConfig import TestingConfig + if self.debug: + self.note('load_config from %r' % path) return TestingConfig.frompath(path, config.parent, self, mustExist = True, config = config) Modified: llvm/trunk/utils/lit/lit/TestingConfig.py URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/lit/lit/TestingConfig.py?rev=149932&r1=149931&r2=149932&view=diff ============================================================================== --- llvm/trunk/utils/lit/lit/TestingConfig.py (original) +++ llvm/trunk/utils/lit/lit/TestingConfig.py Mon Feb 6 17:34:52 2012 @@ -50,14 +50,19 @@ cfg_globals['__file__'] = path try: exec f in cfg_globals + if litConfig.debug: + litConfig.note('... loaded config %r' % path) except SystemExit,status: # We allow normal system exit inside a config file to just # return control without error. if status.args: raise f.close() - elif mustExist: - litConfig.fatal('unable to load config from %r ' % path) + else: + if mustExist: + litConfig.fatal('unable to load config from %r ' % path) + elif litConfig.debug: + litConfig.note('... config not found - %r' %path) config.finish(litConfig) return config From atrick at apple.com Mon Feb 6 17:41:26 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 15:41:26 -0800 Subject: [llvm-commits] [PATCH] improve lit --debug In-Reply-To: <9BBE4537D1BAAB479E9E8F9D4234619D3373CA@HASMSX103.ger.corp.intel.com> References: <9BBE4537D1BAAB479E9E8F9D4234619D3373CA@HASMSX103.ger.corp.intel.com> Message-ID: <651C4A20-1AB9-4D4F-85F2-9CB2DFFFF727@apple.com> On Feb 5, 2012, at 4:09 AM, "Bendersky, Eli" wrote: > This is a small patch with a couple of improvements for running lit with --debug: > > 1. Added a status note when a config file is loaded directly with load_config. This helps notice loads of lit.cfg from lit.site.cfg > 2. Added a status note on the result of a config load. Previously, it was just notifying that it tries to load a config file. Now it will also say whether the load succeeded or the file wasn't found > > The two changes give better visibility into which config files were actually loaded by lit. The effect is only on --debug runs. > > Please review! Committed r149932. Thanks Eli. This should save me doing the same manually each time I debug lit config. -Andy From slarin at codeaurora.org Mon Feb 6 17:53:50 2012 From: slarin at codeaurora.org (Sergei Larin) Date: Mon, 6 Feb 2012 17:53:50 -0600 Subject: [llvm-commits] Question about /llvm/trunk/lib/CodeGen/MachineScheduler.cpp In-Reply-To: <414D1DAF-22FF-4ACB-9C9D-FFBBF2BA3A19@apple.com> References: <20120204052617.5CAF92A6C12C@llvm.org> <0e7e01cce501$14cd0410$3e670c30$@org> <414D1DAF-22FF-4ACB-9C9D-FFBBF2BA3A19@apple.com> Message-ID: <0f8d01cce52a$936c57c0$ba450740$@org> Andrew, Asserts are "on", nothing is caught. Debug output offers a single clue - the BB in question has a non-jump terminator (STrib == store byte). I guess my question then becomes - can a non control flow instruction serve as BB terminator (the implicit assumption I was referring to)? If not then I'll try to find where the "proper" terminator was lost. Thanks. Sergei -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum. > -----Original Message----- > From: Andrew Trick [mailto:atrick at apple.com] > Sent: Monday, February 06, 2012 5:32 PM > To: Sergei Larin > Cc: llvm-commits at cs.uiuc.edu > Subject: Re: Question about > /llvm/trunk/lib/CodeGen/MachineScheduler.cpp > > Hi Sergei, > > Please make sure you run with assertions enabled and look at -debug- > only=misched output. -verify-machineinstrs may also be useful. > > I'm not sure what the problem is, but crashing is bad. If there are any > implicit assumptions, then they should be made explicit. > > I'm not sure I understand the CFG output. A block should end in a > terminator. BB#7 claims to have a successor, but I don't know what it's > terminator is. > > -Andy > > On Feb 6, 2012, at 10:56 AM, Sergei Larin > wrote: > > > > > Andrew, > > > > This is something between a bug report and a question. I do not > provide > > enough context to reproduce the failure, but hope it is fresh enough > in your > > memory :) > > > > In lib/CodeGen/MachineScheduler.cpp > > > > In bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) > {} > > > > While iterating over following MBB, for the following fragment > > ... > > BB#6: derived from LLVM BB %sw.bb6, ADDRESS TAKEN > > Predecessors according to CFG: BB#1 > > %vreg10 = TFRI 1; IntRegs:%vreg10 > > STrib %vreg1, 0, %vreg10; mem:ST1[%Enum_Ref_Par] > > IntRegs:%vreg1,%vreg10 > > JMP > > Successors according to CFG: BB#8 > > > > BB#7: derived from LLVM BB %sw.bb7, ADDRESS TAKEN > > Predecessors according to CFG: BB#1 > > %vreg9 = TFRI 2; IntRegs:%vreg9 > > STrib %vreg1, 0, %vreg9; mem:ST1[%Enum_Ref_Par] > > IntRegs:%vreg1,%vreg9 > > Successors according to CFG: BB#8 > > > > BB#8: derived from LLVM BB %sw.epilog, ADDRESS TAKEN > > Predecessors according to CFG: BB#0 BB#1 BB#7 BB#6 BB#5 BB#4 BB#2 > > JMPR %PC, %R31, %R0 > > ... > > > > BB#7 seems to cause a problem when iterating over it with RegionEnd > pointing > > somewhere wrong. Am I breaking some implicit assumption in BB > formation? > > Want MBB->end() suppose to return for the BB#7? > > > > *** Final schedule *** > > > > MachineScheduling Proc_6:BB#7 > > From: %vreg9 = TFRI 2; IntRegs:%vreg9 > > To: > > Program received signal SIGSEGV, Segmentation fault. > > 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/include/llvm/CodeGen/ > > MachineOperand.h:204 > > 204 bool isReg() const { return OpKind == MO_Register; } > > (gdb) bt > > #0 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/include/llvm/CodeGen/ > > MachineOperand.h:204 > > #1 0x00000000021ca720 in llvm::MachineInstr::print (this=0x3e2c9f0, > OS=..., > > TM=0x0) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/CodeGen/MachineIn > > str.cpp:1462 > > #2 0x0000000001a970fe in llvm::operator<< (OS=..., MI=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/include/llvm/CodeGen/ > > MachineInstr.h:934 > > #3 0x00000000022e4c18 in (anonymous > > namespace)::MachineScheduler::runOnMachineFunction (this=0x3dcc1c0, > mf=...) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/CodeGen/MachineSc > > heduler.cpp:297 > > #4 0x00000000021c41e5 in llvm::MachineFunctionPass::runOnFunction > > (this=0x3dcc1c0, F=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/CodeGen/MachineFu > > nctionPass.cpp:33 > > #5 0x0000000002789db6 in llvm::FPPassManager::runOnFunction > > (this=0x3dcb820, F=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/VMCore/PassManage > > r.cpp:1498 > > #6 0x000000000278a001 in llvm::FPPassManager::runOnModule > (this=0x3dcb820, > > M=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/VMCore/PassManage > > r.cpp:1520 > > #7 0x000000000278a344 in llvm::MPPassManager::runOnModule > (this=0x3dc8ec0, > > M=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/VMCore/PassManage > > r.cpp:1574 > > #8 0x000000000278a85a in llvm::PassManagerImpl::run (this=0x3dc8b70, > M=...) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/VMCore/PassManage > > r.cpp:1658 > > #9 0x000000000278ab55 in llvm::PassManager::run (this=0x3d7f140, > M=...) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/lib/VMCore/PassManage > > r.cpp:1687 > > #10 0x0000000000c9488d in (anonymous > > namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fffffffa2e0, > > Action=clang::Backend_EmitAssembly, OS=0x3d13660) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/CodeG > > en/BackendUtil.cpp:497 > > #11 0x0000000000c94968 in clang::EmitBackendOutput (Diags=..., > CGOpts=..., > > TOpts=..., LOpts=..., M=0x3d1a3c0, > Action=clang::Backend_EmitAssembly, > > OS=0x3d13660) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/CodeG > > en/BackendUtil.cpp:509 > > #12 0x0000000000c9042c in > clang::BackendConsumer::HandleTranslationUnit > > (this=0x3d123a0, C=...) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/CodeG > > en/CodeGenAction.cpp:155 > > #13 0x0000000000e3cf61 in clang::ParseAST (S=..., PrintStats=false) > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/Parse > > /ParseAST.cpp:110 > > #14 0x0000000000b00725 in clang::ASTFrontendAction::ExecuteAction > > (this=0x3cf1740) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/Front > > end/FrontendAction.cpp:414 > > #15 0x0000000000c8ef9c in clang::CodeGenAction::ExecuteAction > > (this=0x3cf1740) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/CodeG > > en/CodeGenAction.cpp:407 > > #16 0x0000000000b00377 in clang::FrontendAction::Execute > (this=0x3cf1740) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/Front > > end/FrontendAction.cpp:334 > > #17 0x0000000000ad8e63 in clang::CompilerInstance::ExecuteAction > > (this=0x3ced2d0, Act=...) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/Front > > end/CompilerInstance.cpp:653 > > #18 0x0000000000aaa8e4 in clang::ExecuteCompilerInvocation > (Clang=0x3ced2d0) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/lib/Front > > endTool/ExecuteCompilerInvocation.cpp:175 > > #19 0x0000000000a99618 in cc1_main (ArgBegin=0x7fffffffaf10, > > ArgEnd=0x7fffffffb108, Argv0=0x3cebaf8 > > "/prj/qct/sunray-austin/scratch/slarin/qdsp6_hex/bin/qc/bin/clang", > > MainAddr=0xaa4654) > > at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/tools/dri > > ver/cc1_main.cpp:165 > > #20 0x0000000000aa5e77 in main (argc_=65, argv_=0x7fffffffc058) at > > /local/mnt/workspace/slarin/tools/llvm-mainline- > merged/tools/clang/tools/dri > > ver/driver.cpp:353 > > > > > > Thanks. > > > > Sergei > > From mcrosier at apple.com Mon Feb 6 17:50:07 2012 From: mcrosier at apple.com (Chad Rosier) Date: Mon, 06 Feb 2012 23:50:07 -0000 Subject: [llvm-commits] [llvm] r149934 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-binary.ll Message-ID: <20120206235007.7EDF82A6C12C@llvm.org> Author: mcrosier Date: Mon Feb 6 17:50:07 2012 New Revision: 149934 URL: http://llvm.org/viewvc/llvm-project?rev=149934&view=rev Log: [fast-isel] Add support for ADDs with non-legal types. Added: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=149934&r1=149933&r2=149934&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Mon Feb 6 17:50:07 2012 @@ -160,7 +160,8 @@ bool SelectCmp(const Instruction *I); bool SelectFPExt(const Instruction *I); bool SelectFPTrunc(const Instruction *I); - bool SelectBinaryOp(const Instruction *I, unsigned ISDOpcode); + bool SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode); + bool SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode); bool SelectIToFP(const Instruction *I, bool isSigned); bool SelectFPToI(const Instruction *I, bool isSigned); bool SelectDiv(const Instruction *I, bool isSigned); @@ -1722,7 +1723,33 @@ return ARMEmitLibcall(I, LC); } -bool ARMFastISel::SelectBinaryOp(const Instruction *I, unsigned ISDOpcode) { +bool ARMFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) { + assert (ISDOpcode == ISD::ADD && "Expected an add."); + EVT DestVT = TLI.getValueType(I->getType(), true); + + // We can get here in the case when we have a binary operation on a non-legal + // type and the target independent selector doesn't know how to handle it. + if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) + return false; + + unsigned SrcReg1 = getRegForValue(I->getOperand(0)); + if (SrcReg1 == 0) return false; + + // TODO: Often the 2nd operand is an immediate, which can be encoded directly + // in the instruction, rather then materializing the value in a register. + unsigned SrcReg2 = getRegForValue(I->getOperand(1)); + if (SrcReg2 == 0) return false; + + unsigned Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr; + unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32)); + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, + TII.get(Opc), ResultReg) + .addReg(SrcReg1).addReg(SrcReg2)); + UpdateValueMap(I, ResultReg); + return true; +} + +bool ARMFastISel::SelectBinaryFPOp(const Instruction *I, unsigned ISDOpcode) { EVT VT = TLI.getValueType(I->getType(), true); // We can get here in the case when we want to use NEON for our fp @@ -2458,12 +2485,14 @@ return SelectFPToI(I, /*isSigned*/ true); case Instruction::FPToUI: return SelectFPToI(I, /*isSigned*/ false); + case Instruction::Add: + return SelectBinaryIntOp(I, ISD::ADD); case Instruction::FAdd: - return SelectBinaryOp(I, ISD::FADD); + return SelectBinaryFPOp(I, ISD::FADD); case Instruction::FSub: - return SelectBinaryOp(I, ISD::FSUB); + return SelectBinaryFPOp(I, ISD::FSUB); case Instruction::FMul: - return SelectBinaryOp(I, ISD::FMUL); + return SelectBinaryFPOp(I, ISD::FMUL); case Instruction::SDiv: return SelectDiv(I, /*isSigned*/ true); case Instruction::UDiv: Added: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll?rev=149934&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll (added) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Mon Feb 6 17:50:07 2012 @@ -0,0 +1,40 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB + +; Test add with non-legal types + +define void @add_i1(i1 %a, i1 %b) nounwind ssp { +entry: +; ARM: add_i1 +; THUMB: add_i1 + %a.addr = alloca i1, align 4 + %0 = add i1 %a, %b +; ARM: add r0, r0, r1 +; THUMB: add r0, r1 + store i1 %0, i1* %a.addr, align 4 + ret void +} + +define void @add_i8(i8 %a, i8 %b) nounwind ssp { +entry: +; ARM: add_i8 +; THUMB: add_i8 + %a.addr = alloca i8, align 4 + %0 = add i8 %a, %b +; ARM: add r0, r0, r1 +; THUMB: add r0, r1 + store i8 %0, i8* %a.addr, align 4 + ret void +} + +define void @add_i16(i16 %a, i16 %b) nounwind ssp { +entry: +; ARM: add_i16 +; THUMB: add_i16 + %a.addr = alloca i16, align 4 + %0 = add i16 %a, %b +; ARM: add r0, r0, r1 +; THUMB: add r0, r1 + store i16 %0, i16* %a.addr, align 4 + ret void +} From atrick at apple.com Mon Feb 6 18:05:54 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 16:05:54 -0800 Subject: [llvm-commits] Question about /llvm/trunk/lib/CodeGen/MachineScheduler.cpp In-Reply-To: <0f8d01cce52a$936c57c0$ba450740$@org> References: <20120204052617.5CAF92A6C12C@llvm.org> <0e7e01cce501$14cd0410$3e670c30$@org> <414D1DAF-22FF-4ACB-9C9D-FFBBF2BA3A19@apple.com> <0f8d01cce52a$936c57c0$ba450740$@org> Message-ID: Sergei, Anything can be a terminator if the target says so. A terminator can only be followed by other terminators in the same block (at least I think that's true throughout the backend). Empty blocks, or blocks with only a single instruction that not a terminator or some other scheduling boundary should never be seen by the scheduler. Maybe that's your problem. I don't know because I haven't seen your debug output. -Andy On Feb 6, 2012, at 3:53 PM, Sergei Larin wrote: > > Andrew, > > Asserts are "on", nothing is caught. Debug output offers a single clue - > the BB in question has a non-jump terminator (STrib == store byte). > I guess my question then becomes - can a non control flow instruction serve > as BB terminator (the implicit assumption I was referring to)? If not then > I'll try to find where the "proper" terminator was lost. > > Thanks. > > Sergei > > -- > Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum. > > >> -----Original Message----- >> From: Andrew Trick [mailto:atrick at apple.com] >> Sent: Monday, February 06, 2012 5:32 PM >> To: Sergei Larin >> Cc: llvm-commits at cs.uiuc.edu >> Subject: Re: Question about >> /llvm/trunk/lib/CodeGen/MachineScheduler.cpp >> >> Hi Sergei, >> >> Please make sure you run with assertions enabled and look at -debug- >> only=misched output. -verify-machineinstrs may also be useful. >> >> I'm not sure what the problem is, but crashing is bad. If there are any >> implicit assumptions, then they should be made explicit. >> >> I'm not sure I understand the CFG output. A block should end in a >> terminator. BB#7 claims to have a successor, but I don't know what it's >> terminator is. >> >> -Andy >> >> On Feb 6, 2012, at 10:56 AM, Sergei Larin >> wrote: >> >>> >>> Andrew, >>> >>> This is something between a bug report and a question. I do not >> provide >>> enough context to reproduce the failure, but hope it is fresh enough >> in your >>> memory :) >>> >>> In lib/CodeGen/MachineScheduler.cpp >>> >>> In bool MachineScheduler::runOnMachineFunction(MachineFunction &mf) >> {} >>> >>> While iterating over following MBB, for the following fragment >>> ... >>> BB#6: derived from LLVM BB %sw.bb6, ADDRESS TAKEN >>> Predecessors according to CFG: BB#1 >>> %vreg10 = TFRI 1; IntRegs:%vreg10 >>> STrib %vreg1, 0, %vreg10; mem:ST1[%Enum_Ref_Par] >>> IntRegs:%vreg1,%vreg10 >>> JMP >>> Successors according to CFG: BB#8 >>> >>> BB#7: derived from LLVM BB %sw.bb7, ADDRESS TAKEN >>> Predecessors according to CFG: BB#1 >>> %vreg9 = TFRI 2; IntRegs:%vreg9 >>> STrib %vreg1, 0, %vreg9; mem:ST1[%Enum_Ref_Par] >>> IntRegs:%vreg1,%vreg9 >>> Successors according to CFG: BB#8 >>> >>> BB#8: derived from LLVM BB %sw.epilog, ADDRESS TAKEN >>> Predecessors according to CFG: BB#0 BB#1 BB#7 BB#6 BB#5 BB#4 BB#2 >>> JMPR %PC, %R31, %R0 >>> ... >>> >>> BB#7 seems to cause a problem when iterating over it with RegionEnd >> pointing >>> somewhere wrong. Am I breaking some implicit assumption in BB >> formation? >>> Want MBB->end() suppose to return for the BB#7? >>> >>> *** Final schedule *** >>> >>> MachineScheduling Proc_6:BB#7 >>> From: %vreg9 = TFRI 2; IntRegs:%vreg9 >>> To: >>> Program received signal SIGSEGV, Segmentation fault. >>> 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/include/llvm/CodeGen/ >>> MachineOperand.h:204 >>> 204 bool isReg() const { return OpKind == MO_Register; } >>> (gdb) bt >>> #0 0x0000000001a0c814 in llvm::MachineOperand::isReg (this=0x7) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/include/llvm/CodeGen/ >>> MachineOperand.h:204 >>> #1 0x00000000021ca720 in llvm::MachineInstr::print (this=0x3e2c9f0, >> OS=..., >>> TM=0x0) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/CodeGen/MachineIn >>> str.cpp:1462 >>> #2 0x0000000001a970fe in llvm::operator<< (OS=..., MI=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/include/llvm/CodeGen/ >>> MachineInstr.h:934 >>> #3 0x00000000022e4c18 in (anonymous >>> namespace)::MachineScheduler::runOnMachineFunction (this=0x3dcc1c0, >> mf=...) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/CodeGen/MachineSc >>> heduler.cpp:297 >>> #4 0x00000000021c41e5 in llvm::MachineFunctionPass::runOnFunction >>> (this=0x3dcc1c0, F=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/CodeGen/MachineFu >>> nctionPass.cpp:33 >>> #5 0x0000000002789db6 in llvm::FPPassManager::runOnFunction >>> (this=0x3dcb820, F=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/VMCore/PassManage >>> r.cpp:1498 >>> #6 0x000000000278a001 in llvm::FPPassManager::runOnModule >> (this=0x3dcb820, >>> M=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/VMCore/PassManage >>> r.cpp:1520 >>> #7 0x000000000278a344 in llvm::MPPassManager::runOnModule >> (this=0x3dc8ec0, >>> M=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/VMCore/PassManage >>> r.cpp:1574 >>> #8 0x000000000278a85a in llvm::PassManagerImpl::run (this=0x3dc8b70, >> M=...) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/VMCore/PassManage >>> r.cpp:1658 >>> #9 0x000000000278ab55 in llvm::PassManager::run (this=0x3d7f140, >> M=...) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/lib/VMCore/PassManage >>> r.cpp:1687 >>> #10 0x0000000000c9488d in (anonymous >>> namespace)::EmitAssemblyHelper::EmitAssembly (this=0x7fffffffa2e0, >>> Action=clang::Backend_EmitAssembly, OS=0x3d13660) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/CodeG >>> en/BackendUtil.cpp:497 >>> #11 0x0000000000c94968 in clang::EmitBackendOutput (Diags=..., >> CGOpts=..., >>> TOpts=..., LOpts=..., M=0x3d1a3c0, >> Action=clang::Backend_EmitAssembly, >>> OS=0x3d13660) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/CodeG >>> en/BackendUtil.cpp:509 >>> #12 0x0000000000c9042c in >> clang::BackendConsumer::HandleTranslationUnit >>> (this=0x3d123a0, C=...) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/CodeG >>> en/CodeGenAction.cpp:155 >>> #13 0x0000000000e3cf61 in clang::ParseAST (S=..., PrintStats=false) >> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/Parse >>> /ParseAST.cpp:110 >>> #14 0x0000000000b00725 in clang::ASTFrontendAction::ExecuteAction >>> (this=0x3cf1740) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/Front >>> end/FrontendAction.cpp:414 >>> #15 0x0000000000c8ef9c in clang::CodeGenAction::ExecuteAction >>> (this=0x3cf1740) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/CodeG >>> en/CodeGenAction.cpp:407 >>> #16 0x0000000000b00377 in clang::FrontendAction::Execute >> (this=0x3cf1740) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/Front >>> end/FrontendAction.cpp:334 >>> #17 0x0000000000ad8e63 in clang::CompilerInstance::ExecuteAction >>> (this=0x3ced2d0, Act=...) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/Front >>> end/CompilerInstance.cpp:653 >>> #18 0x0000000000aaa8e4 in clang::ExecuteCompilerInvocation >> (Clang=0x3ced2d0) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/lib/Front >>> endTool/ExecuteCompilerInvocation.cpp:175 >>> #19 0x0000000000a99618 in cc1_main (ArgBegin=0x7fffffffaf10, >>> ArgEnd=0x7fffffffb108, Argv0=0x3cebaf8 >>> "/prj/qct/sunray-austin/scratch/slarin/qdsp6_hex/bin/qc/bin/clang", >>> MainAddr=0xaa4654) >>> at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/tools/dri >>> ver/cc1_main.cpp:165 >>> #20 0x0000000000aa5e77 in main (argc_=65, argv_=0x7fffffffc058) at >>> /local/mnt/workspace/slarin/tools/llvm-mainline- >> merged/tools/clang/tools/dri >>> ver/driver.cpp:353 >>> >>> >>> Thanks. >>> >>> Sergei >>> > > From kcc at google.com Mon Feb 6 18:27:16 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 07 Feb 2012 00:27:16 -0000 Subject: [llvm-commits] [compiler-rt] r149940 - in /compiler-rt/trunk/lib/asan: asan_internal.h asan_posix.cc asan_thread.cc asan_thread.h asan_thread_registry.cc tests/asan_test.cc Message-ID: <20120207002716.59AD02A6C12C@llvm.org> Author: kcc Date: Mon Feb 6 18:27:15 2012 New Revision: 149940 URL: http://llvm.org/viewvc/llvm-project?rev=149940&view=rev Log: [asan] make sure the AsanThread object is destroyed if pthread_exit is called Modified: compiler-rt/trunk/lib/asan/asan_internal.h compiler-rt/trunk/lib/asan/asan_posix.cc compiler-rt/trunk/lib/asan/asan_thread.cc compiler-rt/trunk/lib/asan/asan_thread.h compiler-rt/trunk/lib/asan/asan_thread_registry.cc compiler-rt/trunk/lib/asan/tests/asan_test.cc Modified: compiler-rt/trunk/lib/asan/asan_internal.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_internal.h (original) +++ compiler-rt/trunk/lib/asan/asan_internal.h Mon Feb 6 18:27:15 2012 @@ -129,7 +129,7 @@ int AtomicInc(int *a); // Wrapper for TLS/TSD. -void AsanTSDInit(); +void AsanTSDInit(void (*destructor)(void *tsd)); void *AsanTSDGet(); void AsanTSDSet(void *tsd); Modified: compiler-rt/trunk/lib/asan/asan_posix.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_posix.cc (original) +++ compiler-rt/trunk/lib/asan/asan_posix.cc Mon Feb 6 18:27:15 2012 @@ -97,10 +97,10 @@ static pthread_key_t tsd_key; static bool tsd_key_inited = false; -void AsanTSDInit() { +void AsanTSDInit(void (*destructor)(void *tsd)) { CHECK(!tsd_key_inited); tsd_key_inited = true; - CHECK(0 == pthread_key_create(&tsd_key, 0)); + CHECK(0 == pthread_key_create(&tsd_key, destructor)); } void *AsanTSDGet() { Modified: compiler-rt/trunk/lib/asan/asan_thread.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.cc?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_thread.cc (original) +++ compiler-rt/trunk/lib/asan/asan_thread.cc Mon Feb 6 18:27:15 2012 @@ -40,7 +40,23 @@ return thread; } +void AsanThreadSummary::TSDDtor(void *tsd) { + AsanThreadSummary *summary = (AsanThreadSummary*)tsd; + if (FLAG_v >= 1) { + Report("T%d TSDDtor\n", summary->tid()); + } + if (summary->thread()) { + summary->thread()->Destroy(); + } +} + void AsanThread::Destroy() { + if (FLAG_v >= 1) { + Report("T%d exited\n", tid()); + } + + asanThreadRegistry().UnregisterThread(this); + CHECK(summary()->thread() == NULL); // We also clear the shadow on thread destruction because // some code may still be executing in later TSD destructors // and we don't want it to have any poisoned stack. @@ -78,11 +94,6 @@ void *res = start_routine_(arg_); malloc_storage().CommitBack(); - if (FLAG_v >= 1) { - Report("T%d exited\n", tid()); - } - - asanThreadRegistry().UnregisterThread(this); this->Destroy(); return res; Modified: compiler-rt/trunk/lib/asan/asan_thread.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread.h?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_thread.h (original) +++ compiler-rt/trunk/lib/asan/asan_thread.h Mon Feb 6 18:27:15 2012 @@ -51,6 +51,8 @@ void set_tid(int tid) { tid_ = tid; } AsanThread *thread() { return thread_; } void set_thread(AsanThread *thread) { thread_ = thread; } + static void TSDDtor(void *tsd); + private: int tid_; int parent_tid_; Modified: compiler-rt/trunk/lib/asan/asan_thread_registry.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_thread_registry.cc?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_thread_registry.cc (original) +++ compiler-rt/trunk/lib/asan/asan_thread_registry.cc Mon Feb 6 18:27:15 2012 @@ -32,7 +32,7 @@ mu_(x) { } void AsanThreadRegistry::Init() { - AsanTSDInit(); + AsanTSDInit(AsanThreadSummary::TSDDtor); main_thread_.set_summary(&main_thread_summary_); main_thread_summary_.set_thread(&main_thread_); RegisterThread(&main_thread_); Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=149940&r1=149939&r2=149940&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original) +++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Mon Feb 6 18:27:15 2012 @@ -1637,6 +1637,18 @@ } } +static void *PthreadExit(void *a) { + pthread_exit(0); +} + +TEST(AddressSanitizer, PthreadExitTest) { + pthread_t t; + for (int i = 0; i < 1000; i++) { + pthread_create(&t, 0, PthreadExit, 0); + pthread_join(t, 0); + } +} + #ifdef __EXCEPTIONS __attribute__((noinline)) static void StackReuseAndException() { From dschuff at google.com Mon Feb 6 18:28:47 2012 From: dschuff at google.com (Derek Schuff) Date: Tue, 07 Feb 2012 00:28:47 -0000 Subject: [llvm-commits] [llvm] r149941 - /llvm/trunk/lib/Support/DataStream.cpp Message-ID: <20120207002847.4AE6C2A6C12C@llvm.org> Author: dschuff Date: Mon Feb 6 18:28:46 2012 New Revision: 149941 URL: http://llvm.org/viewvc/llvm-project?rev=149941&view=rev Log: Fix win32 build breakage from bitcode streaming patch Modified: llvm/trunk/lib/Support/DataStream.cpp Modified: llvm/trunk/lib/Support/DataStream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149941&r1=149940&r2=149941&view=diff ============================================================================== --- llvm/trunk/lib/Support/DataStream.cpp (original) +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 18:28:46 2012 @@ -17,6 +17,7 @@ #define DEBUG_TYPE "Data-stream" #include "llvm/ADT/Statistic.h" #include "llvm/Support/DataStream.h" +#include "llvm/Support/Program.h" #include "llvm/Support/system_error.h" #include #include @@ -69,8 +70,10 @@ #ifdef O_BINARY OpenFlags |= O_BINARY; // Open input file in binary mode on win32. #endif - if (Filename == "-") + if (Filename == "-") { Fd = 0; + sys::Program::ChangeStdinToBinary(); + } else Fd = ::open(Filename.c_str(), OpenFlags); if (Fd == -1) return error_code(errno, posix_category()); From kcc at google.com Mon Feb 6 18:47:35 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 07 Feb 2012 00:47:35 -0000 Subject: [llvm-commits] [compiler-rt] r149944 - /compiler-rt/trunk/lib/asan/asan_linux.cc Message-ID: <20120207004735.ECE172A6C12C@llvm.org> Author: kcc Date: Mon Feb 6 18:47:35 2012 New Revision: 149944 URL: http://llvm.org/viewvc/llvm-project?rev=149944&view=rev Log: [asan] don't crash if /proc/self/maps has enormous size (linux) Modified: compiler-rt/trunk/lib/asan/asan_linux.cc Modified: compiler-rt/trunk/lib/asan/asan_linux.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=149944&r1=149943&r2=149944&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_linux.cc (original) +++ compiler-rt/trunk/lib/asan/asan_linux.cc Mon Feb 6 18:47:35 2012 @@ -131,7 +131,7 @@ inited = true; size_t environ_size; len = ReadFileToBuffer("/proc/self/environ", - &environ, &environ_size, 1 << 20); + &environ, &environ_size, 1 << 26); } if (!environ || len == 0) return NULL; size_t namelen = internal_strlen(name); @@ -160,7 +160,7 @@ AsanProcMaps::AsanProcMaps() { proc_self_maps_buff_len_ = ReadFileToBuffer("/proc/self/maps", &proc_self_maps_buff_, - &proc_self_maps_buff_mmaped_size_, 1 << 20); + &proc_self_maps_buff_mmaped_size_, 1 << 26); CHECK(proc_self_maps_buff_len_ > 0); // AsanWrite(2, proc_self_maps_buff_, proc_self_maps_buff_len_); Reset(); From greened at obbligato.org Mon Feb 6 18:59:07 2012 From: greened at obbligato.org (David A. Greene) Date: Mon, 06 Feb 2012 18:59:07 -0600 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <86294DCD-DBAD-4949-B054-1E5D5CF4C329@2pi.dk> (Jakob Stoklund Olesen's message of "Mon, 06 Feb 2012 15:01:04 -0800") References: <4ebd9343c592547977b041f93d7ee7160da178e7.1328050160.git.dag@cray.com> <86294DCD-DBAD-4949-B054-1E5D5CF4C329@2pi.dk> Message-ID: <87k43zxxus.fsf@smith.obbligato.org> Jakob Stoklund Olesen writes: > On Feb 6, 2012, at 8:57 AM, David A. Greene wrote: > >>> When resubmitting, please squash everything into one patch. >> >> Are you sure? > > Yes. Ok. >> Incremental development is the preferred approach. > > You misunderstand the concept. It does not mean you should dump your git branch on the mailing list. > > It means you should get your changes reviewed and committed incrementally. > > I think it is explained quite well here: > > http://llvm.org/docs/DeveloperPolicy.html#newwork > http://llvm.org/docs/DeveloperPolicy.html#incremental I tried to follow this guide. For example, making the "setup" changes before turning the feature on. Obviously I misunderstood. I'll try harder next time. -Dave From isanbard at gmail.com Mon Feb 6 19:27:52 2012 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 07 Feb 2012 01:27:52 -0000 Subject: [llvm-commits] [llvm] r149952 - in /llvm/trunk/lib/VMCore: Constants.cpp Type.cpp Message-ID: <20120207012752.2C4032A6C12C@llvm.org> Author: void Date: Mon Feb 6 19:27:51 2012 New Revision: 149952 URL: http://llvm.org/viewvc/llvm-project?rev=149952&view=rev Log: Reserve space in these vectors to prevent having to grow the array too much. This gets us an addition 0.9% on 445.gobmk. Modified: llvm/trunk/lib/VMCore/Constants.cpp llvm/trunk/lib/VMCore/Type.cpp Modified: llvm/trunk/lib/VMCore/Constants.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Constants.cpp?rev=149952&r1=149951&r2=149952&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Constants.cpp (original) +++ llvm/trunk/lib/VMCore/Constants.cpp Mon Feb 6 19:27:51 2012 @@ -784,9 +784,10 @@ StructType *ConstantStruct::getTypeForElements(LLVMContext &Context, ArrayRef V, bool Packed) { - SmallVector EltTypes; - for (unsigned i = 0, e = V.size(); i != e; ++i) - EltTypes.push_back(V[i]->getType()); + unsigned VecSize = V.size(); + SmallVector EltTypes(VecSize); + for (unsigned i = 0; i != VecSize; ++i) + EltTypes[i] = V[i]->getType(); return StructType::get(Context, EltTypes, Packed); } Modified: llvm/trunk/lib/VMCore/Type.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Type.cpp?rev=149952&r1=149951&r2=149952&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Type.cpp (original) +++ llvm/trunk/lib/VMCore/Type.cpp Mon Feb 6 19:27:51 2012 @@ -440,11 +440,12 @@ StructType *StructType::get(LLVMContext &Context, ArrayRef ETypes, bool isPacked) { // FIXME: std::vector is horribly inefficient for this probe. - std::vector Key; - for (unsigned i = 0, e = ETypes.size(); i != e; ++i) { + unsigned ETypesSize = ETypes.size(); + std::vector Key(ETypesSize); + for (unsigned i = 0, e = ETypesSize; i != e; ++i) { assert(isValidElementType(ETypes[i]) && "Invalid type for structure element!"); - Key.push_back(ETypes[i]); + Key[i] = ETypes[i]; } if (isPacked) Key.push_back(0); From isanbard at gmail.com Mon Feb 6 19:48:12 2012 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 07 Feb 2012 01:48:12 -0000 Subject: [llvm-commits] [llvm] r149954 - /llvm/trunk/lib/VMCore/Type.cpp Message-ID: <20120207014812.79ADC2A6C12C@llvm.org> Author: void Date: Mon Feb 6 19:48:12 2012 New Revision: 149954 URL: http://llvm.org/viewvc/llvm-project?rev=149954&view=rev Log: Cache the sizes of vectors instead of calculating them all over the place. Modified: llvm/trunk/lib/VMCore/Type.cpp Modified: llvm/trunk/lib/VMCore/Type.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Type.cpp?rev=149954&r1=149953&r2=149954&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Type.cpp (original) +++ llvm/trunk/lib/VMCore/Type.cpp Mon Feb 6 19:48:12 2012 @@ -391,10 +391,11 @@ FunctionType *FunctionType::get(Type *ReturnType, ArrayRef Params, bool isVarArg) { // TODO: This is brutally slow. + unsigned ParamsSize = Params.size(); std::vector Key; - Key.reserve(Params.size()+2); + Key.reserve(ParamsSize + 2); Key.push_back(const_cast(ReturnType)); - for (unsigned i = 0, e = Params.size(); i != e; ++i) + for (unsigned i = 0, e = ParamsSize; i != e; ++i) Key.push_back(const_cast(Params[i])); if (isVarArg) Key.push_back(0); @@ -404,7 +405,7 @@ if (FT == 0) { FT = (FunctionType*) pImpl->TypeAllocator. - Allocate(sizeof(FunctionType) + sizeof(Type*)*(Params.size()+1), + Allocate(sizeof(FunctionType) + sizeof(Type*) * (ParamsSize + 1), AlignOf::Alignment); new (FT) FunctionType(ReturnType, Params, isVarArg); } @@ -466,13 +467,13 @@ setSubclassData(getSubclassData() | SCDB_HasBody); if (isPacked) setSubclassData(getSubclassData() | SCDB_Packed); - - Type **Elts = getContext().pImpl-> - TypeAllocator.Allocate(Elements.size()); - memcpy(Elts, Elements.data(), sizeof(Elements[0])*Elements.size()); + + unsigned NumElements = Elements.size(); + Type **Elts = getContext().pImpl->TypeAllocator.Allocate(NumElements); + memcpy(Elts, Elements.data(), sizeof(Elements[0]) * NumElements); ContainedTys = Elts; - NumContainedTys = Elements.size(); + NumContainedTys = NumElements; } void StructType::setName(StringRef Name) { @@ -497,9 +498,10 @@ SmallString<64> TempStr(Name); TempStr.push_back('.'); raw_svector_ostream TmpStream(TempStr); + unsigned NameSize = Name.size(); do { - TempStr.resize(Name.size()+1); + TempStr.resize(NameSize + 1); TmpStream.resync(); TmpStream << getContext().pImpl->NamedStructTypesUniqueID++; From atrick at apple.com Mon Feb 6 20:16:09 2012 From: atrick at apple.com (Andrew Trick) Date: Mon, 06 Feb 2012 18:16:09 -0800 Subject: [llvm-commits] Target independent VLIW Packetizer In-Reply-To: <000001cce4a6$3140dbe0$93c293a0$@org> References: <000001cce4a6$3140dbe0$93c293a0$@org> Message-ID: On Feb 6, 2012, at 12:06 AM, Sundeep wrote: > I have been working on a target independent VLIW packetizer in LLVM. On VLIW > machines, an instruction packet represents a group of instructions which can > be executed in parallel. The compiler is responsible for identifying > independent machine instructions and grouping those together into packets. > The VLIW packetizer in LLVM is implemented as follows: > > Implementation Details: > > 1. The VLIW packetizer is implemented after all target specific passes are > run. This ensures that all pseudo instructions and spill code is enumerated > before packetization. > > 2. The VLIW packetizer extends "ScheduleDAGInstrs" class. The Packetizer > uses "BuildSchedGraph" API to build dependence graph. The dependence graph > along with deterministic finite automaton (DFA) is used to group independent > instructions into packets. > > 3. The instruction packets are finalized using "finalizeBundle" API. This > API inserts BUNDLE instructions and updates each packet instruction with > "insideBundle" bit. > > 4. The Hexagon backend assembly printer is updated to handle BUNDLE > instruction and print packet semantics correctly. Other VLIW targets will > also have to update the assembly printer. > > The VLIW packetizer roughly implements the following algorithm: > > 1 Instantiate DFA resource tracker > 2 For all basic blocks (BB) in Machine Function > 3 do > 4 reset DFA > 5 CurrentPacket = {} > 6 For all machine instructions (I) in BB > 7 do > 8 avail = DFA.IsAvailable(I) > 9 if (avail == true) { > 10 For all machine instructions (Ip) in CurrentPacket > 11 do > 12 if (DependenceGraph.HasDependence(I, Ip)) { > 13 if (Target.CanPruneDependence(I, Ip)) { > 14 // End current packet > 15 finalizeBundle > 16 reset DFA > 17 reset CurrentPacket > 18 } > 19 } > 20 done > 21 } > 22 else { > 23 // End current packet > 24 finalizeBundle > 25 reset DFA > 26 reset CurrentPacket > 27 } > 28 > 29 // Add I to CurrentPacket > 30 CurrentPacket.Add(I) > 31 done > 32 done > > I have already verified that it builds and runs regression test suites clean > on x86. I attaching the initial patch for review and comments. It's nice that you're generalizing the implementation so that it can be extended later and serve as a starting point for similar targets. I understand you've put a lot of work into that aspect. However, it's also important to keep different features of the code generator self contained. For example, we should only add hooks to common target headers when they're generally applicable, and not specific to VLIW support. It's also important to have a consistent scheduling/bundling strategy in the target independent code. Eventually, Hexagon will have to move to the new scheudling/bundling framework. Until then, the inconsistent bits (i.e. packetizing late) need to be confined to the Hexagon target. Let me set a few specific goals for this patch: 1. Don't touch TargetInstrInfo.h. Only the scheduler or packetizer itself should include ScheduleDAG.h. If we need to later, we can make the packetizer extensible by providing hook within the packetizer itself. Other targets can implement the packetizer interface to exploit those hooks. 2. Don't touch LLVMTargetMachine.cpp. We have a preEmit hook already that will work for you. For now, you can keep your command line options target-local. Later we can share the option across multiple targets of it makes sense. TargetPassConfig will handle that. It's not something you need to worry about now. 3. Don't add any new target-independent passes. It's good to provide stand alone utilties that can be used by multiple targets, such as DFAPacketizer and VLIWScheduler. However, I don't see much value in providing a driver loop that can be shared across targets. Targets provide their own scheduling/packetizing pass and share various scheduling utilties bottom-up. In particular, a target can extend ScheduleDAGInstrs or DFAPacketizer within it own pass. If we see that multiple targets really do need a pass that runs at the same time with identical drivers, then we can consider declaring it a "target-independent" pass at that time. I realize there's existing code that doesn't necessarily follow this strategy. We're working on cleaning it up, so it's particularly important not exacerbate the problem at this time. Here's my suggestion for now. Any code that should be shared by multiple targets that both use DFAPacketizer can go in DFAPacketizer.(h|cpp). For example, you can put the VLIWPacketizerList subclass of ScheduleDAGInstrs there. I don't see anything in VLIWPacketizerList that's inconstitent with the general MachineInstrBundle design. You can then create a new HexagonVLIWPacketizer pass within your target and add it during preEmit. -Andy From craig.topper at gmail.com Mon Feb 6 20:50:20 2012 From: craig.topper at gmail.com (Craig Topper) Date: Tue, 07 Feb 2012 02:50:20 -0000 Subject: [llvm-commits] [llvm] r149961 - in /llvm/trunk/lib/Target: ARM/ ARM/AsmParser/ ARM/Disassembler/ ARM/InstPrinter/ ARM/MCTargetDesc/ CellSPU/ CppBackend/ Hexagon/ MBlaze/ MBlaze/MCTargetDesc/ MSP430/ Mips/ Mips/InstPrinter/ PTX/ PowerPC/ PowerPC/InstPrinter/ PowerPC/MCTargetDesc/ Sparc/ Message-ID: <20120207025021.D26142A6C12C@llvm.org> Author: ctopper Date: Mon Feb 6 20:50:20 2012 New Revision: 149961 URL: http://llvm.org/viewvc/llvm-project?rev=149961&view=rev Log: Convert assert(0) to llvm_unreachable Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp llvm/trunk/lib/Target/ARM/ARMELFWriterInfo.cpp llvm/trunk/lib/Target/ARM/ARMFastISel.cpp llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp llvm/trunk/lib/Target/MBlaze/MBlazeMCInstLower.cpp llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp llvm/trunk/lib/Target/MSP430/MSP430MCInstLower.cpp llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMAsmPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -84,6 +84,7 @@ void EmitTextAttribute(unsigned Attribute, StringRef String) { switch (Attribute) { + default: llvm_unreachable("Unsupported Text attribute in ASM Mode"); case ARMBuildAttrs::CPU_name: Streamer.EmitRawText(StringRef("\t.cpu ") + String.lower()); break; @@ -92,7 +93,6 @@ case ARMBuildAttrs::VFP_arch: Streamer.EmitRawText(StringRef("\t.fpu ") + String.lower()); break; - default: assert(0 && "Unsupported Text attribute in ASM Mode"); break; } } void Finish() { } @@ -196,6 +196,7 @@ AttributeItemType item = Contents[i]; Streamer.EmitULEB128IntValue(item.Tag, 0); switch (item.Type) { + default: llvm_unreachable("Invalid attribute type"); case AttributeItemType::NumericAttribute: Streamer.EmitULEB128IntValue(item.IntValue, 0); break; @@ -203,8 +204,6 @@ Streamer.EmitBytes(item.StringValue.upper(), 0); Streamer.EmitIntValue(0, 1); // '\0' break; - default: - assert(0 && "Invalid attribute type"); } } @@ -331,8 +330,7 @@ unsigned TF = MO.getTargetFlags(); switch (MO.getType()) { - default: - assert(0 && ""); + default: llvm_unreachable(""); case MachineOperand::MO_Register: { unsigned Reg = MO.getReg(); assert(TargetRegisterInfo::isPhysicalRegister(Reg)); @@ -1118,7 +1116,7 @@ switch (Opc) { default: MI->dump(); - assert(0 && "Unsupported opcode for unwinding information"); + llvm_unreachable("Unsupported opcode for unwinding information"); case ARM::tPUSH: // Special case here: no src & dst reg, but two extra imp ops. StartOp = 2; NumOffset = 2; @@ -1147,7 +1145,7 @@ switch (Opc) { default: MI->dump(); - assert(0 && "Unsupported opcode for unwinding information"); + llvm_unreachable("Unsupported opcode for unwinding information"); case ARM::MOVr: case ARM::tMOVr: Offset = 0; @@ -1194,16 +1192,16 @@ OutStreamer.EmitPad(Offset); } else { MI->dump(); - assert(0 && "Unsupported opcode for unwinding information"); + llvm_unreachable("Unsupported opcode for unwinding information"); } } else if (DstReg == ARM::SP) { // FIXME: .movsp goes here MI->dump(); - assert(0 && "Unsupported opcode for unwinding information"); + llvm_unreachable("Unsupported opcode for unwinding information"); } else { MI->dump(); - assert(0 && "Unsupported opcode for unwinding information"); + llvm_unreachable("Unsupported opcode for unwinding information"); } } } @@ -1232,7 +1230,7 @@ // Check for manual lowerings. unsigned Opc = MI->getOpcode(); switch (Opc) { - case ARM::t2MOVi32imm: assert(0 && "Should be lowered by thumb2it pass"); + case ARM::t2MOVi32imm: llvm_unreachable("Should be lowered by thumb2it pass"); case ARM::DBG_VALUE: { if (isVerbose() && OutStreamer.hasRawTextSupport()) { SmallString<128> TmpStr; Modified: llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMBaseInstrInfo.cpp Mon Feb 6 20:50:20 2012 @@ -156,9 +156,7 @@ unsigned OffImm = MI->getOperand(NumOps-2).getImm(); ARMCC::CondCodes Pred = (ARMCC::CondCodes)MI->getOperand(NumOps-1).getImm(); switch (AddrMode) { - default: - assert(false && "Unknown indexed op!"); - return NULL; + default: llvm_unreachable("Unknown indexed op!"); case ARMII::AddrMode2: { bool isSub = ARM_AM::getAM2Op(OffImm) == ARM_AM::sub; unsigned Amt = ARM_AM::getAM2Offset(OffImm); Modified: llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMConstantPoolValue.cpp Mon Feb 6 20:50:20 2012 @@ -62,8 +62,7 @@ int ARMConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { - assert(false && "Shouldn't be calling this directly!"); - return -1; + llvm_unreachable("Shouldn't be calling this directly!"); } void Modified: llvm/trunk/lib/Target/ARM/ARMELFWriterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMELFWriterInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMELFWriterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMELFWriterInfo.cpp Mon Feb 6 20:50:20 2012 @@ -41,8 +41,8 @@ case ARM::reloc_arm_machine_cp_entry: case ARM::reloc_arm_jt_base: case ARM::reloc_arm_pic_jt: - assert(0 && "unsupported ARM relocation type"); return 0; - + llvm_unreachable("unsupported ARM relocation type"); + case ARM::reloc_arm_branch: return ELF::R_ARM_CALL; case ARM::reloc_arm_movt: return ELF::R_ARM_MOVT_ABS; case ARM::reloc_arm_movw: return ELF::R_ARM_MOVW_ABS_NC; @@ -53,30 +53,26 @@ long int ARMELFWriterInfo::getDefaultAddendForRelTy(unsigned RelTy, long int Modifier) const { - assert(0 && "ARMELFWriterInfo::getDefaultAddendForRelTy() not implemented"); - return 0; + llvm_unreachable("ARMELFWriterInfo::getDefaultAddendForRelTy() not " + "implemented"); } unsigned ARMELFWriterInfo::getRelocationTySize(unsigned RelTy) const { - assert(0 && "ARMELFWriterInfo::getRelocationTySize() not implemented"); - return 0; + llvm_unreachable("ARMELFWriterInfo::getRelocationTySize() not implemented"); } bool ARMELFWriterInfo::isPCRelativeRel(unsigned RelTy) const { - assert(0 && "ARMELFWriterInfo::isPCRelativeRel() not implemented"); - return 1; + llvm_unreachable("ARMELFWriterInfo::isPCRelativeRel() not implemented"); } unsigned ARMELFWriterInfo::getAbsoluteLabelMachineRelTy() const { - assert(0 && - "ARMELFWriterInfo::getAbsoluteLabelMachineRelTy() not implemented"); - return 0; + llvm_unreachable("ARMELFWriterInfo::getAbsoluteLabelMachineRelTy() not " + "implemented"); } long int ARMELFWriterInfo::computeRelocation(unsigned SymOffset, unsigned RelOffset, unsigned RelTy) const { - assert(0 && - "ARMELFWriterInfo::getAbsoluteLabelMachineRelTy() not implemented"); - return 0; + llvm_unreachable("ARMELFWriterInfo::getAbsoluteLabelMachineRelTy() not " + "implemented"); } Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Mon Feb 6 20:50:20 2012 @@ -881,9 +881,7 @@ bool needsLowering = false; switch (VT.getSimpleVT().SimpleTy) { - default: - assert(false && "Unhandled load/store type!"); - break; + default: llvm_unreachable("Unhandled load/store type!"); case MVT::i1: case MVT::i8: case MVT::i16: Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Mon Feb 6 20:50:20 2012 @@ -2361,8 +2361,7 @@ SDValue Ops[] = { FalseVal, TrueVal, Tmp2, CCR, InFlag }; unsigned Opc = 0; switch (VT.getSimpleVT().SimpleTy) { - default: assert(false && "Illegal conditional move type!"); - break; + default: llvm_unreachable("Illegal conditional move type!"); case MVT::i32: Opc = Subtarget->isThumb() ? (Subtarget->hasThumb2() ? ARM::t2MOVCCr : ARM::tMOVCCr_pseudo) Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -3070,8 +3070,7 @@ unsigned Opc; switch (Op.getOpcode()) { - default: - assert(0 && "Invalid opcode!"); + default: llvm_unreachable("Invalid opcode!"); case ISD::FP_TO_SINT: Opc = ARMISD::FTOSI; break; @@ -3101,8 +3100,7 @@ unsigned CastOpc; unsigned Opc; switch (Op.getOpcode()) { - default: - assert(0 && "Invalid opcode!"); + default: llvm_unreachable("Invalid opcode!"); case ISD::SINT_TO_FP: CastOpc = ISD::SIGN_EXTEND; Opc = ISD::SINT_TO_FP; @@ -3126,8 +3124,7 @@ unsigned Opc; switch (Op.getOpcode()) { - default: - assert(0 && "Invalid opcode!"); + default: llvm_unreachable("Invalid opcode!"); case ISD::SINT_TO_FP: Opc = ARMISD::SITOF; break; @@ -4957,7 +4954,7 @@ unsigned Opc; bool ExtraOp = false; switch (Op.getOpcode()) { - default: assert(0 && "Invalid code"); + default: llvm_unreachable("Invalid code"); case ISD::ADDC: Opc = ARMISD::ADDC; break; case ISD::ADDE: Opc = ARMISD::ADDE; ExtraOp = true; break; case ISD::SUBC: Opc = ARMISD::SUBC; break; @@ -6667,7 +6664,7 @@ case MVT::i16: widenType = MVT::getVectorVT(MVT::i32, numElem); break; case MVT::i32: widenType = MVT::getVectorVT(MVT::i64, numElem); break; default: - assert(0 && "Invalid vector element type for padd optimization."); + llvm_unreachable("Invalid vector element type for padd optimization."); } SDValue tmp = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, N->getDebugLoc(), @@ -7332,7 +7329,7 @@ if (isIntrinsic) { unsigned IntNo = cast(N->getOperand(1))->getZExtValue(); switch (IntNo) { - default: assert(0 && "unexpected intrinsic for Neon base update"); + default: llvm_unreachable("unexpected intrinsic for Neon base update"); case Intrinsic::arm_neon_vld1: NewOpc = ARMISD::VLD1_UPD; NumVecs = 1; break; case Intrinsic::arm_neon_vld2: NewOpc = ARMISD::VLD2_UPD; @@ -7365,7 +7362,7 @@ } else { isLaneOp = true; switch (N->getOpcode()) { - default: assert(0 && "unexpected opcode for Neon base update"); + default: llvm_unreachable("unexpected opcode for Neon base update"); case ARMISD::VLD2DUP: NewOpc = ARMISD::VLD2DUP_UPD; NumVecs = 2; break; case ARMISD::VLD3DUP: NewOpc = ARMISD::VLD3DUP_UPD; NumVecs = 3; break; case ARMISD::VLD4DUP: NewOpc = ARMISD::VLD4DUP_UPD; NumVecs = 4; break; Modified: llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMMCInstLower.cpp Mon Feb 6 20:50:20 2012 @@ -31,8 +31,7 @@ Expr = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, OutContext); switch (MO.getTargetFlags()) { - default: - assert(0 && "Unknown target flag on symbol operand"); + default: llvm_unreachable("Unknown target flag on symbol operand"); case 0: break; case ARMII::MO_LO16: @@ -67,9 +66,7 @@ bool ARMAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) { switch (MO.getType()) { - default: - assert(0 && "unknown operand type"); - return false; + default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all non-CPSR implicit register operands. if (MO.isImplicit() && MO.getReg() != ARM::CPSR) Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original) +++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Feb 6 20:50:20 2012 @@ -2725,7 +2725,7 @@ if (!ARMMCRegisterClasses[ARM::GPRRegClassID].contains(Reg)) return Reg + 1; switch(Reg) { - default: assert(0 && "Invalid GPR number!"); + default: llvm_unreachable("Invalid GPR number!"); case ARM::R0: return ARM::R1; case ARM::R1: return ARM::R2; case ARM::R2: return ARM::R3; case ARM::R3: return ARM::R4; case ARM::R4: return ARM::R5; case ARM::R5: return ARM::R6; @@ -5222,7 +5222,7 @@ static unsigned getRealVSTOpcode(unsigned Opc, unsigned &Spacing) { switch(Opc) { - default: assert(0 && "unexpected opcode!"); + default: llvm_unreachable("unexpected opcode!"); // VST1LN case ARM::VST1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VST1LNd8_UPD; case ARM::VST1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VST1LNd16_UPD; @@ -5331,7 +5331,7 @@ static unsigned getRealVLDOpcode(unsigned Opc, unsigned &Spacing) { switch(Opc) { - default: assert(0 && "unexpected opcode!"); + default: llvm_unreachable("unexpected opcode!"); // VLD1LN case ARM::VLD1LNdWB_fixed_Asm_8: Spacing = 1; return ARM::VLD1LNd8_UPD; case ARM::VLD1LNdWB_fixed_Asm_16: Spacing = 1; return ARM::VLD1LNd16_UPD; @@ -7022,7 +7022,7 @@ ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(Inst.getOperand(3).getImm()); if (SOpc == ARM_AM::rrx) return false; switch (Inst.getOpcode()) { - default: assert(0 && "unexpected opcode!"); + default: llvm_unreachable("unexpected opcode!"); case ARM::ANDrsi: newOpc = ARM::ANDrr; break; case ARM::ORRrsi: newOpc = ARM::ORRrr; break; case ARM::EORrsi: newOpc = ARM::EORrr; break; Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original) +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb 6 20:50:20 2012 @@ -533,7 +533,7 @@ else if (SymbolicOp.VariantKind == LLVMDisassembler_VariantKind_None) MI.addOperand(MCOperand::CreateExpr(Expr)); else - assert(0 && "bad SymbolicOp.VariantKind"); + llvm_unreachable("bad SymbolicOp.VariantKind"); return true; } Modified: llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -645,7 +645,7 @@ if (getAvailableFeatures() & ARM::FeatureMClass) { switch (Op.getImm()) { - default: assert(0 && "Unexpected mask value!"); + default: llvm_unreachable("Unexpected mask value!"); case 0: O << "apsr"; return; case 1: O << "iapsr"; return; case 2: O << "eapsr"; return; @@ -668,7 +668,7 @@ if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { O << "APSR_"; switch (Mask) { - default: assert(0); + default: llvm_unreachable("Unexpected mask value!"); case 4: O << "g"; return; case 8: O << "nzcvq"; return; case 12: O << "nzcvqg"; return; Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h (original) +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAddressingModes.h Mon Feb 6 20:50:20 2012 @@ -16,6 +16,7 @@ #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include @@ -43,7 +44,7 @@ static inline const char *getShiftOpcStr(ShiftOpc Op) { switch (Op) { - default: assert(0 && "Unknown shift opc!"); + default: llvm_unreachable("Unknown shift opc!"); case ARM_AM::asr: return "asr"; case ARM_AM::lsl: return "lsl"; case ARM_AM::lsr: return "lsr"; @@ -54,7 +55,7 @@ static inline unsigned getShiftOpcEncoding(ShiftOpc Op) { switch (Op) { - default: assert(0 && "Unknown shift opc!"); + default: llvm_unreachable("Unknown shift opc!"); case ARM_AM::asr: return 2; case ARM_AM::lsl: return 0; case ARM_AM::lsr: return 1; @@ -72,7 +73,7 @@ static inline const char *getAMSubModeStr(AMSubMode Mode) { switch (Mode) { - default: assert(0 && "Unknown addressing sub-mode!"); + default: llvm_unreachable("Unknown addressing sub-mode!"); case ARM_AM::ia: return "ia"; case ARM_AM::ib: return "ib"; case ARM_AM::da: return "da"; @@ -569,7 +570,7 @@ } EltBits = 64; } else { - assert(false && "Unsupported NEON immediate"); + llvm_unreachable("Unsupported NEON immediate"); } return Val; } Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp (original) +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp Mon Feb 6 20:50:20 2012 @@ -163,7 +163,7 @@ unsigned Type = 0; if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { - default: assert(0 && "Unimplemented"); + default: llvm_unreachable("Unimplemented"); case FK_Data_4: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); @@ -171,8 +171,7 @@ Type = ELF::R_ARM_REL32; break; case MCSymbolRefExpr::VK_ARM_TLSGD: - assert(0 && "unimplemented"); - break; + llvm_unreachable("unimplemented"); case MCSymbolRefExpr::VK_ARM_GOTTPOFF: Type = ELF::R_ARM_TLS_IE32; break; @@ -248,8 +247,7 @@ case ARM::fixup_arm_thumb_cb: case ARM::fixup_arm_thumb_cp: case ARM::fixup_arm_thumb_br: - assert(0 && "Unimplemented"); - break; + llvm_unreachable("Unimplemented"); case ARM::fixup_arm_uncondbranch: Type = ELF::R_ARM_CALL; break; Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp Mon Feb 6 20:50:20 2012 @@ -166,7 +166,7 @@ SmallVectorImpl &Fixups) const { ARM_AM::AMSubMode Mode = (ARM_AM::AMSubMode)MI.getOperand(OpIdx).getImm(); switch (Mode) { - default: assert(0 && "Unknown addressing sub-mode!"); + default: llvm_unreachable("Unknown addressing sub-mode!"); case ARM_AM::da: return 0; case ARM_AM::ia: return 1; case ARM_AM::db: return 2; @@ -832,7 +832,7 @@ // but this is good enough for now. static bool EvaluateAsPCRel(const MCExpr *Expr) { switch (Expr->getKind()) { - default: assert(0 && "Unexpected expression type"); + default: llvm_unreachable("Unexpected expression type"); case MCExpr::SymbolRef: return false; case MCExpr::Binary: return true; } @@ -856,7 +856,7 @@ MCFixupKind Kind; switch (ARM16Expr->getKind()) { - default: assert(0 && "Unsupported ARMFixup"); + default: llvm_unreachable("Unsupported ARMFixup"); case ARMMCExpr::VK_ARM_HI16: if (!isTargetDarwin() && EvaluateAsPCRel(E)) Kind = MCFixupKind(isThumb2() Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp (original) +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCExpr.cpp Mon Feb 6 20:50:20 2012 @@ -21,7 +21,7 @@ void ARMMCExpr::PrintImpl(raw_ostream &OS) const { switch (Kind) { - default: assert(0 && "Invalid kind!"); + default: llvm_unreachable("Invalid kind!"); case VK_ARM_HI16: OS << ":upper16:"; break; case VK_ARM_LO16: OS << ":lower16:"; break; } @@ -45,8 +45,7 @@ static void AddValueSymbols_(const MCExpr *Value, MCAssembler *Asm) { switch (Value->getKind()) { case MCExpr::Target: - assert(0 && "Can't handle nested target expr!"); - break; + llvm_unreachable("Can't handle nested target expr!"); case MCExpr::Constant: break; Modified: llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/ARM/Thumb1RegisterInfo.cpp Mon Feb 6 20:50:20 2012 @@ -694,7 +694,7 @@ // register. The offset is already handled in the vreg value. MI.getOperand(i+1).ChangeToRegister(FrameReg, false, false, false); } else { - assert(false && "Unexpected opcode!"); + llvm_unreachable("Unexpected opcode!"); } // Add predicate back if it's needed. Modified: llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp (original) +++ llvm/trunk/lib/Target/CellSPU/SPUISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -2033,8 +2033,7 @@ int elt_byte = EltNo * VT.getSizeInBits() / 8; switch (VT.getSimpleVT().SimpleTy) { - default: - assert(false && "Invalid value type!"); + default: llvm_unreachable("Invalid value type!"); case MVT::i8: { prefslot_begin = prefslot_end = 3; break; @@ -2362,8 +2361,7 @@ DebugLoc dl = Op.getDebugLoc(); switch (VT.getSimpleVT().SimpleTy) { - default: - assert(false && "Invalid value type!"); + default: llvm_unreachable("Invalid value type!"); case MVT::i8: { SDValue N = Op.getOperand(0); SDValue Elt0 = DAG.getConstant(0, MVT::i32); Modified: llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp (original) +++ llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp Mon Feb 6 20:50:20 2012 @@ -1356,7 +1356,7 @@ case Instruction::PtrToInt: Out << "PtrToIntInst"; break; case Instruction::IntToPtr: Out << "IntToPtrInst"; break; case Instruction::BitCast: Out << "BitCastInst"; break; - default: assert(0 && "Unreachable"); break; + default: llvm_unreachable("Unreachable"); } Out << "(" << opNames[0] << ", " << getCppName(cst->getType()) << ", \""; Modified: llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonAsmPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -318,14 +318,14 @@ if (Base.isReg()) printOperand(MI, OpNo, O); else - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); if (Offset.isImm()) { if (Offset.getImm()) O << " + #" << Offset.getImm(); } else - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); return false; } @@ -333,7 +333,7 @@ void HexagonAsmPrinter::printPredicateOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O) { - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); } Modified: llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonCFGOptimizer.cpp Mon Feb 6 20:50:20 2012 @@ -84,7 +84,7 @@ break; default: - assert(0 && "Cannot handle this case"); + llvm_unreachable("Cannot handle this case"); } MI->setDesc(QII->get(NewOpcode)); Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonISelDAGToDAG.cpp Mon Feb 6 20:50:20 2012 @@ -1099,7 +1099,7 @@ ReplaceUses(N, RsPd); return RsPd; } - assert(0 && "Unexpected value type"); + llvm_unreachable("Unexpected value type"); } } return SelectCode(N); @@ -1145,7 +1145,7 @@ SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32); Ops.push_back(SDVal); } else { - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); } } EVT ReturnValueVT = N->getValueType(0); Modified: llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -449,7 +449,7 @@ switch (VA.getLocInfo()) { default: // Loc info must be one of Full, SExt, ZExt, or AExt. - assert(0 && "Unknown loc info!"); + llvm_unreachable("Unknown loc info!"); case CCValAssign::Full: break; case CCValAssign::SExt: @@ -1345,12 +1345,12 @@ SDValue HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { - default: assert(0 && "Should not custom lower this!"); + default: llvm_unreachable("Should not custom lower this!"); // Frame & Return address. Currently unimplemented. case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); case ISD::GlobalTLSAddress: - assert(0 && "TLS not implemented for Hexagon."); + llvm_unreachable("TLS not implemented for Hexagon."); case ISD::MEMBARRIER: return LowerMEMBARRIER(Op, DAG); case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG); case ISD::GlobalAddress: return LowerGLOBALADDRESS(Op, DAG); @@ -1382,10 +1382,8 @@ FuncInfo->addAllocaAdjustInst(MI); return BB; } - default: - assert(false && "Unexpected instr type to insert"); + default: llvm_unreachable("Unexpected instr type to insert"); } // switch - return NULL; } //===----------------------------------------------------------------------===// @@ -1401,7 +1399,7 @@ case 'r': // R0-R31 switch (VT.getSimpleVT().SimpleTy) { default: - assert(0 && "getRegForInlineAsmConstraint Unhandled data type"); + llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type"); case MVT::i32: case MVT::i16: case MVT::i8: @@ -1410,7 +1408,7 @@ return std::make_pair(0U, Hexagon::DoubleRegsRegisterClass); } default: - assert(0 && "Unknown asm register class"); + llvm_unreachable("Unknown asm register class"); } } Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Mon Feb 6 20:50:20 2012 @@ -383,7 +383,7 @@ .addFrameIndex(FI).addImm(0) .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO); } else { - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); } } @@ -395,8 +395,7 @@ const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { - assert(0 && "Unimplemented"); - return; + llvm_unreachable("Unimplemented"); } @@ -427,7 +426,7 @@ BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg) .addFrameIndex(FI).addImm(0).addMemOperand(MMO); } else { - assert(0 && "Can't store this register to stack slot"); + llvm_unreachable("Can't store this register to stack slot"); } } @@ -436,7 +435,7 @@ SmallVectorImpl &Addr, const TargetRegisterClass *RC, SmallVectorImpl &NewMIs) const { - assert(0 && "Unimplemented"); + llvm_unreachable("Unimplemented"); } @@ -823,7 +822,7 @@ } else if (MO.isImm()) { MI->getOperand(oper+1).ChangeToImmediate(MO.getImm()); } else { - assert(false && "Unexpected operand type"); + llvm_unreachable("Unexpected operand type"); } } @@ -1269,10 +1268,8 @@ return (Offset >= Hexagon_MEMB_AUTOINC_MIN && Offset <= Hexagon_MEMB_AUTOINC_MAX); } - - assert(0 && "Not an auto-inc opc!"); - return false; + llvm_unreachable("Not an auto-inc opc!"); } Modified: llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonRegisterInfo.cpp Mon Feb 6 20:50:20 2012 @@ -125,7 +125,7 @@ } else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) { // Hexagon_TODO: add code } else { - assert(0 && "Cannot handle this call frame pseudo instruction"); + llvm_unreachable("Cannot handle this call frame pseudo instruction"); } MBB.erase(I); } @@ -305,13 +305,11 @@ } unsigned HexagonRegisterInfo::getEHExceptionRegister() const { - assert(0 && "What is the exception register"); - return 0; + llvm_unreachable("What is the exception register"); } unsigned HexagonRegisterInfo::getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); - return 0; + llvm_unreachable("What is the exception handler register"); } #define GET_REGINFO_TARGET_DESC Modified: llvm/trunk/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeELFWriterInfo.cpp Mon Feb 6 20:50:20 2012 @@ -102,8 +102,6 @@ unsigned RelTy) const { if (RelTy == ELF::R_MICROBLAZE_32_PCREL || ELF::R_MICROBLAZE_64_PCREL) return SymOffset - (RelOffset + 4); - else - assert(0 && "computeRelocation unknown for this relocation type"); - return 0; + llvm_unreachable("computeRelocation unknown for this relocation type"); } Modified: llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -216,7 +216,7 @@ MachineBasicBlock *MBB) const { switch (MI->getOpcode()) { - default: assert(false && "Unexpected instr type to insert"); + default: llvm_unreachable("Unexpected instr type to insert"); case MBlaze::ShiftRL: case MBlaze::ShiftRA: Modified: llvm/trunk/lib/Target/MBlaze/MBlazeMCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MBlazeMCInstLower.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MBlazeMCInstLower.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MBlazeMCInstLower.cpp Mon Feb 6 20:50:20 2012 @@ -85,9 +85,7 @@ MCSymbol *MBlazeMCInstLower:: GetBlockAddressSymbol(const MachineOperand &MO) const { switch (MO.getTargetFlags()) { - default: - assert(0 && "Unknown target flag on GV operand"); - + default: llvm_unreachable("Unknown target flag on GV operand"); case 0: break; } Modified: llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeAsmBackend.cpp Mon Feb 6 20:50:20 2012 @@ -27,7 +27,7 @@ static unsigned getFixupKindSize(unsigned Kind) { switch (Kind) { - default: assert(0 && "invalid fixup kind!"); + default: llvm_unreachable("invalid fixup kind!"); case FK_Data_1: return 1; case FK_PCRel_2: case FK_Data_2: return 2; Modified: llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp (original) +++ llvm/trunk/lib/Target/MBlaze/MCTargetDesc/MBlazeMCCodeEmitter.cpp Mon Feb 6 20:50:20 2012 @@ -54,8 +54,8 @@ static unsigned GetMBlazeRegNum(const MCOperand &MO) { // FIXME: getMBlazeRegisterNumbering() is sufficient? - assert(0 && "MBlazeMCCodeEmitter::GetMBlazeRegNum() not yet implemented."); - return 0; + llvm_unreachable("MBlazeMCCodeEmitter::GetMBlazeRegNum() not yet " + "implemented."); } void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const { Modified: llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430AsmPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -65,7 +65,7 @@ raw_ostream &O, const char *Modifier) { const MachineOperand &MO = MI->getOperand(OpNum); switch (MO.getType()) { - default: assert(0 && "Not implemented yet!"); + default: llvm_unreachable("Not implemented yet!"); case MachineOperand::MO_Register: O << MSP430InstPrinter::getRegisterName(MO.getReg()); return; Modified: llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430ISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -593,8 +593,7 @@ // Expand non-constant shifts to loops: if (!isa(N->getOperand(1))) switch (Opc) { - default: - assert(0 && "Invalid shift opcode!"); + default: llvm_unreachable("Invalid shift opcode!"); case ISD::SHL: return DAG.getNode(MSP430ISD::SHL, dl, VT, N->getOperand(0), N->getOperand(1)); @@ -1022,8 +1021,7 @@ unsigned Opc; const TargetRegisterClass * RC; switch (MI->getOpcode()) { - default: - assert(0 && "Invalid shift opcode!"); + default: llvm_unreachable("Invalid shift opcode!"); case MSP430::Shl8: Opc = MSP430::SHL8r1; RC = MSP430::GR8RegisterClass; Modified: llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430InstrInfo.cpp Mon Feb 6 20:50:20 2012 @@ -130,9 +130,7 @@ MSP430CC::CondCodes CC = static_cast(Cond[0].getImm()); switch (CC) { - default: - assert(0 && "Invalid branch condition!"); - break; + default: llvm_unreachable("Invalid branch condition!"); case MSP430CC::COND_E: CC = MSP430CC::COND_NE; break; @@ -297,8 +295,7 @@ switch (Desc.TSFlags & MSP430II::SizeMask) { default: switch (Desc.getOpcode()) { - default: - assert(0 && "Unknown instruction size!"); + default: llvm_unreachable("Unknown instruction size!"); case TargetOpcode::PROLOG_LABEL: case TargetOpcode::EH_LABEL: case TargetOpcode::IMPLICIT_DEF: @@ -314,8 +311,7 @@ } case MSP430II::SizeSpecial: switch (MI->getOpcode()) { - default: - assert(0 && "Unknown instruction size!"); + default: llvm_unreachable("Unknown instruction size!"); case MSP430::SAR8r1c: case MSP430::SAR16r1c: return 4; Modified: llvm/trunk/lib/Target/MSP430/MSP430MCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MSP430/MSP430MCInstLower.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/MSP430/MSP430MCInstLower.cpp (original) +++ llvm/trunk/lib/Target/MSP430/MSP430MCInstLower.cpp Mon Feb 6 20:50:20 2012 @@ -39,7 +39,7 @@ MCSymbol *MSP430MCInstLower:: GetExternalSymbolSymbol(const MachineOperand &MO) const { switch (MO.getTargetFlags()) { - default: assert(0 && "Unknown target flag on GV operand"); + default: llvm_unreachable("Unknown target flag on GV operand"); case 0: break; } @@ -81,7 +81,7 @@ MCSymbol *MSP430MCInstLower:: GetBlockAddressSymbol(const MachineOperand &MO) const { switch (MO.getTargetFlags()) { - default: assert(0 && "Unknown target flag on GV operand"); + default: llvm_unreachable("Unknown target flag on GV operand"); case 0: break; } @@ -116,7 +116,7 @@ switch (MO.getType()) { default: MI->dump(); - assert(0 && "unknown operand type"); + llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) continue; Modified: llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/Mips/InstPrinter/MipsInstPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -92,7 +92,7 @@ MCSymbolRefExpr::VariantKind Kind = SRE->getKind(); switch (Kind) { - default: assert(0 && "Invalid kind!"); + default: llvm_unreachable("Invalid kind!"); case MCSymbolRefExpr::VK_None: break; case MCSymbolRefExpr::VK_Mips_GPREL: OS << "%gp_rel("; break; case MCSymbolRefExpr::VK_Mips_GOT_CALL: OS << "%call16("; break; Modified: llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -810,9 +810,7 @@ MipsTargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *BB) const { switch (MI->getOpcode()) { - default: - assert(false && "Unexpected instr type to insert"); - return NULL; + default: llvm_unreachable("Unexpected instr type to insert"); case Mips::ATOMIC_LOAD_ADD_I8: case Mips::ATOMIC_LOAD_ADD_I8_P8: return EmitAtomicBinaryPartword(MI, BB, 1, Mips::ADDu); Modified: llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp (original) +++ llvm/trunk/lib/Target/Mips/MipsMCInstLower.cpp Mon Feb 6 20:50:20 2012 @@ -37,7 +37,7 @@ const MCSymbol *Symbol; switch(MO.getTargetFlags()) { - default: assert(0 && "Invalid target flag!"); + default: llvm_unreachable("Invalid target flag!"); case MipsII::MO_NO_FLAG: Kind = MCSymbolRefExpr::VK_None; break; case MipsII::MO_GPREL: Kind = MCSymbolRefExpr::VK_Mips_GPREL; break; case MipsII::MO_GOT_CALL: Kind = MCSymbolRefExpr::VK_Mips_GOT_CALL; break; @@ -176,9 +176,7 @@ MachineOperandType MOTy = MO.getType(); switch (MOTy) { - default: - assert(0 && "unknown operand type"); - break; + default: llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: // Ignore all implicit register operands. if (MO.isImplicit()) break; @@ -315,7 +313,7 @@ } default: // FIXME: need to add others - assert(0 && "unaligned instruction not processed"); + llvm_unreachable("unaligned instruction not processed"); } MCInsts.push_back(Instr1); Modified: llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXInstrInfo.cpp Mon Feb 6 20:50:20 2012 @@ -300,7 +300,7 @@ unsigned SrcReg, bool isKill, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { - assert(false && "storeRegToStackSlot should not be called for PTX"); + llvm_unreachable("storeRegToStackSlot should not be called for PTX"); } void PTXInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, @@ -308,7 +308,7 @@ unsigned DestReg, int FrameIdx, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const { - assert(false && "loadRegFromStackSlot should not be called for PTX"); + llvm_unreachable("loadRegFromStackSlot should not be called for PTX"); } // static helper routines Modified: llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/InstPrinter/PPCInstPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -174,7 +174,7 @@ unsigned CCReg = MI->getOperand(OpNo).getReg(); unsigned RegNo; switch (CCReg) { - default: assert(0 && "Unknown CR register"); + default: llvm_unreachable("Unknown CR register"); case PPC::CR0: RegNo = 0; break; case PPC::CR1: RegNo = 1; break; case PPC::CR2: RegNo = 2; break; Modified: llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp Mon Feb 6 20:50:20 2012 @@ -92,14 +92,13 @@ const MCInstFragment *DF, const MCAsmLayout &Layout) const { // FIXME. - assert(0 && "relaxInstruction() unimplemented"); - return false; + llvm_unreachable("relaxInstruction() unimplemented"); } void relaxInstruction(const MCInst &Inst, MCInst &Res) const { // FIXME. - assert(0 && "relaxInstruction() unimplemented"); + llvm_unreachable("relaxInstruction() unimplemented"); } bool writeNopData(uint64_t Count, MCObjectWriter *OW) const { @@ -128,7 +127,7 @@ void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize, uint64_t Value) const { - assert(0 && "UNIMP"); + llvm_unreachable("UNIMP"); } MCObjectWriter *createObjectWriter(raw_ostream &OS) const { Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Mon Feb 6 20:50:20 2012 @@ -4578,8 +4578,7 @@ DebugLoc dl = N->getDebugLoc(); switch (N->getOpcode()) { default: - assert(false && "Do not know how to custom type legalize this operation!"); - return; + llvm_unreachable("Do not know how to custom type legalize this operation!"); case ISD::VAARG: { if (!TM.getSubtarget().isSVR4ABI() || TM.getSubtarget().isPPC64()) Modified: llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCMCInstLower.cpp Mon Feb 6 20:50:20 2012 @@ -140,7 +140,7 @@ switch (MO.getType()) { default: MI->dump(); - assert(0 && "unknown operand type"); + llvm_unreachable("unknown operand type"); case MachineOperand::MO_Register: assert(!MO.getSubReg() && "Subregs should be eliminated!"); MCOp = MCOperand::CreateReg(MO.getReg()); Modified: llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp?rev=149961&r1=149960&r2=149961&view=diff ============================================================================== --- llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/Sparc/SparcAsmPrinter.cpp Mon Feb 6 20:50:20 2012 @@ -142,7 +142,7 @@ std::string operand = ""; const MachineOperand &MO = MI->getOperand(opNum); switch (MO.getType()) { - default: assert(0 && "Operand is not a register "); + default: llvm_unreachable("Operand is not a register"); case MachineOperand::MO_Register: assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) && "Operand is not a physical register "); From kledzik at apple.com Mon Feb 6 20:59:54 2012 From: kledzik at apple.com (Nick Kledzik) Date: Tue, 07 Feb 2012 02:59:54 -0000 Subject: [llvm-commits] [lld] r149962 - in /lld/trunk: include/lld/Core/Atom.h include/lld/Core/NativeReader.h include/lld/Core/UndefinedAtom.h lib/Core/NativeFileFormat.h lib/Core/NativeReader.cpp lib/Core/NativeWriter.cpp lib/Core/Resolver.cpp lib/Core/YamlKeyValues.cpp lib/Core/YamlKeyValues.h lib/Core/YamlReader.cpp lib/Core/YamlWriter.cpp test/undef-coalesce.objtxt tools/lld-core/lld-core.cpp Message-ID: <20120207025954.B290B2A6C12C@llvm.org> Author: kledzik Date: Mon Feb 6 20:59:54 2012 New Revision: 149962 URL: http://llvm.org/viewvc/llvm-project?rev=149962&view=rev Log: Add support for UndefinedAtom in yaml and native format. Add test cases with undefined atoms Added: lld/trunk/test/undef-coalesce.objtxt Modified: lld/trunk/include/lld/Core/Atom.h lld/trunk/include/lld/Core/NativeReader.h lld/trunk/include/lld/Core/UndefinedAtom.h lld/trunk/lib/Core/NativeFileFormat.h lld/trunk/lib/Core/NativeReader.cpp lld/trunk/lib/Core/NativeWriter.cpp lld/trunk/lib/Core/Resolver.cpp lld/trunk/lib/Core/YamlKeyValues.cpp lld/trunk/lib/Core/YamlKeyValues.h lld/trunk/lib/Core/YamlReader.cpp lld/trunk/lib/Core/YamlWriter.cpp lld/trunk/tools/lld-core/lld-core.cpp Modified: lld/trunk/include/lld/Core/Atom.h URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/Atom.h?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/include/lld/Core/Atom.h (original) +++ lld/trunk/include/lld/Core/Atom.h Mon Feb 6 20:59:54 2012 @@ -20,6 +20,7 @@ class File; class DefinedAtom; +class UndefinedAtom; /// /// The linker has a Graph Theory model of linking. An object file is seen @@ -53,6 +54,10 @@ /// returns atom cast to DefinedAtom*, else returns nullptr; virtual const DefinedAtom* definedAtom() const { return 0; } + /// undefinedAtom - like dynamic_cast, if atom is definitionUndefined + /// returns atom cast to UndefinedAtom*, else returns NULL; + virtual const UndefinedAtom* undefinedAtom() const { return NULL; } + protected: /// Atom is an abstract base class. Only subclasses can access constructor. Atom() {} Modified: lld/trunk/include/lld/Core/NativeReader.h URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/NativeReader.h?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/include/lld/Core/NativeReader.h (original) +++ lld/trunk/include/lld/Core/NativeReader.h Mon Feb 6 20:59:54 2012 @@ -12,6 +12,8 @@ #include "lld/Core/File.h" +#include "llvm/ADT/OwningPtr.h" + #include "llvm/Support/system_error.h" #include @@ -26,13 +28,14 @@ /// parseNativeObjectFileOrSTDIN - Open the specified native object file (use /// stdin if the path is "-") and instantiate into an lld::File object. llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path - , File*&); + , llvm::OwningPtr& result); /// parseNativeObjectFile - Parse the specified native object file /// (in a buffer) and instantiate into an lld::File object. - llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb, - llvm::StringRef path, File*& result); + llvm::error_code parseNativeObjectFile(llvm::OwningPtr& mb + ,llvm::StringRef path + ,llvm::OwningPtr& result); } // namespace lld Modified: lld/trunk/include/lld/Core/UndefinedAtom.h URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/UndefinedAtom.h?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/include/lld/Core/UndefinedAtom.h (original) +++ lld/trunk/include/lld/Core/UndefinedAtom.h Mon Feb 6 20:59:54 2012 @@ -20,31 +20,22 @@ /// It exists as a place holder for a future atom. class UndefinedAtom : public Atom { public: - UndefinedAtom(llvm::StringRef nm, bool weakImport, const File& f) - : _name(nm), _file(f), _weakImport(weakImport) {} - - virtual const File& file() const { - return _file; - } - - virtual llvm::StringRef name() const { - return _name; - } - virtual Definition definition() const { return Atom::definitionUndefined; } - virtual bool weakImport() const { - return _weakImport; + /// like dynamic_cast, if atom is definitionUndefined + /// returns atom cast to UndefinedAtom*, else returns NULL + virtual const UndefinedAtom* undefinedAtom() const { + return this; } + /// returns if undefined symbol can be missing at runtime + virtual bool weakImport() const = 0; + protected: + UndefinedAtom() {} virtual ~UndefinedAtom() {} - - llvm::StringRef _name; - const File& _file; - bool _weakImport; }; } // namespace lld Modified: lld/trunk/lib/Core/NativeFileFormat.h URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeFileFormat.h?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/NativeFileFormat.h (original) +++ lld/trunk/lib/Core/NativeFileFormat.h Mon Feb 6 20:59:54 2012 @@ -88,9 +88,10 @@ enum NativeChunkSignatures { NCS_DefinedAtomsV1 = 1, NCS_AttributesArrayV1 = 2, - NCS_Content = 3, + NCS_UndefinedAtomsV1 = 3, NCS_Strings = 4, - NCS_ReferencesArray = 5, + NCS_Content = 5, + NCS_ReferencesArray = 6, }; // @@ -152,6 +153,16 @@ +// +// The NCS_UndefinedAtomsV1 chunk contains an array of these structs +// +struct NativeUndefinedAtomIvarsV1 { + uint32_t nameOffset; + uint32_t flags; +}; + + + Modified: lld/trunk/lib/Core/NativeReader.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeReader.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/NativeReader.cpp (original) +++ lld/trunk/lib/Core/NativeReader.cpp Mon Feb 6 20:59:54 2012 @@ -65,7 +65,8 @@ } virtual DefinedAtom::ContentType contentType() const { - return (DefinedAtom::ContentType)(attributes().contentType); + const NativeAtomAttributesV1& attr = attributes(); + return (DefinedAtom::ContentType)(attr.contentType); } virtual DefinedAtom::Alignment alignment() const { @@ -113,6 +114,29 @@ +// +// An object of this class is instantied for each NativeUndefinedAtomIvarsV1 +// struct in the NCS_UndefinedAtomsV1 chunk. +// +class NativeUndefinedAtomV1 : public UndefinedAtom { +public: + NativeUndefinedAtomV1(const NativeFile& f, + const NativeUndefinedAtomIvarsV1* ivarData) + : _file(&f), _ivarData(ivarData) { } + + virtual const File& file() const; + virtual llvm::StringRef name() const; + + virtual bool weakImport() const { + return (_ivarData->flags & 0x1); + } + +private: + const NativeFile* _file; + const NativeUndefinedAtomIvarsV1* _ivarData; +}; + + // // lld::File object for native llvm object file @@ -122,8 +146,9 @@ /// Instantiates a File object from a native object file. Ownership /// of the MemoryBuffer is transfered to the resulting File object. - static llvm::error_code make(llvm::MemoryBuffer* mb, llvm::StringRef path, - File*& result) { + static llvm::error_code make(llvm::OwningPtr& mb, + llvm::StringRef path, + llvm::OwningPtr& result) { const uint8_t* const base = reinterpret_cast(mb->getBufferStart()); const NativeFileHeader* const header = @@ -159,6 +184,9 @@ case NCS_AttributesArrayV1: ec = file->processAttributesV1(base, chunk); break; + case NCS_UndefinedAtomsV1: + ec = file->processUndefinedAtomsV1(base, chunk); + break; case NCS_Content: ec = file->processContent(base, chunk); break; @@ -175,7 +203,7 @@ // TO DO: validate enough chunks were used - result = file; + result.reset(file); } @@ -183,13 +211,14 @@ } virtual ~NativeFile() { - // The NativeFile owns the MemoryBuffer and must not delete it. - delete _buffer; + // _buffer is automatically deleted because of OwningPtr<> + // All other ivar pointers are pointers into the MemoryBuffer, except // the _definedAtoms array which was allocated to contain an array // of Atom objects. The atoms have empty destructors, so it is ok // to just delete the memory. delete _definedAtoms.arrayStart; + delete _undefinedAtoms.arrayStart; } // visits each atom in the file @@ -199,6 +228,11 @@ const DefinedAtom* atom = reinterpret_cast(p); handler.doDefinedAtom(*atom); } + for(const uint8_t* p=_undefinedAtoms.arrayStart; p != _undefinedAtoms.arrayEnd; + p += _undefinedAtoms.elementSize) { + const UndefinedAtom* atom = reinterpret_cast(p); + handler.doUndefinedAtom(*atom); + } return (_definedAtoms.arrayStart != _definedAtoms.arrayEnd); } @@ -210,6 +244,7 @@ private: friend class NativeDefinedAtomV1; + friend class NativeUndefinedAtomV1; // instantiate array of DefinedAtoms from v1 ivar data in file llvm::error_code processDefinedAtomsV1(const uint8_t* base, @@ -247,6 +282,34 @@ return make_error_code(native_reader_error::success); } + llvm::error_code processUndefinedAtomsV1(const uint8_t* base, + const NativeChunk* chunk) { + const size_t atomSize = sizeof(NativeUndefinedAtomV1); + size_t atomsArraySize = chunk->elementCount * atomSize; + uint8_t* atomsStart = reinterpret_cast + (operator new(atomsArraySize, std::nothrow)); + if (atomsStart == NULL ) + return make_error_code(native_reader_error::memory_error); + const size_t ivarElementSize = chunk->fileSize + / chunk->elementCount; + if ( ivarElementSize != sizeof(NativeUndefinedAtomIvarsV1) ) + return make_error_code(native_reader_error::file_malformed); + uint8_t* atomsEnd = atomsStart + atomsArraySize; + const NativeUndefinedAtomIvarsV1* ivarData = + reinterpret_cast + (base + chunk->fileOffset); + for(uint8_t* s = atomsStart; s != atomsEnd; s += atomSize) { + NativeUndefinedAtomV1* atomAllocSpace = + reinterpret_cast(s); + new (atomAllocSpace) NativeUndefinedAtomV1(*this, ivarData); + ++ivarData; + } + this->_undefinedAtoms.arrayStart = atomsStart; + this->_undefinedAtoms.arrayEnd = atomsEnd; + this->_undefinedAtoms.elementSize = atomSize; + return make_error_code(native_reader_error::success); + } + // set up pointers to string pool in file llvm::error_code processStrings(const uint8_t* base, const NativeChunk* chunk) { @@ -281,12 +344,18 @@ // private constructor, only called by make() - NativeFile(llvm::MemoryBuffer* mb, llvm::StringRef path) : - lld::File(path), _buffer(mb), _header(NULL), - _strings(NULL), _stringsMaxOffset(0), - _contentStart(NULL), _contentEnd(NULL) + NativeFile(llvm::OwningPtr& mb, llvm::StringRef path) : + lld::File(path), + _buffer(mb.take()), // NativeFile now takes ownership of buffer + _header(NULL), + _strings(NULL), + _stringsMaxOffset(0), + _contentStart(NULL), + _contentEnd(NULL) { - _header = reinterpret_cast(mb->getBufferStart()); + _header = reinterpret_cast(_buffer->getBufferStart()); + _definedAtoms.arrayStart = NULL; + _undefinedAtoms.arrayStart = NULL; } struct AtomArray { @@ -297,9 +366,10 @@ uint32_t elementSize; }; - llvm::MemoryBuffer* _buffer; + llvm::OwningPtr _buffer; const NativeFileHeader* _header; AtomArray _definedAtoms; + AtomArray _undefinedAtoms; const uint8_t* _attributes; uint32_t _attributesMaxOffset; const char* _strings; @@ -342,11 +412,24 @@ + +inline const class File& NativeUndefinedAtomV1::file() const { + return *_file; +} + +inline llvm::StringRef NativeUndefinedAtomV1::name() const { + return _file->string(_ivarData->nameOffset); +} + + + + // // Instantiate an lld::File from the given native object file buffer // -llvm::error_code parseNativeObjectFile(llvm::MemoryBuffer* mb, - llvm::StringRef path, File*& result) { +llvm::error_code parseNativeObjectFile(llvm::OwningPtr& mb, + llvm::StringRef path, + llvm::OwningPtr& result) { return NativeFile::make(mb, path, result); } @@ -356,13 +439,13 @@ // Instantiate an lld::File from the given native object file path // llvm::error_code parseNativeObjectFileOrSTDIN(llvm::StringRef path, - File*& result) { + llvm::OwningPtr& result) { llvm::OwningPtr mb; llvm::error_code ec = llvm::MemoryBuffer::getFileOrSTDIN(path, mb); if ( ec ) return ec; - return parseNativeObjectFile(mb.take(), path, result); + return parseNativeObjectFile(mb, path, result); } Modified: lld/trunk/lib/Core/NativeWriter.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/NativeWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/NativeWriter.cpp (original) +++ lld/trunk/lib/Core/NativeWriter.cpp Mon Feb 6 20:59:54 2012 @@ -44,10 +44,13 @@ if (!_attributes.empty()) out.write((char*)&_attributes[0], _attributes.size()*sizeof(NativeAtomAttributesV1)); - if (!_contentPool.empty()) - out.write((char*)&_contentPool[0], _contentPool.size()); + if ( !_undefinedAtomIvars.empty() ) + out.write((char*)&_undefinedAtomIvars[0], + _undefinedAtomIvars.size()*sizeof(NativeUndefinedAtomIvarsV1)); if (!_stringPool.empty()) out.write(&_stringPool[0], _stringPool.size()); + if (!_contentPool.empty()) + out.write((char*)&_contentPool[0], _contentPool.size()); } private: @@ -64,15 +67,22 @@ // visitor routine called by forEachAtom() virtual void doUndefinedAtom(const class UndefinedAtom& atom) { + NativeUndefinedAtomIvarsV1 ivar; + ivar.nameOffset = getNameOffset(atom); + ivar.flags = (atom.weakImport() ? 1 : 0); + _undefinedAtomIvars.push_back(ivar); } // visitor routine called by forEachAtom() virtual void doFile(const class File &) { } - + // fill out native file header and chunk directory void makeHeader() { - _headerBufferSize = sizeof(NativeFileHeader) + 4*sizeof(NativeChunk); + const bool hasUndefines = !_undefinedAtomIvars.empty(); + const int chunkCount = hasUndefines ? 5 : 4; + _headerBufferSize = sizeof(NativeFileHeader) + + chunkCount*sizeof(NativeChunk); _headerBuffer = reinterpret_cast (operator new(_headerBufferSize, std::nothrow)); NativeChunk *chunks = @@ -82,39 +92,59 @@ _headerBuffer->endian = NFH_LittleEndian; _headerBuffer->architecture = 0; _headerBuffer->fileSize = 0; - _headerBuffer->chunkCount = 4; + _headerBuffer->chunkCount = chunkCount; + // create chunk for atom ivar array - NativeChunk& ch0 = chunks[0]; - ch0.signature = NCS_DefinedAtomsV1; - ch0.fileOffset = _headerBufferSize; - ch0.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1); - ch0.elementCount = _definedAtomIvars.size(); - // create chunk for attributes - NativeChunk& ch1 = chunks[1]; - ch1.signature = NCS_AttributesArrayV1; - ch1.fileOffset = ch0.fileOffset + ch0.fileSize; - ch1.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1); - ch1.elementCount = _attributes.size(); - // create chunk for content - NativeChunk& ch2 = chunks[2]; - ch2.signature = NCS_Content; - ch2.fileOffset = ch1.fileOffset + ch1.fileSize; - ch2.fileSize = _contentPool.size(); - ch2.elementCount = _contentPool.size(); + int nextIndex = 0; + NativeChunk& chd = chunks[nextIndex++]; + chd.signature = NCS_DefinedAtomsV1; + chd.fileOffset = _headerBufferSize; + chd.fileSize = _definedAtomIvars.size()*sizeof(NativeDefinedAtomIvarsV1); + chd.elementCount = _definedAtomIvars.size(); + uint32_t nextFileOffset = chd.fileOffset + chd.fileSize; + + // create chunk for attributes + NativeChunk& cha = chunks[nextIndex++]; + cha.signature = NCS_AttributesArrayV1; + cha.fileOffset = nextFileOffset; + cha.fileSize = _attributes.size()*sizeof(NativeAtomAttributesV1); + cha.elementCount = _attributes.size(); + nextFileOffset = cha.fileOffset + cha.fileSize; + + // create chunk for undefined atom array + if ( hasUndefines ) { + NativeChunk& chu = chunks[nextIndex++]; + chu.signature = NCS_UndefinedAtomsV1; + chu.fileOffset = nextFileOffset; + chu.fileSize = _undefinedAtomIvars.size() * + sizeof(NativeUndefinedAtomIvarsV1); + chu.elementCount = _undefinedAtomIvars.size(); + nextFileOffset = chu.fileOffset + chu.fileSize; + } + // create chunk for symbol strings - NativeChunk& ch3 = chunks[3]; - ch3.signature = NCS_Strings; - ch3.fileOffset = ch2.fileOffset + ch2.fileSize; - ch3.fileSize = _stringPool.size(); - ch3.elementCount = _stringPool.size(); + NativeChunk& chs = chunks[nextIndex++]; + chs.signature = NCS_Strings; + chs.fileOffset = nextFileOffset; + chs.fileSize = _stringPool.size(); + chs.elementCount = _stringPool.size(); + nextFileOffset = chs.fileOffset + chs.fileSize; - _headerBuffer->fileSize = ch3.fileOffset + ch3.fileSize; + // create chunk for content + NativeChunk& chc = chunks[nextIndex++]; + chc.signature = NCS_Content; + chc.fileOffset = nextFileOffset; + chc.fileSize = _contentPool.size(); + chc.elementCount = _contentPool.size(); + nextFileOffset = chc.fileOffset + chc.fileSize; + + _headerBuffer->fileSize = nextFileOffset; } // append atom name to string pool and return offset - uint32_t getNameOffset(const class DefinedAtom& atom) { + uint32_t getNameOffset(const Atom& atom) { return this->getNameOffset(atom.name()); } @@ -190,14 +220,15 @@ typedef std::vector > NameToOffsetVector; - const lld::File& _file; - NativeFileHeader* _headerBuffer; - size_t _headerBufferSize; - std::vector _stringPool; - std::vector _contentPool; - std::vector _definedAtomIvars; - std::vector _attributes; - NameToOffsetVector _sectionNames; + const lld::File& _file; + NativeFileHeader* _headerBuffer; + size_t _headerBufferSize; + std::vector _stringPool; + std::vector _contentPool; + std::vector _definedAtomIvars; + std::vector _attributes; + std::vector _undefinedAtomIvars; + NameToOffsetVector _sectionNames; }; Modified: lld/trunk/lib/Core/Resolver.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/Resolver.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/Resolver.cpp (original) +++ lld/trunk/lib/Core/Resolver.cpp Mon Feb 6 20:59:54 2012 @@ -33,7 +33,7 @@ // don't remove if live if ( _liveAtoms.count(atom) ) return false; - // don't remove if marked never-dead-strip + // don't remove if marked never-dead-strip if ( const DefinedAtom* defAtom = atom->definedAtom() ) { if ( defAtom->deadStrip() == DefinedAtom::deadStripNever ) return false; Modified: lld/trunk/lib/Core/YamlKeyValues.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/YamlKeyValues.cpp (original) +++ lld/trunk/lib/Core/YamlKeyValues.cpp Mon Feb 6 20:59:54 2012 @@ -31,7 +31,8 @@ const char* const KeyValues::sectionNameKeyword = "section-name"; const char* const KeyValues::contentKeyword = "content"; const char* const KeyValues::sizeKeyword = "size"; -const char* const KeyValues::permissionsKeyword = "permissions"; +const char* const KeyValues::permissionsKeyword = "permissions"; +const char* const KeyValues::weakImportKeyword = "weak-import"; const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular; @@ -45,27 +46,28 @@ const bool KeyValues::internalNameDefault = false; const bool KeyValues::isThumbDefault = false; const bool KeyValues::isAliasDefault = false; +const bool KeyValues::weakImportDefault = false; struct DefinitionMapping { - const char* string; - Atom::Definition value; + const char* string; + Atom::Definition value; }; static const DefinitionMapping defMappings[] = { - { "regular", Atom::definitionRegular }, - { "absolute", Atom::definitionAbsolute }, - { "undefined", Atom::definitionUndefined }, - { "shared-library", Atom::definitionSharedLibrary }, + { "regular", Atom::definitionRegular }, + { "absolute", Atom::definitionAbsolute }, + { "undefined", Atom::definitionUndefined }, + { "shared-library", Atom::definitionSharedLibrary }, { NULL, Atom::definitionRegular } }; Atom::Definition KeyValues::definition(const char* s) { - for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) { + for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -73,7 +75,7 @@ } const char* KeyValues::definition(Atom::Definition s) { - for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) { + for (const DefinitionMapping* p = defMappings; p->string != NULL; ++p) { if ( p->value == s ) return p->string; } @@ -85,20 +87,20 @@ struct ScopeMapping { - const char* string; - DefinedAtom::Scope value; + const char* string; + DefinedAtom::Scope value; }; static const ScopeMapping scopeMappings[] = { - { "global", DefinedAtom::scopeGlobal }, - { "hidden", DefinedAtom::scopeLinkageUnit }, - { "static", DefinedAtom::scopeTranslationUnit }, + { "global", DefinedAtom::scopeGlobal }, + { "hidden", DefinedAtom::scopeLinkageUnit }, + { "static", DefinedAtom::scopeTranslationUnit }, { NULL, DefinedAtom::scopeGlobal } }; DefinedAtom::Scope KeyValues::scope(const char* s) { - for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) { + for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -106,7 +108,7 @@ } const char* KeyValues::scope(DefinedAtom::Scope s) { - for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) { + for (const ScopeMapping* p = scopeMappings; p->string != NULL; ++p) { if ( p->value == s ) return p->string; } @@ -121,41 +123,41 @@ struct ContentTypeMapping { - const char* string; - DefinedAtom::ContentType value; + const char* string; + DefinedAtom::ContentType value; }; static const ContentTypeMapping typeMappings[] = { - { "unknown", DefinedAtom::typeUnknown }, - { "code", DefinedAtom::typeCode }, - { "resolver", DefinedAtom::typeResolver }, - { "constant", DefinedAtom::typeConstant }, - { "c-string", DefinedAtom::typeCString }, - { "utf16-string", DefinedAtom::typeUTF16String }, - { "CFI", DefinedAtom::typeCFI }, - { "LSDA", DefinedAtom::typeLSDA }, - { "literal-4", DefinedAtom::typeLiteral4 }, - { "literal-8", DefinedAtom::typeLiteral8 }, - { "literal-16", DefinedAtom::typeLiteral16 }, - { "data", DefinedAtom::typeData }, - { "zero-fill", DefinedAtom::typeZeroFill }, - { "cf-string", DefinedAtom::typeCFString }, - { "initializer-ptr",DefinedAtom::typeInitializerPtr }, - { "terminator-ptr", DefinedAtom::typeTerminatorPtr }, - { "c-string-ptr", DefinedAtom::typeCStringPtr }, - { "objc1-class", DefinedAtom::typeObjC1Class }, - { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr }, - { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList }, - { "tlv-thunk", DefinedAtom::typeThunkTLV }, - { "tlv-data", DefinedAtom::typeTLVInitialData }, - { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill }, - { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr }, + { "unknown", DefinedAtom::typeUnknown }, + { "code", DefinedAtom::typeCode }, + { "resolver", DefinedAtom::typeResolver }, + { "constant", DefinedAtom::typeConstant }, + { "c-string", DefinedAtom::typeCString }, + { "utf16-string", DefinedAtom::typeUTF16String }, + { "CFI", DefinedAtom::typeCFI }, + { "LSDA", DefinedAtom::typeLSDA }, + { "literal-4", DefinedAtom::typeLiteral4 }, + { "literal-8", DefinedAtom::typeLiteral8 }, + { "literal-16", DefinedAtom::typeLiteral16 }, + { "data", DefinedAtom::typeData }, + { "zero-fill", DefinedAtom::typeZeroFill }, + { "cf-string", DefinedAtom::typeCFString }, + { "initializer-ptr",DefinedAtom::typeInitializerPtr }, + { "terminator-ptr", DefinedAtom::typeTerminatorPtr }, + { "c-string-ptr", DefinedAtom::typeCStringPtr }, + { "objc1-class", DefinedAtom::typeObjC1Class }, + { "objc1-class-ptr",DefinedAtom::typeObjCClassPtr }, + { "objc2-cat-ptr", DefinedAtom::typeObjC2CategoryList }, + { "tlv-thunk", DefinedAtom::typeThunkTLV }, + { "tlv-data", DefinedAtom::typeTLVInitialData }, + { "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill }, + { "tlv-init-ptr", DefinedAtom::typeTLVInitializerPtr }, { NULL, DefinedAtom::typeUnknown } }; DefinedAtom::ContentType KeyValues::contentType(const char* s) { - for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) { + for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -163,7 +165,7 @@ } const char* KeyValues::contentType(DefinedAtom::ContentType s) { - for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) { + for (const ContentTypeMapping* p = typeMappings; p->string != NULL; ++p) { if ( p->value == s ) return p->string; } @@ -177,20 +179,20 @@ struct DeadStripMapping { - const char* string; - DefinedAtom::DeadStripKind value; + const char* string; + DefinedAtom::DeadStripKind value; }; static const DeadStripMapping deadStripMappings[] = { - { "normal", DefinedAtom::deadStripNormal }, - { "never", DefinedAtom::deadStripNever }, - { "always", DefinedAtom::deadStripAlways }, + { "normal", DefinedAtom::deadStripNormal }, + { "never", DefinedAtom::deadStripNever }, + { "always", DefinedAtom::deadStripAlways }, { NULL, DefinedAtom::deadStripNormal } }; DefinedAtom::DeadStripKind KeyValues::deadStripKind(const char* s) { - for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) { + for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -198,7 +200,7 @@ } const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) { - for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) { + for (const DeadStripMapping* p = deadStripMappings; p->string != NULL; ++p) { if ( p->value == dsk ) return p->string; } @@ -210,20 +212,20 @@ struct InterposableMapping { - const char* string; - DefinedAtom::Interposable value; + const char* string; + DefinedAtom::Interposable value; }; static const InterposableMapping interMappings[] = { - { "no", DefinedAtom::interposeNo }, - { "yes", DefinedAtom::interposeYes }, - { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak }, + { "no", DefinedAtom::interposeNo }, + { "yes", DefinedAtom::interposeYes }, + { "yesAndWeak", DefinedAtom::interposeYesAndRuntimeWeak }, { NULL, DefinedAtom::interposeNo } }; DefinedAtom::Interposable KeyValues::interposable(const char* s) { - for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) { + for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -231,7 +233,7 @@ } const char* KeyValues::interposable(DefinedAtom::Interposable in) { - for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) { + for (const InterposableMapping* p = interMappings; p->string != NULL; ++p) { if ( p->value == in ) return p->string; } @@ -244,21 +246,21 @@ struct MergeMapping { - const char* string; - DefinedAtom::Merge value; + const char* string; + DefinedAtom::Merge value; }; static const MergeMapping mergeMappings[] = { - { "no", DefinedAtom::mergeNo }, - { "asTentative", DefinedAtom::mergeAsTentative }, - { "asWeak", DefinedAtom::mergeAsWeak }, - { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed }, + { "no", DefinedAtom::mergeNo }, + { "asTentative", DefinedAtom::mergeAsTentative }, + { "asWeak", DefinedAtom::mergeAsWeak }, + { "asAddressedWeak",DefinedAtom::mergeAsWeakAndAddressUsed }, { NULL, DefinedAtom::mergeNo } }; DefinedAtom::Merge KeyValues::merge(const char* s) { - for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) { + for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -266,7 +268,7 @@ } const char* KeyValues::merge(DefinedAtom::Merge in) { - for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) { + for (const MergeMapping* p = mergeMappings; p->string != NULL; ++p) { if ( p->value == in ) return p->string; } @@ -279,20 +281,20 @@ struct SectionChoiceMapping { - const char* string; - DefinedAtom::SectionChoice value; + const char* string; + DefinedAtom::SectionChoice value; }; static const SectionChoiceMapping sectMappings[] = { - { "content", DefinedAtom::sectionBasedOnContent }, - { "custom", DefinedAtom::sectionCustomPreferred }, - { "custom-required", DefinedAtom::sectionCustomRequired }, + { "content", DefinedAtom::sectionBasedOnContent }, + { "custom", DefinedAtom::sectionCustomPreferred }, + { "custom-required", DefinedAtom::sectionCustomRequired }, { NULL, DefinedAtom::sectionBasedOnContent } }; DefinedAtom::SectionChoice KeyValues::sectionChoice(const char* s) { - for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) { + for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -300,7 +302,7 @@ } const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) { - for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) { + for (const SectionChoiceMapping* p = sectMappings; p->string != NULL; ++p) { if ( p->value == s ) return p->string; } @@ -314,22 +316,22 @@ struct PermissionsMapping { - const char* string; - DefinedAtom::ContentPermissions value; + const char* string; + DefinedAtom::ContentPermissions value; }; static const PermissionsMapping permMappings[] = { - { "content", DefinedAtom::perm___ }, - { "custom", DefinedAtom::permR__ }, - { "custom-required", DefinedAtom::permR_X }, - { "custom-required", DefinedAtom::permRW_ }, - { "custom-required", DefinedAtom::permRW_L }, + { "content", DefinedAtom::perm___ }, + { "custom", DefinedAtom::permR__ }, + { "custom-required", DefinedAtom::permR_X }, + { "custom-required", DefinedAtom::permRW_ }, + { "custom-required", DefinedAtom::permRW_L }, { NULL, DefinedAtom::perm___ } }; DefinedAtom::ContentPermissions KeyValues::permissions(const char* s) { - for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) { + for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) { if ( strcmp(p->string, s) == 0 ) return p->value; } @@ -337,7 +339,7 @@ } const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) { - for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) { + for (const PermissionsMapping* p = permMappings; p->string != NULL; ++p) { if ( p->value == s ) return p->string; } @@ -398,6 +400,23 @@ +bool KeyValues::weakImport(const char* s) +{ + if ( strcmp(s, "true") == 0 ) + return true; + else if ( strcmp(s, "false") == 0 ) + return false; + llvm::report_fatal_error("bad weak-import value"); +} + +const char* KeyValues::weakImport(bool b) { + return b ? "true" : "false"; +} + + + + + } // namespace yaml Modified: lld/trunk/lib/Core/YamlKeyValues.h URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlKeyValues.h?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/YamlKeyValues.h (original) +++ lld/trunk/lib/Core/YamlKeyValues.h Mon Feb 6 20:59:54 2012 @@ -79,6 +79,11 @@ static bool isAlias(const char*); static const char* isAlias(bool); + static const char* const weakImportKeyword; + static const bool weakImportDefault; + static bool weakImport(const char*); + static const char* weakImport(bool); + }; } // namespace yaml Modified: lld/trunk/lib/Core/YamlReader.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlReader.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/YamlReader.cpp (original) +++ lld/trunk/lib/Core/YamlReader.cpp Mon Feb 6 20:59:54 2012 @@ -267,6 +267,10 @@ it != _definedAtoms.end(); ++it) { handler.doDefinedAtom(**it); } + for (std::vector::const_iterator it = _undefinedAtoms.begin(); + it != _undefinedAtoms.end(); ++it) { + handler.doUndefinedAtom(**it); + } return true; } @@ -424,6 +428,32 @@ }; +class YAMLUndefinedAtom : public UndefinedAtom { +public: + YAMLUndefinedAtom(YAMLFile& f, int32_t ord, const char* nm, bool wi) + : _file(f), _name(nm), _ordinal(ord), _weakImport(wi) { } + + virtual const class File& file() const { + return _file; + } + + virtual llvm::StringRef name() const { + return _name; + } + + virtual bool weakImport() const { + return _weakImport; + } + +private: + YAMLFile& _file; + const char * _name; + uint32_t _ordinal; + bool _weakImport; +}; + + + class YAMLAtomState { public: YAMLAtomState(); @@ -455,6 +485,7 @@ bool _internalName; bool _isThumb; bool _isAlias; + bool _weakImport; Reference _ref; }; @@ -477,6 +508,7 @@ , _internalName(KeyValues::internalNameDefault) , _isThumb(KeyValues::isThumbDefault) , _isAlias(KeyValues::isAliasDefault) + , _weakImport(false) { _ref.target = NULL; _ref.addend = 0; @@ -496,6 +528,12 @@ f._definedAtoms.push_back(a); ++_ordinal; } + else if ( _definition == Atom::definitionUndefined ) { + UndefinedAtom *a = new YAMLUndefinedAtom(f, _ordinal, _name, _weakImport); + + f._undefinedAtoms.push_back(a); + ++_ordinal; + } // reset state for next atom _name = NULL; @@ -515,6 +553,7 @@ _permissions = KeyValues::permissionsDefault; _isThumb = KeyValues::isThumbDefault; _isAlias = KeyValues::isAliasDefault; + _weakImport = KeyValues::weakImportDefault; _ref.target = NULL; _ref.addend = 0; _ref.offsetInAtom = 0; @@ -664,6 +703,10 @@ atomState._isAlias = KeyValues::isAlias(entry->value); haveAtom = true; } + else if (strcmp(entry->key, KeyValues::weakImportKeyword) == 0) { + atomState._weakImport = KeyValues::weakImport(entry->value); + haveAtom = true; + } else if (strcmp(entry->key, KeyValues::sectionNameKeyword) == 0) { atomState._sectionName = entry->value; haveAtom = true; Modified: lld/trunk/lib/Core/YamlWriter.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/YamlWriter.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/lib/Core/YamlWriter.cpp (original) +++ lld/trunk/lib/Core/YamlWriter.cpp Mon Feb 6 20:59:54 2012 @@ -81,7 +81,7 @@ << "\n"; } - if ( atom.merge() != KeyValues::mergeDefault ) { + if ( atom.merge() != KeyValues::mergeDefault ) { _out << " " << KeyValues::mergeKeyword << ":" @@ -124,7 +124,7 @@ << "\n"; } - if ( atom.isThumb() != KeyValues::isThumbDefault ) { + if ( atom.isThumb() != KeyValues::isThumbDefault ) { _out << " " << KeyValues::isThumbKeyword << ":" @@ -142,7 +142,8 @@ << "\n"; } - if ( atom.contentType() != DefinedAtom::typeZeroFill ) { + if ( (atom.contentType() != DefinedAtom::typeZeroFill) + && (atom.size() != 0) ) { _out << " " << KeyValues::contentKeyword << ":" @@ -171,9 +172,35 @@ } - virtual void doUndefinedAtom(const class UndefinedAtom &atom) { + virtual void doUndefinedAtom(const class UndefinedAtom &atom) { + // add blank line between atoms for readability + if ( !_firstAtom ) + _out << "\n"; + _firstAtom = false; + + _out << " - " + << KeyValues::nameKeyword + << ":" + << spacePadding(KeyValues::nameKeyword) + << atom.name() + << "\n"; + + _out << " " + << KeyValues::definitionKeyword + << ":" + << spacePadding(KeyValues::definitionKeyword) + << KeyValues::definition(atom.definition()) + << "\n"; - } + if ( atom.weakImport() != KeyValues::weakImportDefault ) { + _out << " " + << KeyValues::weakImportKeyword + << ":" + << spacePadding(KeyValues::weakImportKeyword) + << KeyValues::weakImport(atom.weakImport()) + << "\n"; + } + } private: Added: lld/trunk/test/undef-coalesce.objtxt URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/undef-coalesce.objtxt?rev=149962&view=auto ============================================================================== --- lld/trunk/test/undef-coalesce.objtxt (added) +++ lld/trunk/test/undef-coalesce.objtxt Mon Feb 6 20:59:54 2012 @@ -0,0 +1,46 @@ +# RUN: lld-core %s | FileCheck %s + +# +# Test that undefined symbols are coalesced with other undefined symbols +# and definitions override them. +# + +--- +atoms: + - name: foo + type: code + + - name: malloc + definition: undefined + + - name: free + definition: undefined +--- +atoms: + - name: bar + type: code + + - name: malloc + definition: undefined + + - name: myfunc + definition: undefined +--- +atoms: + - name: myfunc + scope: global + type: code + + - name: free + definition: undefined +... + +# CHECK: name: foo +# CHECK: name: bar +# CHECK: name: myfunc +# CHECK: scope: global +# CHECK: name: malloc +# CHECK: definition: undefined +# CHECK: name: free +# CHECK: definition: undefined +# CHECK: ... Modified: lld/trunk/tools/lld-core/lld-core.cpp URL: http://llvm.org/viewvc/llvm-project/lld/trunk/tools/lld-core/lld-core.cpp?rev=149962&r1=149961&r2=149962&view=diff ============================================================================== --- lld/trunk/tools/lld-core/lld-core.cpp (original) +++ lld/trunk/tools/lld-core/lld-core.cpp Mon Feb 6 20:59:54 2012 @@ -172,20 +172,19 @@ virtual bool forEachAtom(File::AtomHandler &handler) const { handler.doFile(*this); + // visit defined atoms for (std::vector::iterator it = _atoms.begin(); it != _atoms.end(); ++it) { - const Atom* atom = *it; - switch ( atom->definition() ) { - case Atom::definitionRegular: - handler.doDefinedAtom(*(DefinedAtom*)atom); - break; - case Atom::definitionUndefined: - handler.doUndefinedAtom(*(UndefinedAtom*)atom); - break; - default: - // TO DO - break; - } + const DefinedAtom* atom = (*it)->definedAtom(); + if ( atom ) + handler.doDefinedAtom(*atom); + } + // visit undefined atoms + for (std::vector::iterator it = _atoms.begin(); + it != _atoms.end(); ++it) { + const UndefinedAtom* atom = (*it)->undefinedAtom(); + if ( atom ) + handler.doUndefinedAtom(*atom); } return true; } @@ -198,7 +197,8 @@ private: std::vector &_atoms; }; -} +} //anonymous namespace + int main(int argc, const char *argv[]) { // Print a stack trace if we signal out. @@ -220,7 +220,7 @@ // write new atom graph out as YAML doc std::string errorInfo; llvm::raw_fd_ostream out("-", errorInfo); -// yaml::writeObjectText(outFile, out); + //yaml::writeObjectText(outFile, out); // make unique temp .o file to put generated object file int fd; @@ -233,7 +233,7 @@ binaryOut.close(); // manually close so that file can be read next // read native file - lld::File* natFile; + llvm::OwningPtr natFile; parseNativeObjectFileOrSTDIN(tempPath, natFile); // write new atom graph out as YAML doc @@ -242,6 +242,6 @@ // delete temp .o file bool existed; llvm::sys::fs::remove(tempPath.str(), existed); - + return 0; } From kcc at google.com Mon Feb 6 21:10:06 2012 From: kcc at google.com (Kostya Serebryany) Date: Mon, 6 Feb 2012 19:10:06 -0800 Subject: [llvm-commits] ThreadSanitizer, first patch. Please review. In-Reply-To: References: Message-ID: Thanks for the review! Please take another look. On Mon, Feb 6, 2012 at 2:35 PM, Nick Lewycky wrote: > On 30 January 2012 09:45, Kostya Serebryany wrote: > >> Any feedback? > > > --- test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) > +++ test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) > @@ -0,0 +1,17 @@ > +; RUN: opt < %s -tsan -S | FileCheck %s > + > +target datalayout = > "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" > +target triple = "x86_64-unknown-linux-gnu" > + > +define i32 @read_4_bytes(i32* %a) { > +entry: > + %tmp1 = load i32* %a, align 4 > + ret i32 %tmp1 > +} > +; CHECK: @read_4_bytes > +; CHECK-NOT: ret i32 > +; CHECK: __tsan_func_entry > +; CHECK: __tsan_read4 > +; CHECK: __tsan_func_exit > +; CHECK: ret i32 > +; CHECK: __tsan_init > > I'm not a fan of this pile of CHECK statements. You could actually write > out the IR that you expect to get out and preserve the order using > CHECK-NEXT. Even if you don't want the matches to be too specific, it would > still be clearer to see "CHECK-NEXT: call {{.*}} @__tsan_func_entry". > done > > Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp > =================================================================== > --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) > +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) > @@ -0,0 +1,149 @@ > +//===-- ThreadSanitizer.cpp - race detector ---------------------*- C++ > -*-===// > > Hey hey, this ruler is 81 characters long. :) > Hm? My editor says 80 (81 counting the '+' in the patch). > > +bool ThreadSanitizer::runOnModule(Module &M) { > + bool Res = false; > + CurrentModule = &M; > + TD = getAnalysisIfAvailable(); > + if (!TD) > + return false; > + > + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { > + if (F->isDeclaration()) continue; > + Res |= handleFunction(M, *F); > + } > + // We instrumented at least one function. Insert a call to > __tsan_init(). > + if (Res) { > + IRBuilder<> IRB(M.getContext()); > + Value *TsanInit = M.getOrInsertFunction("__tsan_init", > + IRB.getVoidTy(), NULL); > + appendToGlobalCtors(M, cast(TsanInit), 0); > + } > + return Res; > +} > > You could write this as a FunctionPass; create the __tsan_... methods in > doInitialization() (and store the necessary pointers in your object so that > you needn't look them up each time you instrument a function), then do the > instrumentation per-function, then in doFinalization either add the call to > __tsan_init or clean up declarations you created in doInitialization(). > Rewrote to use FunctionPass. However I have questions: - Suppose I want to count the number of transformed instructions in runOnFunction and store the result in the ThreadSanitizer object. Do I need to use locking or atomics (OMG)? - You suggest to call M->getOrInsertFunction in doInitialization. Bu that will require 5x2+2=12 class members that will decrease the readability. Also, there is no guarantee that all these objects will ever be used, so this is a kind of pessimization. Besides, if getOrInsertFunction is slow, isn't it better to make it faster, than to manually optimize calls? We can do a lazy init for these objects, but then again what is the preferred way to do lazy init in the FunctionPass to avoid races? > > + else if (isa(BI)) > + HasCalls = true; > > > What about invokes? > > Yea, sure. Done. > + // Instrument memory accesses. > + for (size_t i = 0, n = LoadsAndStores.size(); i < n; ++i) { > + Res |= instrumentLoadOrStore(LoadsAndStores[i]); > + } > > Why not just call instrumentLoadOrStore as you encounter them? It seems > that the vector is just overhead. > *in future* we will need to analyze this array and remove some of its elements. Now it just looks a bit cleaner to me. --kcc -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/4f8e340d/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: issue5630068_2001.diff Type: text/x-patch Size: 2854 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/4f8e340d/attachment.bin From stoklund at 2pi.dk Mon Feb 6 21:11:22 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Mon, 6 Feb 2012 19:11:22 -0800 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: References: <4ebd9343c592547977b041f93d7ee7160da178e7.1328050160.git.dag@cray.com> <7DE70FDACDE4CD4887C4278C12A2E3050813E4@HASMSX104.ger.corp.intel.com> <9775869E-C040-4D99-B5A7-DE4C54B6E588@2pi.dk> Message-ID: On Feb 6, 2012, at 8:54 AM, David A. Greene wrote: > If you > accept that foreach is useful, than zip is useful as well, for exactly > the reasons it is in many, many, many other languages with looping > constructs. Let's get the basic patch in first, and deal with this after. /jakob From nlewycky at google.com Mon Feb 6 21:35:40 2012 From: nlewycky at google.com (Nick Lewycky) Date: Mon, 6 Feb 2012 19:35:40 -0800 Subject: [llvm-commits] ThreadSanitizer, first patch. Please review. In-Reply-To: References: Message-ID: On 6 February 2012 19:10, Kostya Serebryany wrote: > Thanks for the review! > Please take another look. > Wrong patch attached? > > On Mon, Feb 6, 2012 at 2:35 PM, Nick Lewycky wrote: > >> On 30 January 2012 09:45, Kostya Serebryany wrote: >> >>> Any feedback? >> >> >> --- test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) >> +++ test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) >> @@ -0,0 +1,17 @@ >> +; RUN: opt < %s -tsan -S | FileCheck %s >> + >> +target datalayout = >> "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" >> +target triple = "x86_64-unknown-linux-gnu" >> + >> +define i32 @read_4_bytes(i32* %a) { >> +entry: >> + %tmp1 = load i32* %a, align 4 >> + ret i32 %tmp1 >> +} >> +; CHECK: @read_4_bytes >> +; CHECK-NOT: ret i32 >> +; CHECK: __tsan_func_entry >> +; CHECK: __tsan_read4 >> +; CHECK: __tsan_func_exit >> +; CHECK: ret i32 >> +; CHECK: __tsan_init >> >> I'm not a fan of this pile of CHECK statements. You could actually write >> out the IR that you expect to get out and preserve the order using >> CHECK-NEXT. Even if you don't want the matches to be too specific, it would >> still be clearer to see "CHECK-NEXT: call {{.*}} @__tsan_func_entry". >> > done > > >> >> Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp >> =================================================================== >> --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) >> +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) >> @@ -0,0 +1,149 @@ >> +//===-- ThreadSanitizer.cpp - race detector ---------------------*- C++ >> -*-===// >> >> Hey hey, this ruler is 81 characters long. :) >> > > Hm? My editor says 80 (81 counting the '+' in the patch). > Sorry, false alarm. (Not sure how that happened; my editor said "82", but I wasn't using my usual editor at the time.) > > > >> >> +bool ThreadSanitizer::runOnModule(Module &M) { >> + bool Res = false; >> + CurrentModule = &M; >> + TD = getAnalysisIfAvailable(); >> + if (!TD) >> + return false; >> + >> + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { >> + if (F->isDeclaration()) continue; >> + Res |= handleFunction(M, *F); >> + } >> + // We instrumented at least one function. Insert a call to >> __tsan_init(). >> + if (Res) { >> + IRBuilder<> IRB(M.getContext()); >> + Value *TsanInit = M.getOrInsertFunction("__tsan_init", >> + IRB.getVoidTy(), NULL); >> + appendToGlobalCtors(M, cast(TsanInit), 0); >> + } >> + return Res; >> +} >> >> You could write this as a FunctionPass; create the __tsan_... methods in >> doInitialization() (and store the necessary pointers in your object so that >> you needn't look them up each time you instrument a function), then do the >> instrumentation per-function, then in doFinalization either add the call to >> __tsan_init or clean up declarations you created in doInitialization(). >> > > Rewrote to use FunctionPass. > However I have questions: > - Suppose I want to count the number of transformed instructions > in runOnFunction and store the result in the ThreadSanitizer object. Do I > need to use locking or atomics (OMG)? > Yes, you would. > - You suggest to call M->getOrInsertFunction in doInitialization. Bu > that will require 5x2+2=12 class members that will decrease the readability. > Feel free to have an array or whatnot to collapse them :) > Also, there is no guarantee that all these objects will ever be used, > so this is a kind of pessimization. > Besides, if getOrInsertFunction is slow, isn't it better to make it > faster, than to manually optimize calls? > We can do a lazy init for these objects, but then again what is the > preferred way to do lazy init in the FunctionPass to avoid races? > The trouble is that a FunctionPass isn't supposed to be creating or deleting Function (or other Globals). This is part of the threading model. See http://llvm.org/docs/WritingAnLLVMPass.html#FunctionPass . If you find these restrictions too hard to live with you can go back to using a ModulePass. in reality, we have plenty FunctionPasses which do manipulate global state against the rules, but I'm trying to make TSan perfect. > >> + else if (isa(BI)) >> + HasCalls = true; >> >> > > >> What about invokes? >> >> > Yea, sure. Done. > > >> + // Instrument memory accesses. >> + for (size_t i = 0, n = LoadsAndStores.size(); i < n; ++i) { >> + Res |= instrumentLoadOrStore(LoadsAndStores[i]); >> + } >> >> Why not just call instrumentLoadOrStore as you encounter them? It seems >> that the vector is just overhead. >> > > *in future* we will need to analyze this array and remove some of its > elements. > Now it just looks a bit cleaner to me. > > > --kcc > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120206/b292160a/attachment.html From craig.topper at gmail.com Mon Feb 6 23:05:23 2012 From: craig.topper at gmail.com (Craig Topper) Date: Tue, 07 Feb 2012 05:05:23 -0000 Subject: [llvm-commits] [llvm] r149967 - in /llvm/trunk/lib: Analysis/ AsmParser/ ExecutionEngine/ ExecutionEngine/JIT/ ExecutionEngine/MCJIT/ ExecutionEngine/RuntimeDyld/ Linker/ MC/ MC/MCDisassembler/ MC/MCParser/ Support/ TableGen/ Transforms/InstCombine/ Transforms/Instrumentation/ Transforms/Scalar/ Transforms/Utils/ Message-ID: <20120207050524.D7ED22A6C12C@llvm.org> Author: ctopper Date: Mon Feb 6 23:05:23 2012 New Revision: 149967 URL: http://llvm.org/viewvc/llvm-project?rev=149967&view=rev Log: Convert assert(0) to llvm_unreachable Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp llvm/trunk/lib/Analysis/DebugInfo.cpp llvm/trunk/lib/Analysis/InstructionSimplify.cpp llvm/trunk/lib/AsmParser/LLParser.cpp llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp llvm/trunk/lib/Linker/LinkModules.cpp llvm/trunk/lib/MC/MCAsmStreamer.cpp llvm/trunk/lib/MC/MCAssembler.cpp llvm/trunk/lib/MC/MCDisassembler/EDMain.cpp llvm/trunk/lib/MC/MCDwarf.cpp llvm/trunk/lib/MC/MCELFStreamer.cpp llvm/trunk/lib/MC/MCExpr.cpp llvm/trunk/lib/MC/MCInstPrinter.cpp llvm/trunk/lib/MC/MCMachOStreamer.cpp llvm/trunk/lib/MC/MCParser/AsmParser.cpp llvm/trunk/lib/MC/MCStreamer.cpp llvm/trunk/lib/Support/ConstantRange.cpp llvm/trunk/lib/Support/Triple.cpp llvm/trunk/lib/TableGen/Record.cpp llvm/trunk/lib/TableGen/TGParser.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp llvm/trunk/lib/Transforms/Utils/CmpInstAnalysis.cpp Modified: llvm/trunk/lib/Analysis/ConstantFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ConstantFolding.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/ConstantFolding.cpp (original) +++ llvm/trunk/lib/Analysis/ConstantFolding.cpp Mon Feb 6 23:05:23 2012 @@ -862,7 +862,7 @@ switch (Opcode) { default: return 0; case Instruction::ICmp: - case Instruction::FCmp: assert(0 && "Invalid for compares"); + case Instruction::FCmp: llvm_unreachable("Invalid for compares"); case Instruction::Call: if (Function *F = dyn_cast(Ops.back())) if (canConstantFoldCallTo(F)) @@ -1390,7 +1390,7 @@ APInt Res; bool Overflow; switch (F->getIntrinsicID()) { - default: assert(0 && "Invalid case"); + default: llvm_unreachable("Invalid case"); case Intrinsic::sadd_with_overflow: Res = Op1->getValue().sadd_ov(Op2->getValue(), Overflow); break; Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Mon Feb 6 23:05:23 2012 @@ -583,8 +583,7 @@ return DIType(DbgNode).getFilename(); if (isFile()) return DIFile(DbgNode).getFilename(); - assert(0 && "Invalid DIScope!"); - return StringRef(); + llvm_unreachable("Invalid DIScope!"); } StringRef DIScope::getDirectory() const { @@ -604,8 +603,7 @@ return DIType(DbgNode).getDirectory(); if (isFile()) return DIFile(DbgNode).getDirectory(); - assert(0 && "Invalid DIScope!"); - return StringRef(); + llvm_unreachable("Invalid DIScope!"); } DIArray DICompileUnit::getEnumTypes() const { Modified: llvm/trunk/lib/Analysis/InstructionSimplify.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InstructionSimplify.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/InstructionSimplify.cpp (original) +++ llvm/trunk/lib/Analysis/InstructionSimplify.cpp Mon Feb 6 23:05:23 2012 @@ -1595,8 +1595,7 @@ if (match(RHS, m_Zero())) { bool LHSKnownNonNegative, LHSKnownNegative; switch (Pred) { - default: - assert(false && "Unknown ICmp predicate!"); + default: llvm_unreachable("Unknown ICmp predicate!"); case ICmpInst::ICMP_ULT: return getFalse(ITy); case ICmpInst::ICMP_UGE: @@ -1766,8 +1765,7 @@ // there. Use this to work out the result of the comparison. if (RExt != CI) { switch (Pred) { - default: - assert(false && "Unknown ICmp predicate!"); + default: llvm_unreachable("Unknown ICmp predicate!"); // LHS getContext()); case ICmpInst::ICMP_NE: Modified: llvm/trunk/lib/AsmParser/LLParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/AsmParser/LLParser.cpp (original) +++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Feb 6 23:05:23 2012 @@ -2837,7 +2837,7 @@ } switch (ParseInstruction(Inst, BB, PFS)) { - default: assert(0 && "Unknown ParseInstruction result!"); + default: llvm_unreachable("Unknown ParseInstruction result!"); case InstError: return true; case InstNormal: BB->getInstList().push_back(Inst); Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Mon Feb 6 23:05:23 2012 @@ -1149,6 +1149,6 @@ void ExecutionEngineState::AddressMapConfig::onRAUW(ExecutionEngineState *, const GlobalValue *, const GlobalValue *) { - assert(false && "The ExecutionEngine doesn't know how to handle a" - " RAUW on a value it has a global mapping for."); + llvm_unreachable("The ExecutionEngine doesn't know how to handle a" + " RAUW on a value it has a global mapping for."); } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Mon Feb 6 23:05:23 2012 @@ -706,9 +706,8 @@ if (I != getBasicBlockAddressMap(locked).end()) { return I->second; } else { - assert(0 && "JIT does not have BB address for address-of-label, was" - " it eliminated by optimizer?"); - return 0; + llvm_unreachable("JIT does not have BB address for address-of-label, was" + " it eliminated by optimizer?"); } } Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Mon Feb 6 23:05:23 2012 @@ -76,8 +76,8 @@ struct NoRAUWValueMapConfig : public ValueMapConfig { typedef JITResolverState *ExtraData; static void onRAUW(JITResolverState *, Value *Old, Value *New) { - assert(false && "The JIT doesn't know how to handle a" - " RAUW on a value it has emitted."); + llvm_unreachable("The JIT doesn't know how to handle a" + " RAUW on a value it has emitted."); } }; @@ -1162,7 +1162,7 @@ break; } case MachineJumpTableInfo::EK_GPRel64BlockAddress: - assert(false && + llvm_unreachable( "JT Info emission not implemented for GPRel64BlockAddress yet."); } } Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Mon Feb 6 23:05:23 2012 @@ -213,6 +213,5 @@ } } - assert(0 && "Full-featured argument passing not supported yet!"); - return GenericValue(); + llvm_unreachable("Full-featured argument passing not supported yet!"); } Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Mon Feb 6 23:05:23 2012 @@ -185,9 +185,7 @@ } switch (RE.Type) { - default: - assert(0 && ("Relocation type not implemented yet!")); - break; + default: llvm_unreachable("Relocation type not implemented yet!"); case ELF::R_X86_64_64: { uint8_t **Target = reinterpret_cast(TargetAddr); *Target = Addr + RE.Addend; @@ -249,8 +247,7 @@ default: // There are other relocation types, but it appears these are the // only ones currently used by the LLVM ELF object writer - assert(0 && ("Relocation type not implemented yet!")); - break; + llvm_unreachable("Relocation type not implemented yet!"); } } @@ -272,9 +269,7 @@ case Triple::arm: resolveArmRelocation(Name, Addr, RE); break; - default: - assert(0 && "Unsupported CPU type!"); - break; + default: llvm_unreachable("Unsupported CPU type!"); } } Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp (original) +++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp Mon Feb 6 23:05:23 2012 @@ -26,7 +26,7 @@ unsigned Type, unsigned Size, int64_t Addend) { // This just dispatches to the proper target specific routine. switch (CPUType) { - default: assert(0 && "Unsupported CPU type!"); + default: llvm_unreachable("Unsupported CPU type!"); case mach::CTM_x86_64: return resolveX86_64Relocation((uintptr_t)Address, (uintptr_t)Value, isPCRel, Type, Size, Addend); Modified: llvm/trunk/lib/Linker/LinkModules.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/LinkModules.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Linker/LinkModules.cpp (original) +++ llvm/trunk/lib/Linker/LinkModules.cpp Mon Feb 6 23:05:23 2012 @@ -267,7 +267,7 @@ // Otherwise, rebuild a modified type. switch (Ty->getTypeID()) { - default: assert(0 && "unknown derived type to remap"); + default: llvm_unreachable("unknown derived type to remap"); case Type::ArrayTyID: return *Entry = ArrayType::get(ElementTypes[0], cast(Ty)->getNumElements()); Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Mon Feb 6 23:05:23 2012 @@ -394,7 +394,7 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { switch (Attribute) { - case MCSA_Invalid: assert(0 && "Invalid symbol attribute"); + case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute"); case MCSA_ELF_TypeFunction: /// .type _foo, STT_FUNC # aka @function case MCSA_ELF_TypeIndFunction: /// .type _foo, STT_GNU_IFUNC case MCSA_ELF_TypeObject: /// .type _foo, STT_OBJECT # aka @object @@ -406,7 +406,7 @@ OS << "\t.type\t" << *Symbol << ',' << ((MAI.getCommentString()[0] != '@') ? '@' : '%'); switch (Attribute) { - default: assert(0 && "Unknown ELF .type"); + default: llvm_unreachable("Unknown ELF .type"); case MCSA_ELF_TypeFunction: OS << "function"; break; case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break; case MCSA_ELF_TypeObject: OS << "object"; break; Modified: llvm/trunk/lib/MC/MCAssembler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp (original) +++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Feb 6 23:05:23 2012 @@ -348,8 +348,7 @@ return cast(F).getContents().size(); } - assert(0 && "invalid fragment kind"); - return 0; + llvm_unreachable("invalid fragment kind"); } void MCAsmLayout::LayoutFragment(MCFragment *F) { @@ -414,8 +413,7 @@ // Otherwise, write out in multiples of the value size. for (uint64_t i = 0; i != Count; ++i) { switch (AF.getValueSize()) { - default: - assert(0 && "Invalid size!"); + default: llvm_unreachable("Invalid size!"); case 1: OW->Write8 (uint8_t (AF.getValue())); break; case 2: OW->Write16(uint16_t(AF.getValue())); break; case 4: OW->Write32(uint32_t(AF.getValue())); break; @@ -439,8 +437,7 @@ for (uint64_t i = 0, e = FF.getSize() / FF.getValueSize(); i != e; ++i) { switch (FF.getValueSize()) { - default: - assert(0 && "Invalid size!"); + default: llvm_unreachable("Invalid size!"); case 1: OW->Write8 (uint8_t (FF.getValue())); break; case 2: OW->Write16(uint16_t(FF.getValue())); break; case 4: OW->Write32(uint32_t(FF.getValue())); break; @@ -496,8 +493,7 @@ for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end(); it != ie; ++it) { switch (it->getKind()) { - default: - assert(0 && "Invalid fragment in virtual section!"); + default: llvm_unreachable("Invalid fragment in virtual section!"); case MCFragment::FT_Data: { // Check that we aren't trying to write a non-zero contents (or fixups) // into a virtual section. This is to support clients which use standard Modified: llvm/trunk/lib/MC/MCDisassembler/EDMain.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDMain.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDisassembler/EDMain.cpp (original) +++ llvm/trunk/lib/MC/MCDisassembler/EDMain.cpp Mon Feb 6 23:05:23 2012 @@ -23,7 +23,7 @@ EDAssemblySyntax_t syntax) { EDDisassembler::AssemblySyntax Syntax; switch (syntax) { - default: assert(0 && "Unknown assembly syntax!"); + default: llvm_unreachable("Unknown assembly syntax!"); case kEDAssemblySyntaxX86Intel: Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel; break; Modified: llvm/trunk/lib/MC/MCDwarf.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCDwarf.cpp (original) +++ llvm/trunk/lib/MC/MCDwarf.cpp Mon Feb 6 23:05:23 2012 @@ -765,8 +765,7 @@ MCContext &context = streamer.getContext(); unsigned format = symbolEncoding & 0x0f; switch (format) { - default: - assert(0 && "Unknown Encoding"); + default: llvm_unreachable("Unknown Encoding"); case dwarf::DW_EH_PE_absptr: case dwarf::DW_EH_PE_signed: return context.getAsmInfo().getPointerSize(); Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCELFStreamer.cpp Mon Feb 6 23:05:23 2012 @@ -60,24 +60,24 @@ virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitCOFFSymbolStorageClass(int StorageClass) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitCOFFSymbolType(int Type) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EndCOFFSymbolDef() { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { @@ -90,11 +90,11 @@ virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) { - assert(0 && "ELF doesn't support this directive"); + llvm_unreachable("ELF doesn't support this directive"); } virtual void EmitBytes(StringRef Data, unsigned AddrSpace); virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value = 0, @@ -180,7 +180,7 @@ return; } - assert(0 && "invalid assembler flag!"); + llvm_unreachable("invalid assembler flag!"); } void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) { @@ -250,8 +250,7 @@ case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: case MCSA_IndirectSymbol: - assert(0 && "Invalid symbol attribute for ELF!"); - break; + llvm_unreachable("Invalid symbol attribute for ELF!"); case MCSA_ELF_TypeGnuUniqueObject: // Ignore for now. Modified: llvm/trunk/lib/MC/MCExpr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCExpr.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCExpr.cpp (original) +++ llvm/trunk/lib/MC/MCExpr.cpp Mon Feb 6 23:05:23 2012 @@ -132,7 +132,7 @@ } } - assert(0 && "Invalid expression kind!"); + llvm_unreachable("Invalid expression kind!"); } void MCExpr::dump() const { @@ -576,8 +576,7 @@ } } - assert(0 && "Invalid assembly expression kind!"); - return false; + llvm_unreachable("Invalid assembly expression kind!"); } const MCSection *MCExpr::FindAssociatedSection() const { @@ -618,6 +617,5 @@ } } - assert(0 && "Invalid assembly expression kind!"); - return 0; + llvm_unreachable("Invalid assembly expression kind!"); } Modified: llvm/trunk/lib/MC/MCInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCInstPrinter.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCInstPrinter.cpp (original) +++ llvm/trunk/lib/MC/MCInstPrinter.cpp Mon Feb 6 23:05:23 2012 @@ -10,6 +10,7 @@ #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -23,7 +24,7 @@ } void MCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const { - assert(0 && "Target should implement this"); + llvm_unreachable("Target should implement this"); } void MCInstPrinter::printAnnotation(raw_ostream &OS, StringRef Annot) { Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Mon Feb 6 23:05:23 2012 @@ -53,23 +53,23 @@ virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EmitCOFFSymbolStorageClass(int StorageClass) { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EmitCOFFSymbolType(int Type) { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EndCOFFSymbolDef() { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment) { - assert(0 && "macho doesn't support this directive"); + llvm_unreachable("macho doesn't support this directive"); } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol = 0, unsigned Size = 0, unsigned ByteAlignment = 0); @@ -211,8 +211,7 @@ case MCSA_Protected: case MCSA_Weak: case MCSA_Local: - assert(0 && "Invalid symbol attribute for Mach-O!"); - break; + llvm_unreachable("Invalid symbol attribute for Mach-O!"); case MCSA_Global: SD.setExternal(true); Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original) +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Mon Feb 6 23:05:23 2012 @@ -805,8 +805,7 @@ } } - assert(0 && "Invalid expression kind!"); - return 0; + llvm_unreachable("Invalid expression kind!"); } /// ParseExpression - Parse an expression and return it. Modified: llvm/trunk/lib/MC/MCStreamer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/MC/MCStreamer.cpp (original) +++ llvm/trunk/lib/MC/MCStreamer.cpp Mon Feb 6 23:05:23 2012 @@ -600,7 +600,7 @@ } void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { - assert(0 && "This file format doesn't support this directive"); + llvm_unreachable("This file format doesn't support this directive"); } void MCStreamer::EmitFnStart() { Modified: llvm/trunk/lib/Support/ConstantRange.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ConstantRange.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Support/ConstantRange.cpp (original) +++ llvm/trunk/lib/Support/ConstantRange.cpp Mon Feb 6 23:05:23 2012 @@ -55,7 +55,7 @@ uint32_t W = CR.getBitWidth(); switch (Pred) { - default: assert(0 && "Invalid ICmp predicate to makeICmpRegion()"); + default: llvm_unreachable("Invalid ICmp predicate to makeICmpRegion()"); case CmpInst::ICMP_EQ: return CR; case CmpInst::ICMP_NE: Modified: llvm/trunk/lib/Support/Triple.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Triple.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Support/Triple.cpp (original) +++ llvm/trunk/lib/Support/Triple.cpp Mon Feb 6 23:05:23 2012 @@ -459,8 +459,7 @@ bool Valid = false; StringRef Comp = Components[Idx]; switch (Pos) { - default: - assert(false && "unexpected component type!"); + default: llvm_unreachable("unexpected component type!"); case 0: Arch = ParseArch(Comp); Valid = Arch != UnknownArch; @@ -618,7 +617,7 @@ getOSVersion(Major, Minor, Micro); switch (getOS()) { - default: assert(0 && "unexpected OS for Darwin triple"); + default: llvm_unreachable("unexpected OS for Darwin triple"); case Darwin: // Default to darwin8, i.e., MacOSX 10.4. if (Major == 0) Modified: llvm/trunk/lib/TableGen/Record.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/Record.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/TableGen/Record.cpp (original) +++ llvm/trunk/lib/TableGen/Record.cpp Mon Feb 6 23:05:23 2012 @@ -942,7 +942,7 @@ int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue(); int64_t Result; switch (getOpcode()) { - default: assert(0 && "Bad opcode!"); + default: llvm_unreachable("Bad opcode!"); case SHL: Result = LHSv << RHSv; break; case SRA: Result = LHSv >> RHSv; break; case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break; Modified: llvm/trunk/lib/TableGen/TGParser.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/TableGen/TGParser.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/TableGen/TGParser.cpp (original) +++ llvm/trunk/lib/TableGen/TGParser.cpp Mon Feb 6 23:05:23 2012 @@ -729,7 +729,7 @@ RecTy *Type = 0; switch (Lex.getCode()) { - default: assert(0 && "Unhandled code!"); + default: llvm_unreachable("Unhandled code!"); case tgtok::XCast: Lex.Lex(); // eat the operation Code = UnOpInit::CAST; @@ -845,7 +845,7 @@ RecTy *Type = 0; switch (OpTok) { - default: assert(0 && "Unhandled code!"); + default: llvm_unreachable("Unhandled code!"); case tgtok::XConcat: Code = BinOpInit::CONCAT;Type = DagRecTy::get(); break; case tgtok::XSRA: Code = BinOpInit::SRA; Type = IntRecTy::get(); break; case tgtok::XSRL: Code = BinOpInit::SRL; Type = IntRecTy::get(); break; @@ -909,7 +909,7 @@ tgtok::TokKind LexCode = Lex.getCode(); Lex.Lex(); // eat the operation switch (LexCode) { - default: assert(0 && "Unhandled code!"); + default: llvm_unreachable("Unhandled code!"); case tgtok::XIf: Code = TernOpInit::IF; break; @@ -954,7 +954,7 @@ Lex.Lex(); // eat the ')' switch (LexCode) { - default: assert(0 && "Unhandled code!"); + default: llvm_unreachable("Unhandled code!"); case tgtok::XIf: { // FIXME: The `!if' operator doesn't handle non-TypedInit well at // all. This can be made much more robust. Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Mon Feb 6 23:05:23 2012 @@ -110,7 +110,7 @@ InstCombiner::BuilderTy *Builder) { CmpInst::Predicate Pred; switch (code) { - default: assert(0 && "Illegal FCmp code!"); + default: llvm_unreachable("Illegal FCmp code!"); case 0: Pred = isordered ? FCmpInst::FCMP_ORD : FCmpInst::FCMP_UNO; break; case 1: Pred = isordered ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_UGT; break; case 2: Pred = isordered ? FCmpInst::FCMP_OEQ : FCmpInst::FCMP_UEQ; break; Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp (original) +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineShifts.cpp Mon Feb 6 23:05:23 2012 @@ -199,7 +199,7 @@ IC.Worklist.Add(I); switch (I->getOpcode()) { - default: assert(0 && "Inconsistency with CanEvaluateShifted"); + default: llvm_unreachable("Inconsistency with CanEvaluateShifted"); case Instruction::And: case Instruction::Or: case Instruction::Xor: Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Mon Feb 6 23:05:23 2012 @@ -703,8 +703,7 @@ if (ShadowRedzoneSize == 4) return (PoisonByte << 24) + (PoisonByte << 16) + (PoisonByte << 8) + (PoisonByte); - assert(0 && "ShadowRedzoneSize is either 1, 2 or 4"); - return 0; + llvm_unreachable("ShadowRedzoneSize is either 1, 2 or 4"); } static void PoisonShadowPartialRightRedzone(uint8_t *Shadow, Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Mon Feb 6 23:05:23 2012 @@ -224,7 +224,7 @@ IntrinsicInst *II = cast(I); switch (II->getIntrinsicID()) { - default: assert(0 && "doesn't pass 'hasMemoryWrite' predicate"); + default: llvm_unreachable("doesn't pass 'hasMemoryWrite' predicate"); case Intrinsic::lifetime_end: // Never remove dead lifetime_end's, e.g. because it is followed by a // free. @@ -268,7 +268,7 @@ IntrinsicInst *II = cast(I); switch (II->getIntrinsicID()) { - default: assert(false && "Unexpected intrinsic!"); + default: llvm_unreachable("Unexpected intrinsic!"); case Intrinsic::init_trampoline: return II->getArgOperand(0); } Modified: llvm/trunk/lib/Transforms/Utils/CmpInstAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/CmpInstAnalysis.cpp?rev=149967&r1=149966&r2=149967&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Utils/CmpInstAnalysis.cpp (original) +++ llvm/trunk/lib/Transforms/Utils/CmpInstAnalysis.cpp Mon Feb 6 23:05:23 2012 @@ -72,7 +72,7 @@ Value *llvm::getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS, CmpInst::Predicate &NewICmpPred) { switch (Code) { - default: assert(0 && "Illegal ICmp code!"); + default: llvm_unreachable("Illegal ICmp code!"); case 0: // False. return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0); case 1: NewICmpPred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break; From nicholas at mxc.ca Mon Feb 6 23:11:06 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Mon, 06 Feb 2012 21:11:06 -0800 Subject: [llvm-commits] [llvm] r149874 - in /llvm/trunk: include/llvm/Analysis/DIBuilder.h include/llvm/Analysis/DebugInfo.h lib/Analysis/DIBuilder.cpp lib/Analysis/DebugInfo.cpp lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp In-Reply-To: <20120206174943.F41EC2A6C12C@llvm.org> References: <20120206174943.F41EC2A6C12C@llvm.org> Message-ID: <4F30B26A.80602@mxc.ca> Devang Patel wrote: > Author: dpatel > Date: Mon Feb 6 11:49:43 2012 > New Revision: 149874 > > URL: http://llvm.org/viewvc/llvm-project?rev=149874&view=rev > Log: > DebugInfo: Provide a new hook to encode relationship between a property and an ivar. > Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=149874&r1=149873&r2=149874&view=diff > ============================================================================== > --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original) > +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Mon Feb 6 11:49:43 2012 > @@ -851,6 +851,12 @@ > if (PropertyAttributes) > addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0, > PropertyAttributes); > + > + DIEEntry *Entry = getDIEEntry(Element); > + if (!Entry) { > + Entry = createDIEEntry(ElemDie); > + insertDIEEntry(Element, Entry); > + } > } else Tab! Nick From craig.topper at gmail.com Tue Feb 7 00:28:43 2012 From: craig.topper at gmail.com (Craig Topper) Date: Tue, 07 Feb 2012 06:28:43 -0000 Subject: [llvm-commits] [llvm] r149968 - in /llvm/trunk: lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td test/CodeGen/X86/avx-shuffle.ll test/CodeGen/X86/avx-splat.ll test/CodeGen/X86/avx-vpermil.ll Message-ID: <20120207062843.6072E2A6C12C@llvm.org> Author: ctopper Date: Tue Feb 7 00:28:42 2012 New Revision: 149968 URL: http://llvm.org/viewvc/llvm-project?rev=149968&view=rev Log: Add instruction selection for 256-bit VPSHUFD and 128-bit VPERMILPS/VPERMILPD. Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrSSE.td llvm/trunk/test/CodeGen/X86/avx-shuffle.ll llvm/trunk/test/CodeGen/X86/avx-splat.ll llvm/trunk/test/CodeGen/X86/avx-vpermil.ll Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=149968&r1=149967&r2=149968&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Tue Feb 7 00:28:42 2012 @@ -3713,7 +3713,7 @@ /// type is 32 or 64. In the VPERMILPS the high half of the mask should point /// to the same elements of the low, but to the higher half of the source. /// In VPERMILPD the two lanes could be shuffled independently of each other -/// with the same restriction that lanes can't be crossed. +/// with the same restriction that lanes can't be crossed. Also handles PSHUFDY. static bool isVPERMILPMask(ArrayRef Mask, EVT VT, bool HasAVX) { if (!HasAVX) return false; @@ -6467,6 +6467,9 @@ unsigned TargetMask = X86::getShuffleSHUFImmediate(SVOp); + if (HasAVX && (VT == MVT::v4f32 || VT == MVT::v2f64)) + return getTargetShuffleNode(X86ISD::VPERMILP, dl, VT, V1, TargetMask, DAG); + if (HasSSE2 && (VT == MVT::v4f32 || VT == MVT::v4i32)) return getTargetShuffleNode(X86ISD::PSHUFD, dl, VT, V1, TargetMask, DAG); @@ -6636,9 +6639,13 @@ return getTargetShuffleNode(X86ISD::MOVDDUP, dl, VT, V1, DAG); // Handle VPERMILPS/D* permutations - if (isVPERMILPMask(M, VT, HasAVX)) + if (isVPERMILPMask(M, VT, HasAVX)) { + if (HasAVX2 && VT == MVT::v8i32) + return getTargetShuffleNode(X86ISD::PSHUFD, dl, VT, V1, + X86::getShuffleSHUFImmediate(SVOp), DAG); return getTargetShuffleNode(X86ISD::VPERMILP, dl, VT, V1, X86::getShuffleSHUFImmediate(SVOp), DAG); + } // Handle VPERM2F128/VPERM2I128 permutations if (isVPERM2X128Mask(M, VT, HasAVX)) Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=149968&r1=149967&r2=149968&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Tue Feb 7 00:28:42 2012 @@ -3993,21 +3993,19 @@ (undef))))]>; } -multiclass sse2_pshuffle_y { +multiclass sse2_pshuffle_y { def Yri : Ii8<0x70, MRMSrcReg, (outs VR256:$dst), (ins VR256:$src1, i8imm:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (vt (pshuf_frag:$src2 VR256:$src1, - (undef))))]>; + [(set VR256:$dst, (vt (OpNode VR256:$src1, (i8 imm:$src2))))]>; def Ymi : Ii8<0x70, MRMSrcMem, (outs VR256:$dst), (ins i256mem:$src1, i8imm:$src2), !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), - [(set VR256:$dst, (vt (pshuf_frag:$src2 - (bc_frag (memopv4i64 addr:$src1)), - (undef))))]>; + [(set VR256:$dst, + (vt (OpNode (bitconvert (memopv4i64 addr:$src1)), + (i8 imm:$src2))))]>; } } // ExeDomain = SSEPackedInt @@ -4053,17 +4051,9 @@ } let Predicates = [HasAVX2] in { - let AddedComplexity = 5 in - defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, pshufd, bc_v8i32>, TB, - OpSize, VEX; - - // SSE2 with ImmT == Imm8 and XS prefix. - defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, pshufhw, bc_v16i16>, XS, - VEX; - - // SSE2 with ImmT == Imm8 and XD prefix. - defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, pshuflw, bc_v16i16>, XD, - VEX; + defm VPSHUFD : sse2_pshuffle_y<"vpshufd", v8i32, X86PShufd>, TB, OpSize, VEX; + defm VPSHUFHW : sse2_pshuffle_y<"vpshufhw", v16i16, X86PShufhw>, XS, VEX; + defm VPSHUFLW : sse2_pshuffle_y<"vpshuflw", v16i16, X86PShuflw>, XD, VEX; } let Predicates = [HasSSE2] in { @@ -4226,9 +4216,9 @@ // Splat v2f64 / v2i64 let AddedComplexity = 10 in { def : Pat<(splat_lo (v2i64 VR128:$src), (undef)), - (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>; - def : Pat<(splat_lo (v2i64 VR128:$src), (undef)), (VPUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasAVX]>; + def : Pat<(splat_lo (v2i64 VR128:$src), (undef)), + (PUNPCKLQDQrr VR128:$src, VR128:$src)>, Requires<[HasSSE2]>; } //===---------------------------------------------------------------------===// @@ -7200,6 +7190,19 @@ (VPERMILPSYmi addr:$src1, imm:$imm)>; def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), (VPERMILPDYmi addr:$src1, imm:$imm)>; + +def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), + (VPERMILPSri VR128:$src1, imm:$imm)>; +def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), + (VPERMILPDri VR128:$src1, imm:$imm)>; +def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), + (VPERMILPDri VR128:$src1, imm:$imm)>; +def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), + (VPERMILPSmi addr:$src1, imm:$imm)>; +def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), + (VPERMILPDmi addr:$src1, imm:$imm)>; +def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), + (VPERMILPDmi addr:$src1, imm:$imm)>; } //===----------------------------------------------------------------------===// Modified: llvm/trunk/test/CodeGen/X86/avx-shuffle.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-shuffle.ll?rev=149968&r1=149967&r2=149968&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/avx-shuffle.ll (original) +++ llvm/trunk/test/CodeGen/X86/avx-shuffle.ll Tue Feb 7 00:28:42 2012 @@ -6,7 +6,7 @@ ret <4 x float> %b ; CHECK: test1: ; CHECK: vshufps -; CHECK: vpshufd +; CHECK: vpermilps } ; rdar://10538417 @@ -98,22 +98,40 @@ } define <4 x float> @test11(<4 x float> %a) nounwind { -; CHECK: pshufd $27 +; check: test11 +; check: vpermilps $27 %tmp1 = shufflevector <4 x float> %a, <4 x float> undef, <4 x i32> ret <4 x float> %tmp1 } define <4 x float> @test12(<4 x float>* %a) nounwind { -; CHECK: pshufd $27, ( +; CHECK: test12 +; CHECK: vpermilps $27, ( %tmp0 = load <4 x float>* %a %tmp1 = shufflevector <4 x float> %tmp0, <4 x float> undef, <4 x i32> ret <4 x float> %tmp1 } -;CHECK: test13 -;CHECK: shufd -;CHECK: ret -define <4 x i32> @test13(<2 x i32>%x) nounwind readnone { +define <4 x i32> @test13(<4 x i32> %a) nounwind { +; check: test13 +; check: vpshufd $27 + %tmp1 = shufflevector <4 x i32> %a, <4 x i32> undef, <4 x i32> + ret <4 x i32> %tmp1 +} + +define <4 x i32> @test14(<4 x i32>* %a) nounwind { +; CHECK: test14 +; CHECK: vpshufd $27, ( + %tmp0 = load <4 x i32>* %a + %tmp1 = shufflevector <4 x i32> %tmp0, <4 x i32> undef, <4 x i32> + ret <4 x i32> %tmp1 +} + +; CHECK: test15 +; CHECK: vpshufd $8 +; CHECK: ret +define <4 x i32> @test15(<2 x i32>%x) nounwind readnone { %x1 = shufflevector <2 x i32> %x, <2 x i32> undef, <4 x i32> ret <4 x i32>%x1 } + Modified: llvm/trunk/test/CodeGen/X86/avx-splat.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-splat.ll?rev=149968&r1=149967&r2=149968&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/avx-splat.ll (original) +++ llvm/trunk/test/CodeGen/X86/avx-splat.ll Tue Feb 7 00:28:42 2012 @@ -32,7 +32,7 @@ ret <4 x i64> %vecinit6.i } -; CHECK: vshufpd $0 +; CHECK: vpermilpd $0 ; CHECK-NEXT: vinsertf128 $1 define <4 x double> @funcD(double %q) nounwind uwtable readnone ssp { entry: Modified: llvm/trunk/test/CodeGen/X86/avx-vpermil.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-vpermil.ll?rev=149968&r1=149967&r2=149968&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/avx-vpermil.ll (original) +++ llvm/trunk/test/CodeGen/X86/avx-vpermil.ll Tue Feb 7 00:28:42 2012 @@ -45,7 +45,7 @@ ret <8 x float> %shuffle } -; CHECK-NOT: vpermilps +; CHECK: vpermilps define <8 x float> @funcF(<8 x float> %a) nounwind uwtable readnone ssp { entry: %shuffle = shufflevector <8 x float> %a, <8 x float> zeroinitializer, <8 x i32> From evan.cheng at apple.com Tue Feb 7 01:09:28 2012 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 07 Feb 2012 07:09:28 -0000 Subject: [llvm-commits] [llvm] r149970 - /llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Message-ID: <20120207070928.AAE362A6C12C@llvm.org> Author: evancheng Date: Tue Feb 7 01:09:28 2012 New Revision: 149970 URL: http://llvm.org/viewvc/llvm-project?rev=149970&view=rev Log: Do not fold ADD / SUB into load / store (to form pre-indexed, post-indexed load / store) if the ADD / SUB has a live definition of CPSR. Bug reported by David Meyer. Alas, no test case. Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Modified: llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp?rev=149970&r1=149969&r2=149970&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMLoadStoreOptimizer.cpp Tue Feb 7 01:09:28 2012 @@ -497,50 +497,84 @@ return; } -static inline bool isMatchingDecrement(MachineInstr *MI, unsigned Base, - unsigned Bytes, unsigned Limit, - ARMCC::CondCodes Pred, unsigned PredReg){ +static bool definesCPSR(MachineInstr *MI) { + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg()) + continue; + if (MO.isDef() && MO.getReg() == ARM::CPSR && !MO.isDead()) + // If the instruction has live CPSR def, then it's not safe to fold it + // into load / store. + return true; + } + + return false; +} + +static bool isMatchingDecrement(MachineInstr *MI, unsigned Base, + unsigned Bytes, unsigned Limit, + ARMCC::CondCodes Pred, unsigned PredReg) { unsigned MyPredReg = 0; if (!MI) return false; - if (MI->getOpcode() != ARM::t2SUBri && - MI->getOpcode() != ARM::tSUBspi && - MI->getOpcode() != ARM::SUBri) - return false; + + bool CheckCPSRDef = false; + switch (MI->getOpcode()) { + default: return false; + case ARM::t2SUBri: + case ARM::SUBri: + CheckCPSRDef = true; + // fallthrough + case ARM::tSUBspi: + break; + } // Make sure the offset fits in 8 bits. if (Bytes == 0 || (Limit && Bytes >= Limit)) return false; unsigned Scale = (MI->getOpcode() == ARM::tSUBspi) ? 4 : 1; // FIXME - return (MI->getOperand(0).getReg() == Base && - MI->getOperand(1).getReg() == Base && - (MI->getOperand(2).getImm()*Scale) == Bytes && - llvm::getInstrPredicate(MI, MyPredReg) == Pred && - MyPredReg == PredReg); + if (!(MI->getOperand(0).getReg() == Base && + MI->getOperand(1).getReg() == Base && + (MI->getOperand(2).getImm()*Scale) == Bytes && + llvm::getInstrPredicate(MI, MyPredReg) == Pred && + MyPredReg == PredReg)) + return false; + + return CheckCPSRDef ? !definesCPSR(MI) : true; } -static inline bool isMatchingIncrement(MachineInstr *MI, unsigned Base, - unsigned Bytes, unsigned Limit, - ARMCC::CondCodes Pred, unsigned PredReg){ +static bool isMatchingIncrement(MachineInstr *MI, unsigned Base, + unsigned Bytes, unsigned Limit, + ARMCC::CondCodes Pred, unsigned PredReg) { unsigned MyPredReg = 0; if (!MI) return false; - if (MI->getOpcode() != ARM::t2ADDri && - MI->getOpcode() != ARM::tADDspi && - MI->getOpcode() != ARM::ADDri) - return false; + + bool CheckCPSRDef = false; + switch (MI->getOpcode()) { + default: return false; + case ARM::t2ADDri: + case ARM::ADDri: + CheckCPSRDef = true; + // fallthrough + case ARM::tADDspi: + break; + } if (Bytes == 0 || (Limit && Bytes >= Limit)) // Make sure the offset fits in 8 bits. return false; unsigned Scale = (MI->getOpcode() == ARM::tADDspi) ? 4 : 1; // FIXME - return (MI->getOperand(0).getReg() == Base && - MI->getOperand(1).getReg() == Base && - (MI->getOperand(2).getImm()*Scale) == Bytes && - llvm::getInstrPredicate(MI, MyPredReg) == Pred && - MyPredReg == PredReg); + if (!(MI->getOperand(0).getReg() == Base && + MI->getOperand(1).getReg() == Base && + (MI->getOperand(2).getImm()*Scale) == Bytes && + llvm::getInstrPredicate(MI, MyPredReg) == Pred && + MyPredReg == PredReg)) + return false; + + return CheckCPSRDef ? !definesCPSR(MI) : true; } static inline unsigned getLSMultipleTransferSize(MachineInstr *MI) { From anat.shemer at intel.com Tue Feb 7 02:18:05 2012 From: anat.shemer at intel.com (Anat Shemer) Date: Tue, 07 Feb 2012 08:18:05 -0000 Subject: [llvm-commits] [llvm] r149971 - /llvm/trunk/README.txt Message-ID: <20120207081805.E6FD82A6C12C@llvm.org> Author: ashemer Date: Tue Feb 7 02:18:05 2012 New Revision: 149971 URL: http://llvm.org/viewvc/llvm-project?rev=149971&view=rev Log: test commit Modified: llvm/trunk/README.txt Modified: llvm/trunk/README.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/README.txt?rev=149971&r1=149970&r2=149971&view=diff ============================================================================== --- llvm/trunk/README.txt (original) +++ llvm/trunk/README.txt Tue Feb 7 02:18:05 2012 @@ -14,3 +14,4 @@ If you're writing a package for LLVM, see docs/Packaging.html for our suggestions. + From baldrick at free.fr Tue Feb 7 02:30:44 2012 From: baldrick at free.fr (Duncan Sands) Date: Tue, 07 Feb 2012 09:30:44 +0100 Subject: [llvm-commits] [llvm] r149914 - /llvm/trunk/docs/ReleaseNotes.html In-Reply-To: <20120206215944.E84D72A6C12C@llvm.org> References: <20120206215944.E84D72A6C12C@llvm.org> Message-ID: <4F30E134.3010700@free.fr> Hi Bill, > --- llvm/trunk/docs/ReleaseNotes.html (original) > +++ llvm/trunk/docs/ReleaseNotes.html Mon Feb 6 15:59:44 2012 > @@ -285,7 +285,10 @@ > >
      >
    • IR support for half float
    • > -
    • IR support for vectors of pointers, including vector GEPs.
    • > +
    • IR support for vectors of pointers, including vector GEPs.
    • > +
    • Theunwind instruction is now gone. It has been replaced by > + thelandingpad/resume exception handling > + mechanisms.
    • I reckon the mention of the landingpad/resume scheme will just confuse people. Probably most people thought of unwind as a way of throwing an exception (rather than a way of rethrowing an exception), and the new scheme doesn't replace that functionality at all. Ciao, Duncan. From isanbard at gmail.com Tue Feb 7 02:42:30 2012 From: isanbard at gmail.com (Bill Wendling) Date: Tue, 07 Feb 2012 08:42:30 -0000 Subject: [llvm-commits] [llvm] r149972 - /llvm/trunk/docs/ReleaseNotes.html Message-ID: <20120207084230.6EB2A2A6C12D@llvm.org> Author: void Date: Tue Feb 7 02:42:29 2012 New Revision: 149972 URL: http://llvm.org/viewvc/llvm-project?rev=149972&view=rev Log: Rephrase to add clarity. Modified: llvm/trunk/docs/ReleaseNotes.html Modified: llvm/trunk/docs/ReleaseNotes.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/ReleaseNotes.html?rev=149972&r1=149971&r2=149972&view=diff ============================================================================== --- llvm/trunk/docs/ReleaseNotes.html (original) +++ llvm/trunk/docs/ReleaseNotes.html Tue Feb 7 02:42:29 2012 @@ -286,9 +286,9 @@
      • IR support for half float
      • IR support for vectors of pointers, including vector GEPs.
      • -
      • The unwind instruction is now gone. It has been replaced by - the landingpad/resume exception handling - mechanisms.
      • +
      • The unwind instruction is now gone. With the introduction of + the new exception handling system in LLVM 3.0, the unwind + instruction became obsolete.
      • ....
      From wendling at apple.com Tue Feb 7 02:47:50 2012 From: wendling at apple.com (Bill Wendling) Date: Tue, 07 Feb 2012 00:47:50 -0800 Subject: [llvm-commits] [llvm] r149914 - /llvm/trunk/docs/ReleaseNotes.html In-Reply-To: <4F30E134.3010700@free.fr> References: <20120206215944.E84D72A6C12C@llvm.org> <4F30E134.3010700@free.fr> Message-ID: <5DDF06F4-7493-47FB-A347-1E5976634BE6@apple.com> On Feb 7, 2012, at 12:30 AM, Duncan Sands wrote: > Hi Bill, > >> --- llvm/trunk/docs/ReleaseNotes.html (original) >> +++ llvm/trunk/docs/ReleaseNotes.html Mon Feb 6 15:59:44 2012 >> @@ -285,7 +285,10 @@ >> >>
        >>
      • IR support for half float
      • >> -
      • IR support for vectors of pointers, including vector GEPs.
      • >> +
      • IR support for vectors of pointers, including vector GEPs.
      • >> +
      • Theunwind instruction is now gone. It has been replaced by >> + thelandingpad/resume exception handling >> + mechanisms.
      • > > I reckon the mention of the landingpad/resume scheme will just confuse people. > Probably most people thought of unwind as a way of throwing an exception (rather > than a way of rethrowing an exception), and the new scheme doesn't replace that > functionality at all. > Okay. I rephrased it for clarity. It's not easy to give an explanation for removing an instruction which didn't have very good semantics in the first place. :-) -bw From baldrick at free.fr Tue Feb 7 02:48:59 2012 From: baldrick at free.fr (Duncan Sands) Date: Tue, 07 Feb 2012 09:48:59 +0100 Subject: [llvm-commits] [llvm] r149914 - /llvm/trunk/docs/ReleaseNotes.html In-Reply-To: <5DDF06F4-7493-47FB-A347-1E5976634BE6@apple.com> References: <20120206215944.E84D72A6C12C@llvm.org> <4F30E134.3010700@free.fr> <5DDF06F4-7493-47FB-A347-1E5976634BE6@apple.com> Message-ID: <4F30E57B.6010404@free.fr> > Okay. I rephrased it for clarity. It's not easy to give an explanation for removing an instruction which didn't have very good semantics in the first place. :-) Not to mention that only the interpreter ever supported throwing exceptions with it! Ciao, Duncan. From baldrick at free.fr Tue Feb 7 04:28:56 2012 From: baldrick at free.fr (Duncan Sands) Date: Tue, 07 Feb 2012 10:28:56 -0000 Subject: [llvm-commits] [dragonegg] r149978 - /dragonegg/trunk/src/Convert.cpp Message-ID: <20120207102856.EF8C52A6C12C@llvm.org> Author: baldrick Date: Tue Feb 7 04:28:56 2012 New Revision: 149978 URL: http://llvm.org/viewvc/llvm-project?rev=149978&view=rev Log: Help out the clang static analyser (it thinks there may be a null pointer dereference in "!nm || ISDIGIT (*nm)"). Modified: dragonegg/trunk/src/Convert.cpp Modified: dragonegg/trunk/src/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=149978&r1=149977&r2=149978&view=diff ============================================================================== --- dragonegg/trunk/src/Convert.cpp (original) +++ dragonegg/trunk/src/Convert.cpp Tue Feb 7 04:28:56 2012 @@ -7509,6 +7509,7 @@ ConstraintStr += ",~{memory}"; break; default: // Normal register name. + assert(RegName && "Null register name successfully decoded!"); RegName = LLVM_GET_REG_NAME(RegName, RegCode); ConstraintStr += ",~{"; ConstraintStr += RegName; From geek4civic at gmail.com Tue Feb 7 04:53:20 2012 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 07 Feb 2012 10:53:20 -0000 Subject: [llvm-commits] [llvm] r149980 - /llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Message-ID: <20120207105320.2078E2A6C12C@llvm.org> Author: chapuni Date: Tue Feb 7 04:53:19 2012 New Revision: 149980 URL: http://llvm.org/viewvc/llvm-project?rev=149980&view=rev Log: Bitcode/BitstreamReader.h: Tweak for big endian hosts. Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149980&r1=149979&r2=149980&view=diff ============================================================================== --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Feb 7 04:53:19 2012 @@ -17,6 +17,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/Bitcode/BitCodes.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/StreamableMemoryObject.h" #include #include @@ -242,12 +243,13 @@ } uint32_t getWord(size_t pos) { - uint32_t word = -1; + uint8_t buf[sizeof(uint32_t)]; + memset(buf, 0xFF, sizeof(buf)); BitStream->getBitcodeBytes().readBytes(pos, - sizeof(word), - reinterpret_cast(&word), + sizeof(buf), + buf, NULL); - return word; + return *reinterpret_cast(buf); } bool AtEndOfStream() { From baldrick at free.fr Tue Feb 7 05:41:58 2012 From: baldrick at free.fr (Duncan Sands) Date: Tue, 07 Feb 2012 12:41:58 +0100 Subject: [llvm-commits] [llvm] r149980 - /llvm/trunk/include/llvm/Bitcode/BitstreamReader.h In-Reply-To: <20120207105320.2078E2A6C12C@llvm.org> References: <20120207105320.2078E2A6C12C@llvm.org> Message-ID: <4F310E06.8070700@free.fr> Hi Takumi, > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Feb 7 04:53:19 2012 > @@ -17,6 +17,7 @@ > > #include "llvm/ADT/OwningPtr.h" > #include "llvm/Bitcode/BitCodes.h" > +#include "llvm/Support/Endian.h" > #include "llvm/Support/StreamableMemoryObject.h" > #include > #include > @@ -242,12 +243,13 @@ > } > > uint32_t getWord(size_t pos) { > - uint32_t word = -1; > + uint8_t buf[sizeof(uint32_t)]; > + memset(buf, 0xFF, sizeof(buf)); > BitStream->getBitcodeBytes().readBytes(pos, > - sizeof(word), > - reinterpret_cast(&word), > + sizeof(buf), > + buf, > NULL); why did you need to introduce buf? I don't see how it differs from using word. > - return word; > + return *reinterpret_cast(buf); Presumably this is where the real content of the change is. Does it work if you use &word rather than buf here? Ciao, Duncan. From samsonov at google.com Tue Feb 7 06:30:28 2012 From: samsonov at google.com (samsonov at google.com) Date: Tue, 07 Feb 2012 12:30:28 +0000 Subject: [llvm-commits] PATCH: AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf3074b31ebcbf4a04b85ef13d@google.com> Reviewers: kcc, ramosian.glider, timurrrr_at_google_com, Please review this at http://codereview.appspot.com/5642046/ Affected files: M Makefile.mk M Makefile.old M asan_interceptors.cc M asan_interceptors.h M asan_mac.cc M asan_malloc_mac.cc A interception/Makefile.mk A interception/interception.h A interception/interception_linux.cc A interception/interception_mac.cc -------------- next part -------------- Index: Makefile.mk =================================================================== --- Makefile.mk (revision 149970) +++ Makefile.mk (working copy) @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# ModuleName := asan -SubDirs := mach_override +SubDirs := interception mach_override Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) ObjNames := $(Sources:%.cc=%.o) Index: Makefile.old =================================================================== --- Makefile.old (revision 149970) +++ Makefile.old (working copy) @@ -178,6 +178,7 @@ asan_stats.h \ asan_thread.h \ asan_thread_registry.h \ + interception/interception.h \ mach_override/mach_override.h LIBASAN_OBJ=$(BIN)/asan_rtl$(SUFF).o \ @@ -195,6 +196,8 @@ $(BIN)/asan_stats$(SUFF).o \ $(BIN)/asan_thread$(SUFF).o \ $(BIN)/asan_thread_registry$(SUFF).o \ + $(BIN)/interception/interception_linux$(SUFF).o \ + $(BIN)/interception/interception_mac$(SUFF).o \ $(BIN)/mach_override/mach_override$(SUFF).o GTEST_ROOT=third_party/googletest @@ -226,6 +229,7 @@ $(BIN): mkdir -p $(BIN) + mkdir -p $(BIN)/interception mkdir -p $(BIN)/mach_override clang: @@ -329,6 +333,7 @@ lint: third_party/cpplint/cpplint.py --filter=$(LLVM_LINT_FILTER) $(ADDRESS_SANITIZER_CPP) third_party/cpplint/cpplint.py --filter=$(RTL_LINT_FITLER) asan_*.cc asan_*.h + third_party/cpplint/cpplint.py --filter=$(RTL_LINT_FITLER) interception/interception*.h interception/interception*.cc third_party/cpplint/cpplint.py --filter=$(TEST_LINT_FITLER) tests/*.cc get_third_party: Index: asan_interceptors.cc =================================================================== --- asan_interceptors.cc (revision 149970) +++ asan_interceptors.cc (working copy) @@ -21,75 +21,23 @@ #include "asan_stack.h" #include "asan_stats.h" #include "asan_thread_registry.h" +#include "interception/interception.h" #include #include #ifndef _WIN32 -#include #include -#endif +#endif // _WIN32 -// To replace weak system functions on Linux we just need to declare functions -// with same names in our library and then obtain the real function pointers -// using dlsym(). This is not so on Mac OS, where the two-level namespace makes -// our replacement functions invisible to other libraries. This may be overcomed -// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared -// libraries in Chromium were noticed when doing so. -// Instead we use mach_override, a handy framework for patching functions at -// runtime. To avoid possible name clashes, our replacement functions have -// the "wrap_" prefix on Mac. -// -// After interception, the calls to system functions will be substituted by -// calls to our interceptors. We store pointers to system function f() -// in __asan::real_f(). #if defined(__APPLE__) -// Include the declarations of the original functions. +// FIXME(samsonov): Gradually replace system headers with declarations of +// intercepted functions. #include #include #include +#endif // __APPLE__ -#include "mach_override/mach_override.h" - -#define OVERRIDE_FUNCTION(oldfunc, newfunc) \ - do {CHECK(0 == __asan_mach_override_ptr_custom((void*)(oldfunc), \ - (void*)(newfunc), \ - (void**)&real_##oldfunc, \ - __asan_allocate_island, \ - __asan_deallocate_island)); \ - CHECK(real_##oldfunc != NULL); } while (0) - -#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc) \ - do { __asan_mach_override_ptr_custom((void*)(oldfunc), \ - (void*)(newfunc), \ - (void**)&real_##oldfunc, \ - __asan_allocate_island, \ - __asan_deallocate_island); \ - } while (0) - -#define INTERCEPT_FUNCTION(func) \ - OVERRIDE_FUNCTION(func, WRAP(func)) - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - OVERRIDE_FUNCTION_IF_EXISTS(func, WRAP(func)) - -#elif defined(_WIN32) -// TODO(timurrrr): change these macros once we decide how to intercept -// functions on Windows. -#define INTERCEPT_FUNCTION(func) \ - do { } while (0) - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - do { } while (0) - -#else // __linux__ -#define INTERCEPT_FUNCTION(func) \ - CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func))); - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - do { real_##func = (func##_f)dlsym(RTLD_NEXT, #func); } while (0) -#endif - namespace __asan { // Instruments read/write access to a single byte in memory. @@ -581,12 +529,12 @@ namespace __asan { void InitializeAsanInterceptors() { #ifndef __APPLE__ - INTERCEPT_FUNCTION(index); + CHECK(INTERCEPT_FUNCTION(index)); #else - OVERRIDE_FUNCTION(index, WRAP(strchr)); + CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); #endif - INTERCEPT_FUNCTION(memcmp); - INTERCEPT_FUNCTION(memmove); + CHECK(INTERCEPT_FUNCTION(memcmp)); + CHECK(INTERCEPT_FUNCTION(memmove)); #ifdef __APPLE__ // Wrap memcpy() on OS X 10.6 only, because on 10.7 memcpy() and memmove() // are resolved into memmove$VARIANT$sse42. @@ -594,44 +542,44 @@ // TODO(glider): need to check dynamically that memcpy() and memmove() are // actually the same function. if (GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD) { - INTERCEPT_FUNCTION(memcpy); + CHECK(INTERCEPT_FUNCTION(memcpy)); } else { real_memcpy = real_memmove; } #else // Always wrap memcpy() on non-Darwin platforms. - INTERCEPT_FUNCTION(memcpy); + CHECK(INTERCEPT_FUNCTION(memcpy)); #endif - INTERCEPT_FUNCTION(memset); - INTERCEPT_FUNCTION(strcasecmp); - INTERCEPT_FUNCTION(strcat); // NOLINT - INTERCEPT_FUNCTION(strchr); - INTERCEPT_FUNCTION(strcmp); - INTERCEPT_FUNCTION(strcpy); // NOLINT - INTERCEPT_FUNCTION(strdup); - INTERCEPT_FUNCTION(strlen); - INTERCEPT_FUNCTION(strncasecmp); - INTERCEPT_FUNCTION(strncmp); - INTERCEPT_FUNCTION(strncpy); + CHECK(INTERCEPT_FUNCTION(memset)); + CHECK(INTERCEPT_FUNCTION(strcasecmp)); + CHECK(INTERCEPT_FUNCTION(strcat)); // NOLINT + CHECK(INTERCEPT_FUNCTION(strchr)); + CHECK(INTERCEPT_FUNCTION(strcmp)); + CHECK(INTERCEPT_FUNCTION(strcpy)); // NOLINT + CHECK(INTERCEPT_FUNCTION(strdup)); + CHECK(INTERCEPT_FUNCTION(strlen)); + CHECK(INTERCEPT_FUNCTION(strncasecmp)); + CHECK(INTERCEPT_FUNCTION(strncmp)); + CHECK(INTERCEPT_FUNCTION(strncpy)); - INTERCEPT_FUNCTION(sigaction); - INTERCEPT_FUNCTION(signal); - INTERCEPT_FUNCTION(longjmp); - INTERCEPT_FUNCTION(_longjmp); - INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw); - INTERCEPT_FUNCTION(pthread_create); + CHECK(INTERCEPT_FUNCTION(sigaction)); + CHECK(INTERCEPT_FUNCTION(signal)); + CHECK(INTERCEPT_FUNCTION(longjmp)); + CHECK(INTERCEPT_FUNCTION(_longjmp)); + INTERCEPT_FUNCTION(__cxa_throw); + CHECK(INTERCEPT_FUNCTION(pthread_create)); #ifdef __APPLE__ - INTERCEPT_FUNCTION(dispatch_async_f); - INTERCEPT_FUNCTION(dispatch_sync_f); - INTERCEPT_FUNCTION(dispatch_after_f); - INTERCEPT_FUNCTION(dispatch_barrier_async_f); - INTERCEPT_FUNCTION(dispatch_group_async_f); + CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_after_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_barrier_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_group_async_f)); // We don't need to intercept pthread_workqueue_additem_np() to support the // libdispatch API, but it helps us to debug the unsupported functions. Let's // intercept it only during verbose runs. if (FLAG_v >= 2) { - INTERCEPT_FUNCTION(pthread_workqueue_additem_np); + CHECK(INTERCEPT_FUNCTION(pthread_workqueue_additem_np)); } // Normally CFStringCreateCopy should not copy constant CF strings. // Replacing the default CFAllocator causes constant strings to be copied @@ -640,15 +588,15 @@ // http://code.google.com/p/address-sanitizer/issues/detail?id=10 // Until this problem is fixed we need to check that the string is // non-constant before calling CFStringCreateCopy. - INTERCEPT_FUNCTION(CFStringCreateCopy); + CHECK(INTERCEPT_FUNCTION(CFStringCreateCopy)); #else // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it // there. - INTERCEPT_FUNCTION(siglongjmp); + CHECK(INTERCEPT_FUNCTION(siglongjmp)); #endif #ifndef __APPLE__ - INTERCEPT_FUNCTION(strnlen); + CHECK(INTERCEPT_FUNCTION(strnlen)); #endif if (FLAG_v > 0) { Printf("AddressSanitizer: libc interceptors initialized\n"); Index: asan_interceptors.h =================================================================== --- asan_interceptors.h (revision 149970) +++ asan_interceptors.h (working copy) @@ -15,67 +15,8 @@ #define ASAN_INTERCEPTORS_H #include "asan_internal.h" +#include "interception/interception.h" -// Suppose you need to wrap/replace system function (generally, from libc): -// int foo(const char *bar, double baz); -// You'll need to: -// 1) define INTERCEPT(int, foo, const char *bar, double baz) { ... } -// 2) add a line "INTERCEPT_FUNCTION(foo)" to InitializeAsanInterceptors() -// You can access original function by calling __asan::real_foo(bar, baz). -// By defualt, real_foo will be visible only inside your interceptor, and if -// you want to use it in other parts of RTL, you'll need to: -// 3a) add DECLARE_REAL(int, foo, const char*, double); to a -// header file. -// However, if you want to implement your interceptor somewhere outside -// asan_interceptors.cc, you'll instead need to: -// 3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double); -// to a header. - -#if defined(__APPLE__) -# define WRAP(x) wrap_##x -# define WRAPPER_NAME(x) "wrap_"#x -# define INTERCEPTOR_ATTRIBUTE -#elif defined(_WIN32) -// TODO(timurrrr): we're likely to use something else later on Windows. -# define WRAP(x) wrap_##x -# define WRAPPER_NAME(x) #x -# define INTERCEPTOR_ATTRIBUTE -#else -# define WRAP(x) x -# define WRAPPER_NAME(x) #x -# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) -#endif - -#define REAL(x) real_##x -#define FUNC_TYPE(x) x##_f - -#define DECLARE_REAL(ret_type, func, ...); \ - typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ - namespace __asan { \ - extern FUNC_TYPE(func) REAL(func); \ - } - -#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...); \ - DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ - extern "C" \ - ret_type WRAP(func)(__VA_ARGS__); - -// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR -// macros does its job. In exceptional cases you may need to call REAL(foo) -// without defining INTERCEPTOR(..., foo, ...). For example, if you override -// foo with interceptor for other function. -#define DEFINE_REAL(ret_type, func, ...); \ - typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ - namespace __asan { \ - FUNC_TYPE(func) REAL(func); \ - } - -#define INTERCEPTOR(ret_type, func, ...); \ - DEFINE_REAL(ret_type, func, __VA_ARGS__); \ - extern "C" \ - INTERCEPTOR_ATTRIBUTE \ - ret_type WRAP(func)(__VA_ARGS__) - DECLARE_REAL(int, memcmp, const void *a1, const void *a2, size_t size); DECLARE_REAL(void*, memcpy, void *to, const void *from, size_t size); DECLARE_REAL(void*, memset, void *block, int c, size_t size); Index: asan_mac.cc =================================================================== --- asan_mac.cc (revision 149970) +++ asan_mac.cc (working copy) @@ -36,8 +36,6 @@ namespace __asan { -void *island_allocator_pos = NULL; - void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp) { ucontext_t *ucontext = (ucontext_t*)context; # if __WORDSIZE == 64 @@ -314,47 +312,6 @@ } } -// The range of pages to be used by __asan_mach_override_ptr for escape -// islands. -// TODO(glider): instead of mapping a fixed range we must find a range of -// unmapped pages in vmmap and take them. -// These constants were chosen empirically and may not work if the shadow -// memory layout changes. Unfortunately they do necessarily depend on -// kHighMemBeg or kHighMemEnd. -#if __WORDSIZE == 32 -#define kIslandEnd (0xffdf0000 - kPageSize) -#define kIslandBeg (kIslandEnd - 256 * kPageSize) -#else -#define kIslandEnd (0x7fffffdf0000 - kPageSize) -#define kIslandBeg (kIslandEnd - 256 * kPageSize) -#endif - -extern "C" -mach_error_t __asan_allocate_island(void **ptr, - size_t unused_size, - void *unused_hint) { - if (!island_allocator_pos) { - island_allocator_pos = - asan_mmap((void*)kIslandBeg, kIslandEnd - kIslandBeg, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, - -1, 0); - if (island_allocator_pos != (void*)kIslandBeg) { - return KERN_NO_SPACE; - } - }; - *ptr = island_allocator_pos; - island_allocator_pos = (char*)island_allocator_pos + kPageSize; - return err_none; -} - -extern "C" -mach_error_t __asan_deallocate_island(void *ptr) { - // Do nothing. - // TODO(glider): allow to free and reuse the island memory. - return err_none; -} - // Support for the following functions from libdispatch on Mac OS: // dispatch_async_f() // dispatch_async() Index: interception/Makefile.mk =================================================================== --- interception/Makefile.mk (revision 0) +++ interception/Makefile.mk (revision 0) @@ -0,0 +1,22 @@ +#===- lib/asan/interception/Makefile.mk --------------------*- Makefile -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# + +ModuleName := asan +SubDirs := + +Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) +ObjNames := $(Sources:%.cc=%.o) + +Implementation := Generic + +# FIXME: use automatic dependencies? +Dependencies := $(wildcard $(Dir)/*.h) + +# Define a convenience variable for all the asan functions. +AsanFunctions += $(Sources:%.cc=%) Index: interception/interception_linux.cc =================================================================== --- interception/interception_linux.cc (revision 0) +++ interception/interception_linux.cc (revision 0) @@ -0,0 +1,22 @@ +// Copyright 2012 Google Inc. All Rights Reserved. +// Author: samsonov at google.com (Alexey Samsonov) + +#ifdef __linux__ + +#include "interception.h" +#include // for dlsym + +extern "C" +bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { + // not implemented + return false; +} + +extern "C" +bool GetRealFunctionAddress(const char *func_name, + void **func_addr) { + *func_addr = dlsym(RTLD_NEXT, func_name); + return (*func_addr != NULL); +} + +#endif // __linux__ Index: interception/interception_mac.cc =================================================================== --- interception/interception_mac.cc (revision 0) +++ interception/interception_mac.cc (revision 0) @@ -0,0 +1,83 @@ +//===-- interception_mac.cc -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Mac-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef __APPLE__ + +#include "interception.h" +#include "../mach_override/mach_override.h" +#include // for NULL +#include // for mmap + +// The range of pages to be used by __asan_mach_override_ptr for escape +// islands. +// TODO(glider): instead of mapping a fixed range we must find a range of +// unmapped pages in vmmap and take them. +// These constants were chosen empirically and may not work if the shadow +// memory layout changes. Unfortunately they do necessarily depend on +// kHighMemBeg or kHighMemEnd. +static const size_t kPageSizeBits = 12; +static const size_t kPageSize = 1UL << kPageSizeBits; +static void *island_allocator_pos = NULL; + +#if __WORDSIZE == 32 +# define kIslandEnd (0xffdf0000 - kPageSize) +# define kIslandBeg (kIslandEnd - 256 * kPageSize) +#else +# define kIslandEnd (0x7fffffdf0000 - kPageSize) +# define kIslandBeg (kIslandEnd - 256 * kPageSize) +#endif + +extern "C" +mach_error_t __asan_allocate_island(void **ptr, + size_t unused_size, + void *unused_hint) { + if (!island_allocator_pos) { + island_allocator_pos = + mmap((void*)kIslandBeg, kIslandEnd - kIslandBeg, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, + -1, 0); + if (island_allocator_pos != (void*)kIslandBeg) { + return KERN_NO_SPACE; + } + }; + *ptr = island_allocator_pos; + island_allocator_pos = (char*)island_allocator_pos + kPageSize; + return err_none; +} + +extern "C" +mach_error_t __asan_deallocate_island(void *ptr) { + // Do nothing. + // TODO(glider): allow to free and reuse the island memory. + return err_none; +} + +extern "C" +bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { + *orig_old_func = NULL; + int res = __asan_mach_override_ptr_custom(old_func, new_func, + orig_old_func, + __asan_allocate_island, + __asan_deallocate_island); + return (res == 0) && (*orig_old_func != NULL); +} + +extern "C" +bool GetRealFunctionAddress(const char *func_name, void **func_addr) { + // not implemented + return false; +} + +#endif // __APPLE__ Index: interception/interception.h =================================================================== --- interception/interception.h (revision 0) +++ interception/interception.h (revision 0) @@ -0,0 +1,117 @@ +//===-- interception.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Machinery for providing replacements/wrappers for system functions. +//===----------------------------------------------------------------------===// + +#ifndef INTERCEPTION_H +#define INTERCEPTION_H + +// How to use: +// Suppose you need to wrap/replace system function (generally, from libc): +// int foo(const char *bar, double baz); +// You'll need to: +// 1) define INTERCEPTOR(int, foo, const char *bar, double baz) { ... } in +// your source file. +// 2) Call "INTERCEPT_FUNCTION(foo)" prior to the first call of "foo". +// INTERCEPT_FUNCTION(foo) evaluates to "true" iff the function was +// intercepted successfully. +// You can access original function by calling REAL(foo)(bar, baz). +// By defualt, REAL(foo) will be visible only inside your interceptor, and if +// you want to use it in other parts of RTL, you'll need to: +// 3a) add DECLARE_REAL(int, foo, const char*, double); to a +// header file. +// However, if you want to implement your interceptor somewhere outside +// asan_interceptors.cc, you'll instead need to: +// 3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double); +// to a header. + +// Notes: 1. Things may not work properly if macro INTERCEPT(...) {...} or +// DECLARE_REAL(...); will be located inside namespaces. +// 2. On Mac you can also use: "OVERRIDE_FUNCTION(foo, zoo);" to +// effectively redirect calls from "foo" to "zoo". In this case +// you aren't required to implement +// INTERCEPTOR(int, foo, const char *bar, double baz); +// but instead you'll have to add +// DEFINE_REAL(int, foo, const char *bar, double baz); in your +// source file (to define a pointer to overriden function). + +// How it works: +// To replace weak system functions on Linux we just need to declare functions +// with same names in our library and then obtain the real function pointers +// using dlsym(). This is not so on Mac OS, where the two-level namespace makes +// our replacement functions invisible to other libraries. This may be overcomed +// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared +// libraries in Chromium were noticed when doing so. +// Instead we use mach_override, a handy framework for patching functions at +// runtime. To avoid possible name clashes, our replacement functions have +// the "wrap_" prefix on Mac. + +#if defined(__APPLE__) +# define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) "wrap_"#x +# define INTERCEPTOR_ATTRIBUTE +#elif defined(_WIN32) +// TODO(timurrrr): we're likely to use something else later on Windows. +# define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) #x +# define INTERCEPTOR_ATTRIBUTE +#else +# define WRAP(x) x +# define WRAPPER_NAME(x) #x +# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) +#endif + +#define REAL(x) real_##x +#define FUNC_TYPE(x) x##_f + +#define DECLARE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + extern FUNC_TYPE(func) REAL(func); + +#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...); \ + DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ + extern "C" ret_type WRAP(func)(__VA_ARGS__); + +// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR +// macros does its job. In exceptional cases you may need to call REAL(foo) +// without defining INTERCEPTOR(..., foo, ...). For example, if you override +// foo with interceptor for other function. +#define DEFINE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + FUNC_TYPE(func) REAL(func); + +#define INTERCEPTOR(ret_type, func, ...) \ + DEFINE_REAL(ret_type, func, __VA_ARGS__); \ + extern "C" \ + INTERCEPTOR_ATTRIBUTE \ + ret_type WRAP(func)(__VA_ARGS__) + +extern "C" { +// returns true if the old function existed. +bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); +// returns true if a function with the given name was found. +bool GetRealFunctionAddress(const char *func_name, void **func_addr); +} // extern "C" + +#if defined(__linux__) +# define INTERCEPT_FUNCTION(func) \ + GetRealFunctionAddress(#func, (void**)&REAL(func)) +#elif defined(__APPLE__) +# define OVERRIDE_FUNCTION(old_func, new_func) \ + OverrideFunction((void*)old_func, (void*)new_func, (void**)&REAL(old_func)) +# define INTERCEPT_FUNCTION(func) OVERRIDE_FUNCTION(func, WRAP(func)) +#else // defined(_WIN32) + // FIXME: deal with interception on Win. +# define INTERCEPT_FUNCTON(func) true +#endif + +#endif // INTERCEPTION_H Index: asan_malloc_mac.cc =================================================================== --- asan_malloc_mac.cc (revision 149970) +++ asan_malloc_mac.cc (working copy) @@ -310,7 +310,7 @@ namespace __asan { void ReplaceSystemMalloc() { static malloc_introspection_t asan_introspection; - __asan::real_memset(&asan_introspection, 0, sizeof(asan_introspection)); + REAL(memset)(&asan_introspection, 0, sizeof(asan_introspection)); asan_introspection.enumerator = &mi_enumerator; asan_introspection.good_size = &mi_good_size; @@ -321,7 +321,7 @@ asan_introspection.force_unlock = &mi_force_unlock; static malloc_zone_t asan_zone; - __asan::real_memset(&asan_zone, 0, sizeof(malloc_zone_t)); + REAL(memset)(&asan_zone, 0, sizeof(malloc_zone_t)); // Start with a version 4 zone which is used for OS X 10.4 and 10.5. asan_zone.version = 4; From timurrrr at google.com Tue Feb 7 06:39:16 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Tue, 07 Feb 2012 12:39:16 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf30334a452e7f9b04b85f1168@google.com> http://codereview.appspot.com/5642046/diff/1/interception/interception.h File interception/interception.h (right): http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode38 interception/interception.h:38: // DECLARE_REAL(...); will be located inside namespaces. "if ... are", not "if ... will be ..." http://codereview.appspot.com/5642046/ From timurrrr at google.com Tue Feb 7 06:51:08 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Tue, 07 Feb 2012 12:51:08 +0000 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) Message-ID: <20cf3074b182a4ed2f04b85f3b0f@google.com> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 lib/asan/asan_internal.h:24: # include On 2012/02/06 19:18:31, kcc wrote: > Can we avoid this include in the header? > ( I am not sure we can, just asking) I doubt so. Or we'll need to #include it in every file which uses GET_CURRENT_PC or GET_BP_PC_SP. Following the "include what you use" rule, we have to include here. http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode218 lib/asan/asan_internal.h:218: (uintptr_t)__builtin_extract_return_address(__builtin_return_address(0)) The other one works too, but up to you (reverted) On 2012/02/06 19:18:31, kcc wrote: > I'd keep this as as, it works. http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode222 lib/asan/asan_internal.h:222: // TODO(timurrrr): We don't unwind on Windows - do we need this? On 2012/02/06 19:18:31, kcc wrote: > What do you mean "we don't unwind"? > Also, better use FIXME instead of TODO(user) Done. http://codereview.appspot.com/5630065/ From glider at google.com Tue Feb 7 07:14:29 2012 From: glider at google.com (glider at google.com) Date: Tue, 07 Feb 2012 13:14:29 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf3074b44018ea3304b85f8fe9@google.com> 2 general comments: 1. You'll need to get rid of all the ASanish stuff in these files. This is a bit tricky on Mac, so I'm not insisting on factoring out the branch island allocator now. 2. Please keep interception.h clean. You don't need to put anything but the macros intended to be used by the clients there. http://codereview.appspot.com/5642046/diff/1/interception/interception.h File interception/interception.h (right): http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode33 interception/interception.h:33: // asan_interceptors.cc, you'll instead need to: Please rewrite this comment without mentioning ASan. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode87 interception/interception.h:87: // foo with interceptor for other function. "with an interceptor" http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode100 interception/interception.h:100: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); You should not need these functions in the interface header. Moreover, you don't need to define them for each platform. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode102 interception/interception.h:102: bool GetRealFunctionAddress(const char *func_name, void **func_addr); Any reason not to return the address instead of bool here? http://codereview.appspot.com/5642046/diff/1/interception/interception_linux.cc File interception/interception_linux.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_linux.cc#newcode10 interception/interception_linux.cc:10: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { Please remove this function. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc File interception/interception_mac.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode18 interception/interception_mac.cc:18: #include "../mach_override/mach_override.h" Please put mach_override/ under interception/ as the former should now become a part of the latter. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode34 interception/interception_mac.cc:34: # define kIslandEnd (0xffdf0000 - kPageSize) This stuff is in fact ASan-dependent and may not work with TSan. We need to implement those __asan_[de]allocate_island routines in each tool. And they certainly should not have the "__asan" prefix. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode71 interception/interception_mac.cc:71: orig_old_func, mach_override_ptr_custom should have a custom prefix, too. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode79 interception/interception_mac.cc:79: // not implemented Please remove this function. http://codereview.appspot.com/5642046/ From geek4civic at gmail.com Tue Feb 7 07:54:46 2012 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Tue, 7 Feb 2012 22:54:46 +0900 Subject: [llvm-commits] [llvm] r149980 - /llvm/trunk/include/llvm/Bitcode/BitstreamReader.h In-Reply-To: <4F310E06.8070700@free.fr> References: <20120207105320.2078E2A6C12C@llvm.org> <4F310E06.8070700@free.fr> Message-ID: Duncan, thank you to review mine. 2012/2/7 Duncan Sands : > Hi Takumi, > >> --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) >> +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Tue Feb ?7 04:53:19 2012 >> @@ -17,6 +17,7 @@ >> >> ? #include "llvm/ADT/OwningPtr.h" >> ? #include "llvm/Bitcode/BitCodes.h" >> +#include "llvm/Support/Endian.h" >> ? #include "llvm/Support/StreamableMemoryObject.h" >> ? #include >> ? #include >> @@ -242,12 +243,13 @@ >> ? ? } >> >> ? ? uint32_t getWord(size_t pos) { >> - ? ?uint32_t word = -1; >> + ? ?uint8_t buf[sizeof(uint32_t)]; >> + ? ?memset(buf, 0xFF, sizeof(buf)); >> ? ? ? BitStream->getBitcodeBytes().readBytes(pos, >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(word), >> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? reinterpret_cast(&word), >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(buf), >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buf, >> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?NULL); > > why did you need to introduce buf? ?I don't see how it differs from > using word. > >> - ? ?return word; >> + ? ?return *reinterpret_cast(buf); > > Presumably this is where the real content of the change is. ?Does it work > if you use &word rather than buf here? In my tweaks, I have not satisfied strict-aliasing (on g++) with uint32_t nor ulittle32_t. It is a reason why I introduced uint8_t[4]. I am dubious Support/Endian.h might not be ready for compatibility to strict-aliasing in some cases. In this case, I could implement without ulittle32_t but packing 4x uint_8s manually. Anyway, feel free to rework if anyone would know smarter resolution, thank you. ...Takumi From baldrick at free.fr Tue Feb 7 08:06:18 2012 From: baldrick at free.fr (Duncan Sands) Date: Tue, 07 Feb 2012 14:06:18 -0000 Subject: [llvm-commits] [zorg] r149985 - /zorg/trunk/buildbot/osuosl/master/config/builders.py Message-ID: <20120207140618.B27412A6C12C@llvm.org> Author: baldrick Date: Tue Feb 7 08:06:18 2012 New Revision: 149985 URL: http://llvm.org/viewvc/llvm-project?rev=149985&view=rev Log: Workaround the lack of dragonegg support for GCC's "target" function attribute by building for the best possible processor rather than i386. Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/buildbot/osuosl/master/config/builders.py?rev=149985&r1=149984&r2=149985&view=diff ============================================================================== --- zorg/trunk/buildbot/osuosl/master/config/builders.py (original) +++ zorg/trunk/buildbot/osuosl/master/config/builders.py Tue Feb 7 08:06:18 2012 @@ -318,7 +318,8 @@ 'factory' : DragonEggBuilder.getDragonEggBootstrapFactory(gcc_repository='http://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch at 183339', extra_languages=['fortran', 'objc', 'obj-c++'], extra_gcc_configure_args=['--disable-bootstrap', '--enable-checking'], - extra_llvm_configure_args=['--enable-optimized', '--enable-assertions']), + extra_llvm_configure_args=['--enable-optimized', '--enable-assertions'], + env={ 'CFLAGS' : '-march=native' }), 'category' : 'dragonegg'}, {'name' : "dragonegg-x86_64-linux-gcc-4.6-self-host", From samsonov at google.com Tue Feb 7 08:31:32 2012 From: samsonov at google.com (samsonov at google.com) Date: Tue, 07 Feb 2012 14:31:32 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf3074b182b32ad304b860a2c6@google.com> http://codereview.appspot.com/5642046/diff/1/interception/interception.h File interception/interception.h (right): http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode33 interception/interception.h:33: // asan_interceptors.cc, you'll instead need to: On 2012/02/07 13:14:29, glider wrote: > Please rewrite this comment without mentioning ASan. Done. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode38 interception/interception.h:38: // DECLARE_REAL(...); will be located inside namespaces. On 2012/02/07 12:39:16, timurrrr_at_google_com wrote: > "if ... are", > not > "if ... will be ..." Done. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode87 interception/interception.h:87: // foo with interceptor for other function. On 2012/02/07 13:14:29, glider wrote: > "with an interceptor" Done. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode100 interception/interception.h:100: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); On 2012/02/07 13:14:29, glider wrote: > You should not need these functions in the interface header. Not sure. When the macros expand, the actual code in ASan RTL will have calls to OverrideFunction(...), so we need to add them to some headers anyway. > Moreover, you don't need to define them for each platform. Done, although I don't like the idea of different sets of functions present in header for each platform. http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode102 interception/interception.h:102: bool GetRealFunctionAddress(const char *func_name, void **func_addr); On 2012/02/07 13:14:29, glider wrote: > Any reason not to return the address instead of bool here? To simplify a macro to a plain function call and avoid casts. http://codereview.appspot.com/5642046/diff/1/interception/interception_linux.cc File interception/interception_linux.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_linux.cc#newcode10 interception/interception_linux.cc:10: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { On 2012/02/07 13:14:29, glider wrote: > Please remove this function. Done. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc File interception/interception_mac.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode18 interception/interception_mac.cc:18: #include "../mach_override/mach_override.h" On 2012/02/07 13:14:29, glider wrote: > Please put mach_override/ under interception/ as the former should now become a > part of the latter. Added a FIXME. I'd rather do this in other commit. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode34 interception/interception_mac.cc:34: # define kIslandEnd (0xffdf0000 - kPageSize) On 2012/02/07 13:14:29, glider wrote: > This stuff is in fact ASan-dependent and may not work with TSan. We need to > implement those __asan_[de]allocate_island routines in each tool. And they > certainly should not have the "__asan" prefix. Right. Returned island allocation to asan_mac.cc and did a re-naming. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode71 interception/interception_mac.cc:71: orig_old_func, On 2012/02/07 13:14:29, glider wrote: > mach_override_ptr_custom should have a custom prefix, too. So, you'd need different mach_override_ptr for each tool? (disregarding custom allocate/deallocate island) http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode79 interception/interception_mac.cc:79: // not implemented On 2012/02/07 13:14:29, glider wrote: > Please remove this function. Done. http://codereview.appspot.com/5642046/ From timurrrr at google.com Tue Feb 7 08:32:22 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Tue, 07 Feb 2012 14:32:22 +0000 Subject: [llvm-commits] Explicitly say that everything is OK at the end of the 'test' rule (issue 5645045) Message-ID: <20cf3074d8dcadb43104b860a552@google.com> Reviewers: kcc1, Message: Hi, Can you please review this tiny patch? While testing ASan with "-j" I've noticed that intermediate test failures are very hard to notice. I think it's good to have an explicit green light sign at the end of "make test" Thanks, Timur Please review this at http://codereview.appspot.com/5645045/ Affected files: M Makefile.old Index: Makefile.old =================================================================== --- Makefile.old (revision 149985) +++ Makefile.old (working copy) @@ -205,6 +205,7 @@ all: b64 b32 test: t64 t32 output_tests lint + @echo "ALL TESTS PASSED" output_tests: b32 b64 cd tests && ./test_output.sh $(CLANG_CXX) $(CLANG_CC) From andy.zhang at intel.com Tue Feb 7 09:11:28 2012 From: andy.zhang at intel.com (Zhang, Andy) Date: Tue, 7 Feb 2012 15:11:28 +0000 Subject: [llvm-commits] [PATCH] Intel Atom optimization - use LEA to adjust stack pointer In-Reply-To: <5C9B2DB6AAFD914E864AF9803780B66A010CC4@FMSMSX108.amr.corp.intel.com> References: <9A83F73AEA08BB46A2799C5D4C16BFED011A38BC09@rrsmsx509.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66A7EAC@FMSMSX108.amr.corp.intel.com> <5CED04BC-2514-4235-9364-9FFB13E415EE@2pi.dk> <5C9B2DB6AAFD914E864AF9803780B66A976F@FMSMSX108.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66AAACF@FMSMSX108.amr.corp.intel.com> <44458013-AAF2-4D59-AE66-BFCFCFBF63FE@apple.com> <5C9B2DB6AAFD914E864AF9803780B66AB1CD@FMSMSX108.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66A010CC4@FMSMSX108.amr.corp.intel.com> Message-ID: <5C9B2DB6AAFD914E864AF9803780B66A01181D@FMSMSX108.amr.corp.intel.com> Ping... > -----Original Message----- > From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits- > bounces at cs.uiuc.edu] On Behalf Of Zhang, Andy > Sent: Thursday, February 02, 2012 2:33 PM > To: llvm-commits at cs.uiuc.edu > Subject: Re: [llvm-commits] Intel Atom optimization - use LEA to adjust > stack pointer > > On January 18, 2012 4:35 PM, Evan Cheng wrote: > > > > Yes, that's the right way to use subtarget features. If the number of > > Atom specific optimizations get too large, then we can refactor it. > > > > Evan > > > > Hi Evan, > > I've changed my patch to use a separate subtarget feature for this > optimization. > Sorry for the delay -- I was away for the past couple of weeks. > > If there are no more comments, could you please commit the patch. > > > Thanks, > Andy From ojab at ojab.ru Tue Feb 7 04:50:12 2012 From: ojab at ojab.ru (ojab) Date: Tue, 7 Feb 2012 13:50:12 +0300 Subject: [llvm-commits] Add InitializeNativeTargetDisassembler function In-Reply-To: References: Message-ID: Hello, can I have review? //wbr ojab On Wed, Feb 1, 2012 at 9:48 AM, ojab wrote: > Hello, > > I would be useful to have InitializeNativeTargetDisassembler() function to > initialize the native target disassembler, similar to > InitializeNativeTargetAsmPrinter/InitializeNativeTargetAsmParser/etc, patch > in the attached file. > > //wbr ojab > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/f23e06dc/attachment.html From greened at obbligato.org Tue Feb 7 10:13:11 2012 From: greened at obbligato.org (David A. Greene) Date: Tue, 07 Feb 2012 10:13:11 -0600 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <86294DCD-DBAD-4949-B054-1E5D5CF4C329@2pi.dk> (Jakob Stoklund Olesen's message of "Mon, 06 Feb 2012 15:01:04 -0800") Message-ID: <87mx8uvcyw.fsf@smith.obbligato.org> Jakob Stoklund Olesen writes: > On Feb 6, 2012, at 8:57 AM, David A. Greene wrote: > >>> When resubmitting, please squash everything into one patch. >> >> Are you sure? > > Yes. Ok. >> Incremental development is the preferred approach. > > You misunderstand the concept. It does not mean you should dump your git branch on the mailing list. > > It means you should get your changes reviewed and committed incrementally. > > I think it is explained quite well here: > > http://llvm.org/docs/DeveloperPolicy.html#newwork > http://llvm.org/docs/DeveloperPolicy.html#incremental I tried to follow this guide. For example, making the "setup" changes before turning the feature on. Obviously I misunderstood. I'll try harder next time. -Dave From benny.kra at googlemail.com Tue Feb 7 10:27:39 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 07 Feb 2012 16:27:39 -0000 Subject: [llvm-commits] [llvm] r149986 - /llvm/trunk/unittests/ADT/APIntTest.cpp Message-ID: <20120207162739.74F8A2A6C12C@llvm.org> Author: d0k Date: Tue Feb 7 10:27:39 2012 New Revision: 149986 URL: http://llvm.org/viewvc/llvm-project?rev=149986&view=rev Log: Add a unittest for rotating a really big APInt. Clang miscompiles it under certain circumstances, and it's a good exercise for APInt. Modified: llvm/trunk/unittests/ADT/APIntTest.cpp Modified: llvm/trunk/unittests/ADT/APIntTest.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/APIntTest.cpp?rev=149986&r1=149985&r2=149986&view=diff ============================================================================== --- llvm/trunk/unittests/ADT/APIntTest.cpp (original) +++ llvm/trunk/unittests/ADT/APIntTest.cpp Tue Feb 7 10:27:39 2012 @@ -480,6 +480,10 @@ EXPECT_EQ(APInt(8, 64), APInt(8, 1).rotr(2)); EXPECT_EQ(APInt(8, 16), APInt(8, 1).rotr(4)); EXPECT_EQ(APInt(8, 1), APInt(8, 1).rotr(8)); + + APInt Big(256, "00004000800000000000000000003fff8000000000000000", 16); + APInt Rot(256, "3fff80000000000000000000000000000000000040008000", 16); + EXPECT_EQ(Rot, Big.rotr(144)); } } From glider at google.com Tue Feb 7 10:42:36 2012 From: glider at google.com (glider at google.com) Date: Tue, 07 Feb 2012 16:42:36 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf30334a456f3c1604b8627793@google.com> http://codereview.appspot.com/5642046/diff/1/interception/interception.h File interception/interception.h (right): http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode100 interception/interception.h:100: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); #define INTERCEPT_FUNCTION(func) #ifdef __linux__ INTERCEPT_FUNCTION_LINUX(func) #elif __APPLE__ ... WDYT? This won't dictate unnecessary interfaces to the systems that don't need them and will hide this stuff from the user. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc File interception/interception_mac.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode71 interception/interception_mac.cc:71: orig_old_func, On 2012/02/07 14:31:32, samsonov wrote: > On 2012/02/07 13:14:29, glider wrote: > > mach_override_ptr_custom should have a custom prefix, too. > So, you'd need different mach_override_ptr for each tool? (disregarding custom > allocate/deallocate island) We'll need an option to prepend a custom prefix to it. I'll do that later in mach_override (I had asked Jonathan about that, but he hasn't responded yet) http://codereview.appspot.com/5642046/ From kcc at google.com Tue Feb 7 11:36:12 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 09:36:12 -0800 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) In-Reply-To: <20cf3074b182a4ed2f04b85f3b0f@google.com> References: <20cf3074b182a4ed2f04b85f3b0f@google.com> Message-ID: On Tue, Feb 7, 2012 at 4:51 AM, wrote: > > http://codereview.appspot.com/**5630065/diff/1/lib/asan/asan_**internal.h > File lib/asan/asan_internal.h (right): > > http://codereview.appspot.com/**5630065/diff/1/lib/asan/asan_** > internal.h#newcode24 > lib/asan/asan_internal.h:24: # include > On 2012/02/06 19:18:31, kcc wrote: > >> Can we avoid this include in the header? >> ( I am not sure we can, just asking) >> > I doubt so. > Or we'll need to #include it in every file which uses GET_CURRENT_PC or > GET_BP_PC_SP. > Maybe you can find how this thing is defined in intrin.h and use similar definition? --kcc -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/7a53ab1d/attachment.html From kcc at google.com Tue Feb 7 11:36:07 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 07 Feb 2012 17:36:07 -0000 Subject: [llvm-commits] [compiler-rt] r149990 - /compiler-rt/trunk/lib/asan/Makefile.old Message-ID: <20120207173607.438602A6C12C@llvm.org> Author: kcc Date: Tue Feb 7 11:36:07 2012 New Revision: 149990 URL: http://llvm.org/viewvc/llvm-project?rev=149990&view=rev Log: [asan] print 'ALL TESTS PASSED' in makefile when running tests (convenience) Modified: compiler-rt/trunk/lib/asan/Makefile.old Modified: compiler-rt/trunk/lib/asan/Makefile.old URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.old?rev=149990&r1=149989&r2=149990&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/Makefile.old (original) +++ compiler-rt/trunk/lib/asan/Makefile.old Tue Feb 7 11:36:07 2012 @@ -205,6 +205,7 @@ all: b64 b32 test: t64 t32 output_tests lint + @echo "ALL TESTS PASSED" output_tests: b32 b64 cd tests && ./test_output.sh $(CLANG_CXX) $(CLANG_CC) From kcc at google.com Tue Feb 7 11:40:30 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 09:40:30 -0800 Subject: [llvm-commits] Explicitly say that everything is OK at the end of the 'test' rule (issue 5645045) In-Reply-To: <20cf3074d8dcadb43104b860a552@google.com> References: <20cf3074d8dcadb43104b860a552@google.com> Message-ID: r149990, thanks! On Tue, Feb 7, 2012 at 6:32 AM, wrote: > Reviewers: kcc1, > > Message: > Hi, > > Can you please review this tiny patch? > > While testing ASan with "-j" I've noticed that intermediate test > failures are very hard to notice. > I think it's good to have an explicit green light sign at the end of > "make test" > > Thanks, > Timur > > > > Please review this at http://codereview.appspot.com/**5645045/ > > Affected files: > M Makefile.old > > > Index: Makefile.old > ==============================**==============================**======= > --- Makefile.old (revision 149985) > +++ Makefile.old (working copy) > @@ -205,6 +205,7 @@ > all: b64 b32 > > test: t64 t32 output_tests lint > + @echo "ALL TESTS PASSED" > > output_tests: b32 b64 > cd tests && ./test_output.sh $(CLANG_CXX) $(CLANG_CC) > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/864b3ef0/attachment.html From timurrrr at google.com Tue Feb 7 11:41:15 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Tue, 07 Feb 2012 17:41:15 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf3074b1822304aa04b86349b7@google.com> Reviewers: kcc1, Evgeniy Stepanov, glider, Message: Hi, Can you please review this patch? Rationale: on Windows, it's much easier to get function name, source file and source line than obj+offset we use on POSIX (where we have to use an exterenal symbolizer script). I think the old API goes a little bit too much into the details on how things work, so I'm suggesting a slightly more generic API. There's one question inline, see comments. Thanks, Timur http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (left): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_internal.h#oldcode145 lib/asan/asan_internal.h:145: int SNPrint(char *buffer, size_t length, const char *format, ...); This was wrong in the first place http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc File lib/asan/asan_linux.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode216 lib/asan/asan_linux.cc:216: uintptr_t offset; this code is identical to that on Mac, see comment below http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode265 lib/asan/asan_linux.cc:265: if (dl_iterate_phdr(dl_iterate_phdr_callback, &data)) { Alternative suggestion: I can extract this code to IterateForObjectNameAndOffset and move the common AsanProcMaps::DescribeAddress code to asan_posix.cc (we have the same symbolization capabilities on Linux and Mac, right?) WDYT? http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h File lib/asan/asan_procmaps.h (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode30 lib/asan/asan_procmaps.h:30: // and puts it into the given buffer with a leading space I know this may sound a bit confusing, but look at how easy it is to use this function now (asan_stack.cc, which is the only place this is used) Please review this at http://codereview.appspot.com/5643047/ Affected files: M lib/asan/asan_internal.h M lib/asan/asan_linux.cc M lib/asan/asan_mac.cc M lib/asan/asan_procmaps.h M lib/asan/asan_stack.cc Index: lib/asan/asan_internal.h diff --git lib/asan/asan_internal.h lib/asan/asan_internal.h index 041fa3dce803be895a325f1601891bc98bffad92..31842013b64419263a9ba67f8dca30d08cca4fab 100644 --- lib/asan/asan_internal.h +++ lib/asan/asan_internal.h @@ -142,7 +142,7 @@ size_t ReadFileToBuffer(const char *file_name, char **buff, // asan_printf.cc void RawWrite(const char *buffer); -int SNPrint(char *buffer, size_t length, const char *format, ...); +int SNPrintf(char *buffer, size_t length, const char *format, ...); void Printf(const char *format, ...); int SScanf(const char *str, const char *format, ...); void Report(const char *format, ...); Index: lib/asan/asan_linux.cc diff --git lib/asan/asan_linux.cc lib/asan/asan_linux.cc index 01a019eac850c2de05d8204bc068f19e9b25a52a..d530415cc69c459496c6f50a561aebac204f7623 100644 --- lib/asan/asan_linux.cc +++ lib/asan/asan_linux.cc @@ -210,11 +210,16 @@ bool AsanProcMaps::Next(uintptr_t *start, uintptr_t *end, #ifdef __arm__ -// Gets the object name and the offset by walking AsanProcMaps. -bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset, - char filename[], - size_t filename_size) { - return IterateForObjectNameAndOffset(addr, offset, filename, filename_size); +void AsanProcMaps::DescribeAddress(uintptr_t addr, + char out_buffer[], + size_t buffer_size) { + uintptr_t offset; + char objname[4096]; + if (IterateForObjectNameAndOffset(addr, &offset, objname, sizeof(objname))) { + SNPrintf(out_buffer, buffer_size, " (%s+0x%lx)", objname, offset); + } else { + out_buffer[0] = '\0'; + } } #else // __arm__ @@ -248,19 +253,21 @@ static int dl_iterate_phdr_callback(struct dl_phdr_info *info, } // Gets the object name and the offset using dl_iterate_phdr. -bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset, - char filename[], - size_t filename_size) { +void AsanProcMaps::DescribeAddress(uintptr_t addr, + char out_buffer[], + size_t buffer_size) { + char filename[4096]; DlIterateData data; data.count = 0; data.addr = addr; data.filename = filename; - data.filename_size = filename_size; + data.filename_size = sizeof(filename); if (dl_iterate_phdr(dl_iterate_phdr_callback, &data)) { - *offset = data.offset; - return true; + SNPrintf(out_buffer, buffer_size, + " (%s+0x%lx)", data.filename, data.offset); + } else { + out_buffer[0] = '\0'; } - return false; } #endif // __arm__ Index: lib/asan/asan_mac.cc diff --git lib/asan/asan_mac.cc lib/asan/asan_mac.cc index 112aebf8d93b52a9c8c75e516ccd7907afadac44..7832ce8a17722192f87f96cce90733ea6fadc4fa 100644 --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -271,10 +271,16 @@ bool AsanProcMaps::Next(uintptr_t *start, uintptr_t *end, return false; } -bool AsanProcMaps::GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset, - char filename[], - size_t filename_size) { - return IterateForObjectNameAndOffset(addr, offset, filename, filename_size); +void AsanProcMaps::DescribeAddress(uintptr_t addr, + char out_buffer[], + size_t buffer_size) { + uintptr_t offset; + char objname[4096]; + if (IterateForObjectNameAndOffset(addr, &offset, objname, sizeof(objname))) { + SNPrintf(out_buffer, buffer_size, " (%s+0x%lx)", objname, offset); + } else { + out_buffer[0] = '\0'; + } } void AsanThread::SetThreadStackTopAndBottom() { Index: lib/asan/asan_procmaps.h diff --git lib/asan/asan_procmaps.h lib/asan/asan_procmaps.h index 6dd42f9f653610588dca45535371380792516f89..bc5f67b2de033acf4f205101f9a69082ec6bdce3 100644 --- lib/asan/asan_procmaps.h +++ lib/asan/asan_procmaps.h @@ -24,10 +24,13 @@ class AsanProcMaps { bool Next(uintptr_t *start, uintptr_t *end, uintptr_t *offset, char filename[], size_t filename_size); void Reset(); - // Gets the object file name and the offset in that object for a given - // address 'addr'. Returns true on success. - bool GetObjectNameAndOffset(uintptr_t addr, uintptr_t *offset, - char filename[], size_t filename_size); + + // Gets all the information possible for a given address 'addr' + // (object file name, offset, source file name, source line, etc.) + // and puts it into the given buffer with a leading space + // or puts an empty string "" if no information is available. + void DescribeAddress(uintptr_t addr, char out_buffer[], size_t buffer_size); + ~AsanProcMaps(); private: // Default implementation of GetObjectNameAndOffset. Index: lib/asan/asan_stack.cc diff --git lib/asan/asan_stack.cc lib/asan/asan_stack.cc index 9f7469749085b576d8359b927da2c58623773e15..fe83534e8ff96546c09029705e2d94a1af039c00 100644 --- lib/asan/asan_stack.cc +++ lib/asan/asan_stack.cc @@ -42,14 +42,9 @@ void AsanStackTrace::PrintStack(uintptr_t *addr, size_t size) { for (size_t i = 0; i < size && addr[i]; i++) { proc_maps.Reset(); uintptr_t pc = addr[i]; - uintptr_t offset; - char filename[4096]; - if (proc_maps.GetObjectNameAndOffset(pc, &offset, - filename, sizeof(filename))) { - Printf(" #%ld 0x%lx (%s+0x%lx)\n", i, pc, filename, offset); - } else { - Printf(" #%ld 0x%lx\n", i, pc); - } + char descr[4096]; + proc_maps.DescribeAddress(pc, descr, sizeof(descr)); + Printf(" #%ld 0x%lx%s\n", i, pc, descr); } } #endif // ASAN_USE_EXTERNAL_SYMBOLIZER From stoklund at 2pi.dk Tue Feb 7 11:52:05 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 07 Feb 2012 09:52:05 -0800 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <87mx8uvcyw.fsf@smith.obbligato.org> References: <87mx8uvcyw.fsf@smith.obbligato.org> Message-ID: <8C4644C6-E42C-498B-9634-E33EC1E04E5F@2pi.dk> On Feb 7, 2012, at 8:13 AM, greened at obbligato.org (David A. Greene) wrote: > > Jakob Stoklund Olesen writes: >> I think it is explained quite well here: >> >> http://llvm.org/docs/DeveloperPolicy.html#newwork >> http://llvm.org/docs/DeveloperPolicy.html#incremental > > I tried to follow this guide. For example, making the "setup" changes > before turning the feature on. Of course the granularity is a judgment call, but in general, don't submit multiple patches at once. The exception is large mechanical changes like changing constness or namespaces etc. The roundtrip delay on pre-commit reviews makes it necessary to review larger changes than one would normally commit directly. In the present case, I think the granularity you chose is fine: 1. Add a single-variable foreach loop. 2. Zip. If you need to make changes that reach into other parts of the code, they should be submitted and reviewed independently. Always make sure reviewers know why you need to make the change. /jakob From timurrrr at google.com Tue Feb 7 11:56:19 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Tue, 7 Feb 2012 21:56:19 +0400 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) In-Reply-To: References: <20cf3074b182a4ed2f04b85f3b0f@google.com> Message-ID: PTAL, though personally I don't like how it looks now. On Tue, Feb 7, 2012 at 9:36 PM, Kostya Serebryany wrote: > > > On Tue, Feb 7, 2012 at 4:51 AM, wrote: >> >> >> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h >> File lib/asan/asan_internal.h (right): >> >> >> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 >> lib/asan/asan_internal.h:24: # include >> On 2012/02/06 19:18:31, kcc wrote: >>> >>> Can we avoid this include in the header? >>> ( I am not sure we can, just asking) >> >> I doubt so. >> Or we'll need to #include it in every file which uses GET_CURRENT_PC or >> GET_BP_PC_SP. > > > Maybe you can find how this thing is defined in intrin.h and use similar > definition? > > > --kcc From kcc at google.com Tue Feb 7 12:01:04 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 10:01:04 -0800 Subject: [llvm-commits] PATCH: AddressSanitizer: start factoring out interception machinery (issue 5642046) In-Reply-To: <20cf3074b31ebcbf4a04b85ef13d@google.com> References: <20cf3074b31ebcbf4a04b85ef13d@google.com> Message-ID: In general, this is what we need. - Please make sure that the real_* functions reside in a proper namespace. Maybe you will need one more parameter to the macros (namespace name). - The functions from the interception interfaces should reside in some namspace or have a __ prefix (__interception?) - try to resolve FIXME's --kcc On Tue, Feb 7, 2012 at 4:30 AM, wrote: > Reviewers: kcc, ramosian.glider, timurrrr_at_google_com, > > > > Please review this at http://codereview.appspot.com/**5642046/ > > Affected files: > M Makefile.mk > M Makefile.old > M asan_interceptors.cc > M asan_interceptors.h > M asan_mac.cc > M asan_malloc_mac.cc > A interception/Makefile.mk > A interception/interception.h > A interception/interception_**linux.cc > A interception/interception_mac.**cc > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/46ae78df/attachment.html From kcc at google.com Tue Feb 7 12:05:31 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 10:05:31 -0800 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) In-Reply-To: References: <20cf3074b182a4ed2f04b85f3b0f@google.com> Message-ID: Much better. Now, how about using _AddressOfReturnAddress() for the frame? --kcc On Tue, Feb 7, 2012 at 9:56 AM, Timur Iskhodzhanov wrote: > PTAL, > though personally I don't like how it looks now. > > On Tue, Feb 7, 2012 at 9:36 PM, Kostya Serebryany wrote: > > > > > > On Tue, Feb 7, 2012 at 4:51 AM, wrote: > >> > >> > >> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h > >> File lib/asan/asan_internal.h (right): > >> > >> > >> > http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 > >> lib/asan/asan_internal.h:24: # include > >> On 2012/02/06 19:18:31, kcc wrote: > >>> > >>> Can we avoid this include in the header? > >>> ( I am not sure we can, just asking) > >> > >> I doubt so. > >> Or we'll need to #include it in every file which uses GET_CURRENT_PC or > >> GET_BP_PC_SP. > > > > > > Maybe you can find how this thing is defined in intrin.h and use similar > > definition? > > > > > > --kcc > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/806fc65d/attachment.html From dag at cray.com Tue Feb 7 12:08:59 2012 From: dag at cray.com (David A. Greene) Date: Tue, 7 Feb 2012 12:08:59 -0600 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <8C4644C6-E42C-498B-9634-E33EC1E04E5F@2pi.dk> (Jakob Stoklund Olesen's message of "Tue, 7 Feb 2012 11:52:05 -0600") References: <87mx8uvcyw.fsf@smith.obbligato.org> <8C4644C6-E42C-498B-9634-E33EC1E04E5F@2pi.dk> Message-ID: <87ehu6tt1g.fsf@smith.obbligato.org> Jakob Stoklund Olesen writes: > The roundtrip delay on pre-commit reviews makes it necessary to review > larger changes than one would normally commit directly. Ah. I'm assuming I should submit the patch as review, not break it up. Is that right? > In the present case, I think the granularity you chose is fine: 1. Add > a single-variable foreach loop. 2. Zip. Ok. I thought zip was a no-go. I'm going to wait on it anyway while I work out how various things might work. It may or may not come back. > If you need to make changes that reach into other parts of the code, > they should be submitted and reviewed independently. Always make sure > reviewers know why you need to make the change. Sure. Thanks for your help! -Dave From daniel at zuster.org Tue Feb 7 12:14:16 2012 From: daniel at zuster.org (Daniel Dunbar) Date: Tue, 07 Feb 2012 18:14:16 -0000 Subject: [llvm-commits] [zorg] r149993 - /zorg/trunk/zorg/buildbot/builders/LNTBuilder.py Message-ID: <20120207181416.85C7D2A6C12C@llvm.org> Author: ddunbar Date: Tue Feb 7 12:14:16 2012 New Revision: 149993 URL: http://llvm.org/viewvc/llvm-project?rev=149993&view=rev Log: buildbot: Add a sketch of a buildbot builder for running the LLVM test-suite using LNT. Added: zorg/trunk/zorg/buildbot/builders/LNTBuilder.py Added: zorg/trunk/zorg/buildbot/builders/LNTBuilder.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/zorg/buildbot/builders/LNTBuilder.py?rev=149993&view=auto ============================================================================== --- zorg/trunk/zorg/buildbot/builders/LNTBuilder.py (added) +++ zorg/trunk/zorg/buildbot/builders/LNTBuilder.py Tue Feb 7 12:14:16 2012 @@ -0,0 +1,106 @@ +""" +Builders for using LNT to test LLVM/Clang. +""" + +# The URL of our local package cache. +g_package_url = "http://lab.llvm.org/packages" + +def getLNTFactory(triple, nt_flags, xfails=[], clean=True, test=False, + **kwargs): + # Build compiler to test. + f = ClangBuilder.getClangBuildFactory( + triple, outOfDir=True, clean=clean, test=test, + always_install=True, **kwargs) + + # Add an LNT test runner. + AddLNTTestsToFactory(f, nt_flags, + cc_path="llvm.install/bin/clang", + cxx_path="llvm.install/bin/clang++") + + return f + +def AddLNTTestsToFactory(f, nt_flags, cc_path, cxx_path, + parallel = False, jobs = '%(jobs)s'): + """ + Add the buildbot steps necessary to run an LNT driven test of a compiler. + + This assumes at a minimum that the factory has already been set up to + contain a builddir proeprty which points at the full path to the build + directory. + """ + + # Create variables to refer to the compiler-under-test. + # + # We assume any relative paths are relative to the build directory (which + # prior steps will have presumably populated with a compiler). + cc_path = WithProperties(os.path.join('%(builddir)s', cc_path)) + cxx_path = WithProperties(os.path.join'%(builddir)s', cxx_path)) + + # Add --liblto-path if necessary. We assume it will be in a lib directory + # adjacent to cc_path. + # + # FIXME: This is currently only going to work on Darwin. + if '-flto' in nt_flags: + base_directory = os.path.dirname(os.path.dirname(cc_path)) + lnt_flags.extend(['--liblto-path', WithProperties( + os.path.join('%(builddir)s', + os.path.join(base_directory, 'lib', + 'libLTO.dylib')) + + # Get the Zorg sources, for LNT. + f.addStep(SVN(name='pull.zorg', mode='incremental', method='fresh', + baseURL='http://llvm.org/svn/llvm-project/zorg/', + defaultBranch='trunk', workdir='zorg', alwaysUseLatest=True)) + + # Get the LLVM test-suite sources. + f.addStep(SVN(name='pull.test-suite', mode='incremental', method='fresh', + baseURL='http://llvm.org/svn/llvm-project/test-suite/', + defaultBranch='trunk', workdir='test-suite', + alwaysUseLatest=False)) + + # Create the LNT virtual env. + f.addStep(buildbot.steps.shell.ShellCommand( + name='venv.lnt.clean', command=['rm', '-rf', 'lnt.venv'], + haltOnFailure=True, description=['clean', 'LNT', 'venv'], + workdir='%(builddir)s')) + f.addStep(buildbot.steps.shell.ShellCommand( + name='venv.lnt.create', command=['virtualenv', 'lnt.venv'], + haltOnFailure=True, description=['create', 'LNT', 'venv'], + workdir=WithProperties('%(builddir)s'), + env={'PATH' : '${PATH}:/usr/local/bin'})) + f.addStep(buildbot.steps.shell.ShellCommand( + name='venv.lnt.install', haltOnFailure=True, + command=[WithProperties('%(builddir)s/lnt.venv/bin/pip'), 'install', + '--no-index', + '--find-links', g_package_url, + '-e', '.'], + description=['install', 'LNT'], workdir='zorg/lnt', + env={'ARCHFLAGS' : '-arch i386 -arch x86_64'})) + + # Clean up the sandbox dir. + f.addStep(buildbot.steps.shell.ShellCommand( + name='lnt.nightly-test.clean', command=['rm', '-rf', 'nt'], + haltOnFailure=True, description=['clean', 'LNT', 'sandbox'], + workdir='tests')) + + # Run the nightly test. + args = [WithProperties('%(builddir)s/lnt.venv/bin/python'), + WithProperties('%(builddir)s/lnt.venv/bin/lnt'), + 'runtest', '--verbose', + '--submit', 'http://llvm.org/perf/submitRun', + 'nt', '--sandbox', 'nt', + '--cc', cc_path, '--cxx', cxx_path, + '--without-llvm', + '--test-suite', WithProperties('%(builddir)s/test-suite'), + '--no-machdep-info', WithProperties('%(slavename)s')] + if parallel: + args.extend(['-j', WithProperties(jobs)]) + args.extend(nt_flags) + f.addStep(zorg.buildbot.commands.LitTestCommand.LitTestCommand( + name='lnt.nightly-test', command=args, haltOnFailure=True, + description=['nightly test'], workdir='tests', + logfiles={'configure.log' : 'nt/build/configure.log', + 'build-tools.log' : 'nt/build/build-tools.log', + 'test.log' : 'nt/build/test.log', + 'report.json' : 'nt/build/report.json'})) + return f From timurrrr at google.com Tue Feb 7 12:18:52 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Tue, 7 Feb 2012 22:18:52 +0400 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) In-Reply-To: References: <20cf3074b182a4ed2f04b85f3b0f@google.com> Message-ID: On Tue, Feb 7, 2012 at 10:05 PM, Kostya Serebryany wrote: > Much better. > Now, how about using?_AddressOfReturnAddress() for the frame? This will be a separate patch, see the reasoning below. On Windows, the value of GET_CURRENT_FRAME is only used when printing ASan reports and it is named "bp=". (we use CaptureStackBackTrace to get stack traces now, it doesn't require to know bp) _AddressOfReturnAddress returns "ebp+4" on x86, which isn't a problem; (but this might not be true for all the calling conventions? need to check) On x64 however rbp is not used making function calls (tested on helloworld-like app calling foo(), rbp==0!) and _AddressOfReturnAddress actually returns rsp+40 (which is likely to always stay true as there's only one calling convention on Win x64) Also, it's not clear if we need to print ebp at all on Windows in the ASan reports. > --kcc > > > On Tue, Feb 7, 2012 at 9:56 AM, Timur Iskhodzhanov > wrote: >> >> PTAL, >> though personally I don't like how it looks now. >> >> On Tue, Feb 7, 2012 at 9:36 PM, Kostya Serebryany wrote: >> > >> > >> > On Tue, Feb 7, 2012 at 4:51 AM, wrote: >> >> >> >> >> >> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h >> >> File lib/asan/asan_internal.h (right): >> >> >> >> >> >> >> >> http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 >> >> lib/asan/asan_internal.h:24: # include >> >> On 2012/02/06 19:18:31, kcc wrote: >> >>> >> >>> Can we avoid this include in the header? >> >>> ( I am not sure we can, just asking) >> >> >> >> I doubt so. >> >> Or we'll need to #include it in every file which uses GET_CURRENT_PC or >> >> GET_BP_PC_SP. >> > >> > >> > Maybe you can find how this thing is defined in intrin.h and use similar >> > definition? >> > >> > >> > --kcc > > From kcc at google.com Tue Feb 7 12:20:47 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 10:20:47 -0800 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) In-Reply-To: <20cf3074b1822304aa04b86349b7@google.com> References: <20cf3074b1822304aa04b86349b7@google.com> Message-ID: Ok in general. Please define "const int kAsanMaxPath = 4096;" in asan_internal.h and use it everywhere instead of the literal const. Please ask glider@ to review and then commit. --kcc On Tue, Feb 7, 2012 at 9:41 AM, wrote: > Reviewers: kcc1, Evgeniy Stepanov, glider, > > Message: > Hi, > > Can you please review this patch? > > Rationale: on Windows, it's much easier to get function name, source > file and source line than obj+offset we use on POSIX (where we have to > use an exterenal symbolizer script). > I think the old API goes a little bit too much into the details on how > things work, so I'm suggesting a slightly more generic API. > > There's one question inline, see comments. > > Thanks, > Timur > > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_**internal.h > File lib/asan/asan_internal.h (left): > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_** > internal.h#oldcode145 > lib/asan/asan_internal.h:145: int SNPrint(char *buffer, size_t length, > const char *format, ...); > This was wrong in the first place > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_**linux.cc > File lib/asan/asan_linux.cc (right): > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_** > linux.cc#newcode216 > lib/asan/asan_linux.cc:216: uintptr_t offset; > this code is identical to that on Mac, see comment below > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_** > linux.cc#newcode265 > lib/asan/asan_linux.cc:265: if > (dl_iterate_phdr(dl_iterate_**phdr_callback, &data)) { > Alternative suggestion: > I can extract this code to IterateForObjectNameAndOffset > and move the common AsanProcMaps::DescribeAddress code to asan_posix.cc > (we have the same symbolization capabilities on Linux and Mac, right?) > > WDYT? > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_**procmaps.h > File lib/asan/asan_procmaps.h (right): > > http://codereview.appspot.com/**5643047/diff/1/lib/asan/asan_** > procmaps.h#newcode30 > lib/asan/asan_procmaps.h:30: // and puts it into the given buffer with a > leading space > I know this may sound a bit confusing, but look at how easy it is to use > this function now (asan_stack.cc, which is the only place this is used) > > > > Please review this at http://codereview.appspot.com/**5643047/ > > Affected files: > M lib/asan/asan_internal.h > M lib/asan/asan_linux.cc > M lib/asan/asan_mac.cc > M lib/asan/asan_procmaps.h > M lib/asan/asan_stack.cc > > > Index: lib/asan/asan_internal.h > diff --git lib/asan/asan_internal.h lib/asan/asan_internal.h > index 041fa3dce803be895a325f1601891b**c98bffad92..** > 31842013b64419263a9ba67f8dca30**d08cca4fab 100644 > --- lib/asan/asan_internal.h > +++ lib/asan/asan_internal.h > @@ -142,7 +142,7 @@ size_t ReadFileToBuffer(const char *file_name, char > **buff, > > // asan_printf.cc > void RawWrite(const char *buffer); > -int SNPrint(char *buffer, size_t length, const char *format, ...); > +int SNPrintf(char *buffer, size_t length, const char *format, ...); > void Printf(const char *format, ...); > int SScanf(const char *str, const char *format, ...); > void Report(const char *format, ...); > Index: lib/asan/asan_linux.cc > diff --git lib/asan/asan_linux.cc lib/asan/asan_linux.cc > index 01a019eac850c2de05d8204bc068f1**9e9b25a52a..** > d530415cc69c459496c6f50a561aeb**ac204f7623 100644 > --- lib/asan/asan_linux.cc > +++ lib/asan/asan_linux.cc > @@ -210,11 +210,16 @@ bool AsanProcMaps::Next(uintptr_t *start, uintptr_t > *end, > > #ifdef __arm__ > > -// Gets the object name and the offset by walking AsanProcMaps. > -bool AsanProcMaps::**GetObjectNameAndOffset(**uintptr_t addr, uintptr_t > *offset, > - char filename[], > - size_t filename_size) { > - return IterateForObjectNameAndOffset(**addr, offset, filename, > filename_size); > +void AsanProcMaps::DescribeAddress(**uintptr_t addr, > + char out_buffer[], > + size_t buffer_size) { > + uintptr_t offset; > + char objname[4096]; > + if (**IterateForObjectNameAndOffset(**addr, &offset, objname, > sizeof(objname))) { > + SNPrintf(out_buffer, buffer_size, " (%s+0x%lx)", objname, offset); > + } else { > + out_buffer[0] = '\0'; > + } > } > > #else // __arm__ > @@ -248,19 +253,21 @@ static int dl_iterate_phdr_callback(**struct > dl_phdr_info *info, > } > > // Gets the object name and the offset using dl_iterate_phdr. > -bool AsanProcMaps::**GetObjectNameAndOffset(**uintptr_t addr, uintptr_t > *offset, > - char filename[], > - size_t filename_size) { > +void AsanProcMaps::DescribeAddress(**uintptr_t addr, > + char out_buffer[], > + size_t buffer_size) { > + char filename[4096]; > DlIterateData data; > data.count = 0; > data.addr = addr; > data.filename = filename; > - data.filename_size = filename_size; > + data.filename_size = sizeof(filename); > if (dl_iterate_phdr(dl_iterate_**phdr_callback, &data)) { > - *offset = data.offset; > - return true; > + SNPrintf(out_buffer, buffer_size, > + " (%s+0x%lx)", data.filename, data.offset); > + } else { > + out_buffer[0] = '\0'; > } > - return false; > } > > #endif // __arm__ > Index: lib/asan/asan_mac.cc > diff --git lib/asan/asan_mac.cc lib/asan/asan_mac.cc > index 112aebf8d93b52a9c8c75e516ccd79**07afadac44..** > 7832ce8a17722192f87f96cce90733**ea6fadc4fa 100644 > --- lib/asan/asan_mac.cc > +++ lib/asan/asan_mac.cc > @@ -271,10 +271,16 @@ bool AsanProcMaps::Next(uintptr_t *start, uintptr_t > *end, > return false; > } > > -bool AsanProcMaps::**GetObjectNameAndOffset(**uintptr_t addr, uintptr_t > *offset, > - char filename[], > - size_t filename_size) { > - return IterateForObjectNameAndOffset(**addr, offset, filename, > filename_size); > +void AsanProcMaps::DescribeAddress(**uintptr_t addr, > + char out_buffer[], > + size_t buffer_size) { > + uintptr_t offset; > + char objname[4096]; > + if (**IterateForObjectNameAndOffset(**addr, &offset, objname, > sizeof(objname))) { > + SNPrintf(out_buffer, buffer_size, " (%s+0x%lx)", objname, offset); > + } else { > + out_buffer[0] = '\0'; > + } > } > > void AsanThread::**SetThreadStackTopAndBottom() { > Index: lib/asan/asan_procmaps.h > diff --git lib/asan/asan_procmaps.h lib/asan/asan_procmaps.h > index 6dd42f9f653610588dca4553537138**0792516f89..** > bc5f67b2de033acf4f205101f9a690**82ec6bdce3 100644 > --- lib/asan/asan_procmaps.h > +++ lib/asan/asan_procmaps.h > @@ -24,10 +24,13 @@ class AsanProcMaps { > bool Next(uintptr_t *start, uintptr_t *end, uintptr_t *offset, > char filename[], size_t filename_size); > void Reset(); > - // Gets the object file name and the offset in that object for a given > - // address 'addr'. Returns true on success. > - bool GetObjectNameAndOffset(**uintptr_t addr, uintptr_t *offset, > - char filename[], size_t filename_size); > + > + // Gets all the information possible for a given address 'addr' > + // (object file name, offset, source file name, source line, etc.) > + // and puts it into the given buffer with a leading space > + // or puts an empty string "" if no information is available. > + void DescribeAddress(uintptr_t addr, char out_buffer[], size_t > buffer_size); > + > ~AsanProcMaps(); > private: > // Default implementation of GetObjectNameAndOffset. > Index: lib/asan/asan_stack.cc > diff --git lib/asan/asan_stack.cc lib/asan/asan_stack.cc > index 9f7469749085b576d8359b927da2c5**8623773e15..** > fe83534e8ff96546c09029705e2d94**a1af039c00 100644 > --- lib/asan/asan_stack.cc > +++ lib/asan/asan_stack.cc > @@ -42,14 +42,9 @@ void AsanStackTrace::PrintStack(**uintptr_t *addr, > size_t size) { > for (size_t i = 0; i < size && addr[i]; i++) { > proc_maps.Reset(); > uintptr_t pc = addr[i]; > - uintptr_t offset; > - char filename[4096]; > - if (proc_maps.**GetObjectNameAndOffset(pc, &offset, > - filename, sizeof(filename))) { > - Printf(" #%ld 0x%lx (%s+0x%lx)\n", i, pc, filename, offset); > - } else { > - Printf(" #%ld 0x%lx\n", i, pc); > - } > + char descr[4096]; > + proc_maps.DescribeAddress(pc, descr, sizeof(descr)); > + Printf(" #%ld 0x%lx%s\n", i, pc, descr); > } > } > #endif // ASAN_USE_EXTERNAL_SYMBOLIZER > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/a18dde64/attachment.html From kcc at google.com Tue Feb 7 12:23:54 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 07 Feb 2012 18:23:54 -0000 Subject: [llvm-commits] [compiler-rt] r149994 - /compiler-rt/trunk/lib/asan/asan_internal.h Message-ID: <20120207182354.C6DD82A6C12C@llvm.org> Author: kcc Date: Tue Feb 7 12:23:54 2012 New Revision: 149994 URL: http://llvm.org/viewvc/llvm-project?rev=149994&view=rev Log: [asan] GET_CALLER_PC macro for Win. Patch by timurrrr at google.com Modified: compiler-rt/trunk/lib/asan/asan_internal.h Modified: compiler-rt/trunk/lib/asan/asan_internal.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=149994&r1=149993&r2=149994&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_internal.h (original) +++ compiler-rt/trunk/lib/asan/asan_internal.h Tue Feb 7 12:23:54 2012 @@ -212,12 +212,16 @@ const size_t kPageSize = 1UL << kPageSizeBits; #ifndef _WIN32 -#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) -#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) +# define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) +# define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) #else -// TODO(timurrrr): implement. -#define GET_CALLER_PC() (uintptr_t)0 -#define GET_CURRENT_FRAME() (uintptr_t)0 +extern "C" void* _ReturnAddress(void); +# pragma intrinsic(_ReturnAddress) +# define GET_CALLER_PC() (uintptr_t)_ReturnAddress() +// CaptureStackBackTrace doesn't need to know BP on Windows. +// FIXME: This macro is still used when printing error reports though it's not +// clear if the BP value is needed in the ASan reports on Windows. +# define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF #endif #define GET_BP_PC_SP \ From kcc at google.com Tue Feb 7 12:28:38 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 10:28:38 -0800 Subject: [llvm-commits] Implement the GET_CALLER_PC macro, stub the GET_CURRENT_FRAME macro (issue 5630065) In-Reply-To: References: <20cf3074b182a4ed2f04b85f3b0f@google.com> Message-ID: Ok, r149994. thanks! On Tue, Feb 7, 2012 at 10:18 AM, Timur Iskhodzhanov wrote: > On Tue, Feb 7, 2012 at 10:05 PM, Kostya Serebryany wrote: > > Much better. > > Now, how about using _AddressOfReturnAddress() for the frame? > This will be a separate patch, see the reasoning below. > > On Windows, the value of GET_CURRENT_FRAME is only used when printing > ASan reports and it is named "bp=". > (we use CaptureStackBackTrace to get stack traces now, it doesn't > require to know bp) > CaptureStackBackTrace may appear to be prohibitively slow in the long run. But ok for now. > _AddressOfReturnAddress returns "ebp+4" on x86, which isn't a problem; > (but this might not be true for all the calling conventions? need to check) > > On x64 however rbp is not used making function calls (tested on > helloworld-like app calling foo(), rbp==0!) and _AddressOfReturnAddress > actually returns rsp+40 (which is likely to always stay true as > there's only one calling convention on Win x64) > > Also, it's not clear if we need to print ebp at all on Windows in the > ASan reports. > bp= is useful when you have weird stack-buffer-overflow reports that are hard to reason about. --kcc > > > --kcc > > > > > > On Tue, Feb 7, 2012 at 9:56 AM, Timur Iskhodzhanov > > wrote: > >> > >> PTAL, > >> though personally I don't like how it looks now. > >> > >> On Tue, Feb 7, 2012 at 9:36 PM, Kostya Serebryany > wrote: > >> > > >> > > >> > On Tue, Feb 7, 2012 at 4:51 AM, wrote: > >> >> > >> >> > >> >> > http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h > >> >> File lib/asan/asan_internal.h (right): > >> >> > >> >> > >> >> > >> >> > http://codereview.appspot.com/5630065/diff/1/lib/asan/asan_internal.h#newcode24 > >> >> lib/asan/asan_internal.h:24: # include > >> >> On 2012/02/06 19:18:31, kcc wrote: > >> >>> > >> >>> Can we avoid this include in the header? > >> >>> ( I am not sure we can, just asking) > >> >> > >> >> I doubt so. > >> >> Or we'll need to #include it in every file which uses GET_CURRENT_PC > or > >> >> GET_BP_PC_SP. > >> > > >> > > >> > Maybe you can find how this thing is defined in intrin.h and use > similar > >> > definition? > >> > > >> > > >> > --kcc > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/75f7d3b7/attachment.html From stoklund at 2pi.dk Tue Feb 7 12:28:40 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Tue, 07 Feb 2012 10:28:40 -0800 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <87ehu6tt1g.fsf@smith.obbligato.org> References: <87mx8uvcyw.fsf@smith.obbligato.org> <8C4644C6-E42C-498B-9634-E33EC1E04E5F@2pi.dk> <87ehu6tt1g.fsf@smith.obbligato.org> Message-ID: <408C9E85-535E-4F73-B721-A681029F347E@2pi.dk> On Feb 7, 2012, at 10:08 AM, "David A. Greene" wrote: > Jakob Stoklund Olesen writes: > >> The roundtrip delay on pre-commit reviews makes it necessary to review >> larger changes than one would normally commit directly. > > Ah. I'm assuming I should submit the patch as review, not break > it up. Is that right? Yes. I don't think it makes sense to review a series of commit-sized changes. A single patch can be quite large as long as it is doing just one thing, see for example Hal's vectorizer. >> In the present case, I think the granularity you chose is fine: 1. Add >> a single-variable foreach loop. 2. Zip. > > Ok. I thought zip was a no-go. I'm going to wait on it anyway while I > work out how various things might work. It may or may not come back. Let's discuss the design before you put too much work into it. The example you pasted looked like it would require a laundry list of syntax and type system extensions. I don't want to do that for something that probably won't be used much. Back in October, we discussed something much simpler: "foreach x = [?], y = [?] in ?". That's a fairly simple extension to your first patch, and it doesn't require you to invent tuple types and generic zip operators. I think that would be fine to add. /jakob From benny.kra at googlemail.com Tue Feb 7 12:58:19 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 07 Feb 2012 18:58:19 -0000 Subject: [llvm-commits] [llvm] r149997 - /llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Message-ID: <20120207185819.DFACD2A6C12C@llvm.org> Author: d0k Date: Tue Feb 7 12:58:19 2012 New Revision: 149997 URL: http://llvm.org/viewvc/llvm-project?rev=149997&view=rev Log: ocaml bindings: landing pad is now the last opcode. Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Modified: llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c?rev=149997&r1=149996&r2=149997&view=diff ============================================================================== --- llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c (original) +++ llvm/trunk/bindings/ocaml/llvm/llvm_ocaml.c Tue Feb 7 12:58:19 2012 @@ -1163,7 +1163,7 @@ if (!LLVMIsAInstruction(Inst)) failwith("Not an instruction"); o = LLVMGetInstructionOpcode(Inst); - assert (o <= LLVMUnwind ); + assert (o <= LLVMLandingPad); return Val_int(o); } From thomas.stellard at amd.com Tue Feb 7 13:13:51 2012 From: thomas.stellard at amd.com (Tom Stellard) Date: Tue, 7 Feb 2012 14:13:51 -0500 Subject: [llvm-commits] Patch: Add get_global_id builtin/intrinsic In-Reply-To: <7DE70FDACDE4CD4887C4278C12A2E305081425@HASMSX104.ger.corp.intel.com> References: <20120203211902.GC1710@L7-CNU1252LKR-172027226155.amd.com> <7DE70FDACDE4CD4887C4278C12A2E305081425@HASMSX104.ger.corp.intel.com> Message-ID: <20120207191351.GA3511@L7-CNU1252LKR-172027226155.amd.com> On Fri, Feb 03, 2012 at 09:26:14PM +0000, Rotem, Nadav wrote: > Tom, > > I can see a number of problems with this patch. First, get_global_id does not return llvm_i32_ty on 64bit systems. It returns size_t (which is i64 on x86_64). Second, I am not sure that this is the correct approach for implementing this. What's wrong with having get_global_id as a standard library call ? Why do we need a special intrinsic for it ? Hi, I've updated these two patches by changing the return type of the get_global_id intrinsic from llvm_i32_ty to llvm_anyint_ty and the return type of the builtin from int to size_t. I think I still may be missing something in Clang to make get_global_id return the correct integer type, because the generated LLVM IR still has i32 as the return type for get_global_id on my x86_64 system. Hopefully, someone can spot my mistake. Please review. Thanks, Tom > > Thanks, > Nadav > > -----Original Message----- > From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Tom Stellard > Sent: Friday, February 03, 2012 23:19 > To: llvm-commits at cs.uiuc.edu; cfe-commits at cs.uiuc.edu > Subject: [llvm-commits] Patch: Add get_global_id builtin/intrinsic > > Hi, > > I've attached two patches, one for llvm and one for clang that add support for the OpenCL C builtin function get_global_id(). I would like to eventually add support for more OpenCL builtins to clang/llvm, but this initial patch is just to make sure I'm doing it the right way. > > Please review. > > Thanks, > Tom Stellard > > --------------------------------------------------------------------- > Intel Israel (74) Limited > > This e-mail and any attachments may contain confidential material for > the sole use of the intended recipient(s). Any review or distribution > by others is strictly prohibited. If you are not the intended > recipient, please contact the sender and delete all copies. > > -------------- next part -------------- diff --git include/llvm/Intrinsics.td include/llvm/Intrinsics.td index 069f907..72ea8ae 100644 --- include/llvm/Intrinsics.td +++ include/llvm/Intrinsics.td @@ -430,6 +430,11 @@ def int_convertus : Intrinsic<[llvm_anyint_ty], def int_convertuu : Intrinsic<[llvm_anyint_ty], [llvm_anyint_ty, llvm_i32_ty, llvm_i32_ty]>; +//===--------------------------- OpenCL Intrinsics ------------------------===// +// +def int_get_global_id : Intrinsic<[llvm_anyint_ty], [llvm_i32_ty]>; + + //===----------------------------------------------------------------------===// // Target-specific intrinsics //===----------------------------------------------------------------------===// -------------- next part -------------- diff --git include/clang/Basic/Builtins.def include/clang/Basic/Builtins.def index b3b3c21..7e9542a 100644 --- include/clang/Basic/Builtins.def +++ include/clang/Basic/Builtins.def @@ -624,6 +624,8 @@ BUILTIN(__assume, "vb", "n") BUILTIN(__noop, "v.", "n") BUILTIN(__debugbreak, "v", "n") +// OpenCL builtins. +BUILTIN(__builtin_get_global_id, "ii", "n") // C99 library functions // C99 stdlib.h diff --git lib/CodeGen/CGBuiltin.cpp lib/CodeGen/CGBuiltin.cpp index e463230..d830dd0 100644 --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1087,6 +1087,15 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, llvm::StringRef Str = cast(AnnotationStrExpr)->getString(); return RValue::get(EmitAnnotationCall(F, AnnVal, Str, E->getExprLoc())); } + + // OpenCL builtins + case Builtin::BI__builtin_get_global_id: { + Value *Dim = EmitScalarExpr(E->getArg(0)); + llvm::Type *ArgType = Dim->getType(); + Value *Call = CGM.getIntrinsic(Intrinsic::get_global_id, ArgType); + return RValue::get(Builder.CreateCall(Call, Dim, "")); + } + } // If this is an alias for a lib function (e.g. __builtin_sin), emit From grosbach at apple.com Tue Feb 7 13:15:51 2012 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 07 Feb 2012 11:15:51 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ lib/Target/X86/Disassembler/ tools/llvm-bcanalyzer/ tools/llvm-dis/ tools/llvm-mc/ tools/llvm-objdump/ In-Reply-To: <20120206223030.ECC142A6C12C@llvm.org> References: <20120206223030.ECC142A6C12C@llvm.org> Message-ID: <9081ABD9-AC64-4C4A-826A-2742EA44FA74@apple.com> Hi Derek, I don't follow why this needs to change the MC disassemblers. Those have nothing to do with bitcode. Can you elaborate? I'm uncomfortable with removing the const'ness of the input to those methods, for example. -Jim On Feb 6, 2012, at 2:30 PM, Derek Schuff wrote: > Author: dschuff > Date: Mon Feb 6 16:30:29 2012 > New Revision: 149918 > > URL: http://llvm.org/viewvc/llvm-project?rev=149918&view=rev > Log: > Enable streaming of bitcode > > This CL delays reading of function bodies from initial parse until > materialization, allowing overlap of compilation with bitcode download. > > > Added: > llvm/trunk/include/llvm/Support/DataStream.h > llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > llvm/trunk/lib/Support/DataStream.cpp > llvm/trunk/lib/Support/StreamableMemoryObject.cpp > Modified: > llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > llvm/trunk/include/llvm/MC/MCDisassembler.h > llvm/trunk/include/llvm/Support/MemoryObject.h > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > llvm/trunk/lib/Support/CMakeLists.txt > llvm/trunk/lib/Support/MemoryObject.cpp > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > llvm/trunk/tools/llvm-dis/llvm-dis.cpp > llvm/trunk/tools/llvm-mc/Disassembler.cpp > llvm/trunk/tools/llvm-objdump/MCFunction.cpp > llvm/trunk/tools/llvm-objdump/MCFunction.h > llvm/trunk/tools/llvm-objdump/llvm-objdump.h > > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb 6 16:30:29 2012 > @@ -15,10 +15,12 @@ > #ifndef BITSTREAM_READER_H > #define BITSTREAM_READER_H > > +#include "llvm/ADT/OwningPtr.h" > #include "llvm/Bitcode/BitCodes.h" > #include > #include > #include > +#include "llvm/Support/StreamableMemoryObject.h" > > namespace llvm { > > @@ -36,9 +38,7 @@ > std::vector > RecordNames; > }; > private: > - /// FirstChar/LastChar - This remembers the first and last bytes of the > - /// stream. > - const unsigned char *FirstChar, *LastChar; > + OwningPtr BitcodeBytes; > > std::vector BlockInfoRecords; > > @@ -47,10 +47,10 @@ > /// uses this. > bool IgnoreBlockInfoNames; > > - BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED > - void operator=(const BitstreamReader&); // NOT IMPLEMENTED > + BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT > + void operator=(const BitstreamReader&); // DO NOT IMPLEMENT > public: > - BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { > + BitstreamReader() : IgnoreBlockInfoNames(true) { > } > > BitstreamReader(const unsigned char *Start, const unsigned char *End) { > @@ -58,12 +58,17 @@ > init(Start, End); > } > > + BitstreamReader(StreamableMemoryObject *bytes) { > + BitcodeBytes.reset(bytes); > + } > + > void init(const unsigned char *Start, const unsigned char *End) { > - FirstChar = Start; > - LastChar = End; > assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); > + BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); > } > > + StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } > + > ~BitstreamReader() { > // Free the BlockInfoRecords. > while (!BlockInfoRecords.empty()) { > @@ -75,9 +80,6 @@ > BlockInfoRecords.pop_back(); > } > } > - > - const unsigned char *getFirstChar() const { return FirstChar; } > - const unsigned char *getLastChar() const { return LastChar; } > > /// CollectBlockInfoNames - This is called by clients that want block/record > /// name information. > @@ -122,7 +124,7 @@ > class BitstreamCursor { > friend class Deserializer; > BitstreamReader *BitStream; > - const unsigned char *NextChar; > + size_t NextChar; > > /// CurWord - This is the current data we have pulled from the stream but have > /// not returned to the client. > @@ -156,8 +158,7 @@ > } > > explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { > - NextChar = R.getFirstChar(); > - assert(NextChar && "Bitstream not initialized yet"); > + NextChar = 0; > CurWord = 0; > BitsInCurWord = 0; > CurCodeSize = 2; > @@ -167,8 +168,7 @@ > freeState(); > > BitStream = &R; > - NextChar = R.getFirstChar(); > - assert(NextChar && "Bitstream not initialized yet"); > + NextChar = 0; > CurWord = 0; > BitsInCurWord = 0; > CurCodeSize = 2; > @@ -225,13 +225,38 @@ > /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. > unsigned GetAbbrevIDWidth() const { return CurCodeSize; } > > - bool AtEndOfStream() const { > - return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; > + bool isEndPos(size_t pos) { > + return BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos)); > + } > + > + bool canSkipToPos(size_t pos) const { > + // pos can be skipped to if it is a valid address or one byte past the end. > + return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( > + static_cast(pos - 1)); > + } > + > + unsigned char getByte(size_t pos) { > + uint8_t byte = -1; > + BitStream->getBitcodeBytes().readByte(pos, &byte); > + return byte; > + } > + > + uint32_t getWord(size_t pos) { > + uint32_t word = -1; > + BitStream->getBitcodeBytes().readBytes(pos, > + sizeof(word), > + reinterpret_cast(&word), > + NULL); > + return word; > + } > + > + bool AtEndOfStream() { > + return isEndPos(NextChar) && BitsInCurWord == 0; > } > > /// GetCurrentBitNo - Return the bit # of the bit we are reading. > uint64_t GetCurrentBitNo() const { > - return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; > + return NextChar*CHAR_BIT - BitsInCurWord; > } > > BitstreamReader *getBitStreamReader() { > @@ -246,12 +271,10 @@ > void JumpToBit(uint64_t BitNo) { > uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; > uintptr_t WordBitNo = uintptr_t(BitNo) & 31; > - assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- > - BitStream->getFirstChar()) && > - "Invalid location"); > + assert(canSkipToPos(ByteNo) && "Invalid location"); > > // Move the cursor to the right word. > - NextChar = BitStream->getFirstChar()+ByteNo; > + NextChar = ByteNo; > BitsInCurWord = 0; > CurWord = 0; > > @@ -272,7 +295,7 @@ > } > > // If we run out of data, stop at the end of the stream. > - if (NextChar == BitStream->getLastChar()) { > + if (isEndPos(NextChar)) { > CurWord = 0; > BitsInCurWord = 0; > return 0; > @@ -281,8 +304,7 @@ > unsigned R = CurWord; > > // Read the next word from the stream. > - CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | > - (NextChar[2] << 16) | (NextChar[3] << 24); > + CurWord = getWord(NextChar); > NextChar += 4; > > // Extract NumBits-BitsInCurWord from what we just read. > @@ -376,9 +398,8 @@ > > // Check that the block wasn't partially defined, and that the offset isn't > // bogus. > - const unsigned char *const SkipTo = NextChar + NumWords*4; > - if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || > - SkipTo < BitStream->getFirstChar()) > + size_t SkipTo = NextChar + NumWords*4; > + if (AtEndOfStream() || !canSkipToPos(SkipTo)) > return true; > > NextChar = SkipTo; > @@ -409,8 +430,7 @@ > if (NumWordsP) *NumWordsP = NumWords; > > // Validate that this block is sane. > - if (CurCodeSize == 0 || AtEndOfStream() || > - NextChar+NumWords*4 > BitStream->getLastChar()) > + if (CurCodeSize == 0 || AtEndOfStream()) > return true; > > return false; > @@ -512,24 +532,25 @@ > SkipToWord(); // 32-bit alignment > > // Figure out where the end of this blob will be including tail padding. > - const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); > + size_t NewEnd = NextChar+((NumElts+3)&~3); > > // If this would read off the end of the bitcode file, just set the > // record to empty and return. > - if (NewEnd > BitStream->getLastChar()) { > + if (!canSkipToPos(NewEnd)) { > Vals.append(NumElts, 0); > - NextChar = BitStream->getLastChar(); > + NextChar = BitStream->getBitcodeBytes().getExtent(); > break; > } > > // Otherwise, read the number of bytes. If we can return a reference to > // the data, do so to avoid copying it. > if (BlobStart) { > - *BlobStart = (const char*)NextChar; > + *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer( > + NextChar, NumElts); > *BlobLen = NumElts; > } else { > for (; NumElts; ++NextChar, --NumElts) > - Vals.push_back(*NextChar); > + Vals.push_back(getByte(NextChar)); > } > // Skip over tail padding. > NextChar = NewEnd; > > Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) > +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Feb 6 16:30:29 2012 > @@ -17,35 +17,45 @@ > #include > > namespace llvm { > - class Module; > - class MemoryBuffer; > - class ModulePass; > class BitstreamWriter; > + class MemoryBuffer; > + class DataStreamer; > class LLVMContext; > + class Module; > + class ModulePass; > class raw_ostream; > - > + > /// getLazyBitcodeModule - Read the header of the specified bitcode buffer > /// and prepare for lazy deserialization of function bodies. If successful, > /// this takes ownership of 'buffer' and returns a non-null pointer. On > /// error, this returns null, *does not* take ownership of Buffer, and fills > /// in *ErrMsg with an error description if ErrMsg is non-null. > Module *getLazyBitcodeModule(MemoryBuffer *Buffer, > - LLVMContext& Context, > + LLVMContext &Context, > std::string *ErrMsg = 0); > > + /// getStreamedBitcodeModule - Read the header of the specified stream > + /// and prepare for lazy deserialization and streaming of function bodies. > + /// On error, this returns null, and fills in *ErrMsg with an error > + /// description if ErrMsg is non-null. > + Module *getStreamedBitcodeModule(const std::string &name, > + DataStreamer *streamer, > + LLVMContext &Context, > + std::string *ErrMsg = 0); > + > /// getBitcodeTargetTriple - Read the header of the specified bitcode > /// buffer and extract just the triple information. If successful, > /// this returns a string and *does not* take ownership > /// of 'buffer'. On error, this returns "", and fills in *ErrMsg > /// if ErrMsg is non-null. > std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, > - LLVMContext& Context, > + LLVMContext &Context, > std::string *ErrMsg = 0); > > /// ParseBitcodeFile - Read the specified bitcode file, returning the module. > /// If an error occurs, this returns null and fills in *ErrMsg if it is > /// non-null. This method *never* takes ownership of Buffer. > - Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, > + Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context, > std::string *ErrMsg = 0); > > /// WriteBitcodeToFile - Write the specified module to the specified > @@ -60,8 +70,8 @@ > /// createBitcodeWriterPass - Create and return a pass that writes the module > /// to the specified ostream. > ModulePass *createBitcodeWriterPass(raw_ostream &Str); > - > - > + > + > /// isBitcodeWrapper - Return true if the given bytes are the magic bytes > /// for an LLVM IR bitcode wrapper. > /// > @@ -109,21 +119,24 @@ > /// uint32_t BitcodeSize; // Size of traditional bitcode file. > /// ... potentially other gunk ... > /// }; > - /// > + /// > /// This function is called when we find a file with a matching magic number. > /// In this case, skip down to the subsection of the file that is actually a > /// BC file. > - static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr, > - unsigned char *&BufEnd) { > + /// If 'VerifyBufferSize' is true, check that the buffer is large enough to > + /// contain the whole bitcode file. > + static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, > + const unsigned char *&BufEnd, > + bool VerifyBufferSize) { > enum { > KnownHeaderSize = 4*4, // Size of header we read. > OffsetField = 2*4, // Offset in bytes to Offset field. > SizeField = 3*4 // Offset in bytes to Size field. > }; > - > + > // Must contain the header! > if (BufEnd-BufPtr < KnownHeaderSize) return true; > - > + > unsigned Offset = ( BufPtr[OffsetField ] | > (BufPtr[OffsetField+1] << 8) | > (BufPtr[OffsetField+2] << 16) | > @@ -132,9 +145,9 @@ > (BufPtr[SizeField +1] << 8) | > (BufPtr[SizeField +2] << 16) | > (BufPtr[SizeField +3] << 24)); > - > + > // Verify that Offset+Size fits in the file. > - if (Offset+Size > unsigned(BufEnd-BufPtr)) > + if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) > return true; > BufPtr += Offset; > BufEnd = BufPtr+Size; > > Modified: llvm/trunk/include/llvm/MC/MCDisassembler.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/MC/MCDisassembler.h (original) > +++ llvm/trunk/include/llvm/MC/MCDisassembler.h Mon Feb 6 16:30:29 2012 > @@ -79,7 +79,7 @@ > /// MCDisassembler::Fail if the instruction was invalid. > virtual DecodeStatus getInstruction(MCInst& instr, > uint64_t& size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const = 0; > > Added: llvm/trunk/include/llvm/Support/DataStream.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149918&view=auto > ============================================================================== > --- llvm/trunk/include/llvm/Support/DataStream.h (added) > +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb 6 16:30:29 2012 > @@ -0,0 +1,38 @@ > +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This header defines DataStreamer, which fetches bytes of data from > +// a stream source. It provides support for streaming (lazy reading) of > +// data, e.g. bitcode > +// > +//===----------------------------------------------------------------------===// > + > + > +#ifndef LLVM_SUPPORT_DATASTREAM_H_ > +#define LLVM_SUPPORT_DATASTREAM_H_ > + > +#include > + > +namespace llvm { > + > +class DataStreamer { > +public: > + /// Fetch bytes [start-end) from the stream, and write them to the > + /// buffer pointed to by buf. Returns the number of bytes actually written. > + virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; > + > + virtual ~DataStreamer(); > +}; > + > +DataStreamer *getDataFileStreamer(const std::string &Filename, > + std::string *Err); > + > +} > + > +#endif // LLVM_SUPPORT_DATASTREAM_H_ > > Modified: llvm/trunk/include/llvm/Support/MemoryObject.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryObject.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/Support/MemoryObject.h (original) > +++ llvm/trunk/include/llvm/Support/MemoryObject.h Mon Feb 6 16:30:29 2012 > @@ -34,7 +34,7 @@ > /// is getBase() + getExtent() - 1). > /// > /// @result - The size of the region. > - virtual uint64_t getExtent() const = 0; > + virtual uint64_t getExtent() = 0; > > /// readByte - Tries to read a single byte from the region. > /// > @@ -42,7 +42,7 @@ > /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. > /// @result - 0 if successful; -1 if not. Failure may be due to a > /// bounds violation or an implementation-specific error. > - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > > /// readBytes - Tries to read a contiguous range of bytes from the > /// region, up to the end of the region. > @@ -61,7 +61,7 @@ > virtual int readBytes(uint64_t address, > uint64_t size, > uint8_t* buf, > - uint64_t* copied) const; > + uint64_t* copied); > }; > > } > > Added: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149918&view=auto > ============================================================================== > --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (added) > +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb 6 16:30:29 2012 > @@ -0,0 +1,181 @@ > +//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > + > +#ifndef STREAMABLEMEMORYOBJECT_H_ > +#define STREAMABLEMEMORYOBJECT_H_ > + > +#include "llvm/ADT/OwningPtr.h" > +#include "llvm/Support/MemoryObject.h" > +#include "llvm/Support/DataStream.h" > +#include > + > +namespace llvm { > + > +/// StreamableMemoryObject - Interface to data which might be streamed. > +/// Streamability has 2 important implications/restrictions. First, the data > +/// might not yet exist in memory when the request is made. This just means > +/// that readByte/readBytes might have to block or do some work to get it. > +/// More significantly, the exact size of the object might not be known until > +/// it has all been fetched. This means that to return the right result, > +/// getExtent must also wait for all the data to arrive; therefore it should > +/// not be called on objects which are actually streamed (this would defeat > +/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be > +/// used to test addresses without knowing the exact size of the stream. > +/// Finally, getPointer can be used instead of readBytes to avoid extra copying. > +class StreamableMemoryObject : public MemoryObject { > + public: > + /// Destructor - Override as necessary. > + virtual ~StreamableMemoryObject(); > + > + /// getBase - Returns the lowest valid address in the region. > + /// > + /// @result - The lowest valid address. > + virtual uint64_t getBase() const = 0; > + > + /// getExtent - Returns the size of the region in bytes. (The region is > + /// contiguous, so the highest valid address of the region > + /// is getBase() + getExtent() - 1). > + /// May block until all bytes in the stream have been read > + /// > + /// @result - The size of the region. > + virtual uint64_t getExtent() = 0; > + > + /// readByte - Tries to read a single byte from the region. > + /// May block until (address - base) bytes have been read > + /// @param address - The address of the byte, in the same space as getBase(). > + /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. > + /// @result - 0 if successful; -1 if not. Failure may be due to a > + /// bounds violation or an implementation-specific error. > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > + > + /// readBytes - Tries to read a contiguous range of bytes from the > + /// region, up to the end of the region. > + /// May block until (address - base + size) bytes have > + /// been read. Additionally, StreamableMemoryObjects will > + /// not do partial reads - if size bytes cannot be read, > + /// readBytes will fail. > + /// > + /// @param address - The address of the first byte, in the same space as > + /// getBase(). > + /// @param size - The maximum number of bytes to copy. > + /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL > + /// and large enough to hold size bytes. > + /// @param copied - A pointer to a nunber that is filled in with the number > + /// of bytes actually read. May be NULL. > + /// @result - 0 if successful; -1 if not. Failure may be due to a > + /// bounds violation or an implementation-specific error. > + virtual int readBytes(uint64_t address, > + uint64_t size, > + uint8_t* buf, > + uint64_t* copied) = 0; > + > + /// getPointer - Ensures that the requested data is in memory, and returns > + /// A pointer to it. More efficient than using readBytes if the > + /// data is already in memory. > + /// May block until (address - base + size) bytes have been read > + /// @param address - address of the byte, in the same space as getBase() > + /// @param size - amount of data that must be available on return > + /// @result - valid pointer to the requested data > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) = 0; > + > + /// isValidAddress - Returns true if the address is within the object > + /// (i.e. between base and base + extent - 1 inclusive) > + /// May block until (address - base) bytes have been read > + /// @param address - address of the byte, in the same space as getBase() > + /// @result - true if the address may be read with readByte() > + virtual bool isValidAddress(uint64_t address) = 0; > + > + /// isObjectEnd - Returns true if the address is one past the end of the > + /// object (i.e. if it is equal to base + extent) > + /// May block until (address - base) bytes have been read > + /// @param address - address of the byte, in the same space as getBase() > + /// @result - true if the address is equal to base + extent > + virtual bool isObjectEnd(uint64_t address) = 0; > +}; > + > +/// StreamingMemoryObject - interface to data which is actually streamed from > +/// a DataStreamer. In addition to inherited members, it has the > +/// dropLeadingBytes and setKnownObjectSize methods which are not applicable > +/// to non-streamed objects. > +class StreamingMemoryObject : public StreamableMemoryObject { > +public: > + StreamingMemoryObject(DataStreamer *streamer); > + virtual uint64_t getBase() const { return 0; } > + virtual uint64_t getExtent(); > + virtual int readByte(uint64_t address, uint8_t* ptr); > + virtual int readBytes(uint64_t address, > + uint64_t size, > + uint8_t* buf, > + uint64_t* copied); > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) { > + // This could be fixed by ensuring the bytes are fetched and making a copy, > + // requiring that the bitcode size be known, or otherwise ensuring that > + // the memory doesn't go away/get reallocated, but it's > + // not currently necessary. Users that need the pointer don't stream. > + assert(0 && "getPointer in streaming memory objects not allowed"); > + return NULL; > + } > + virtual bool isValidAddress(uint64_t address); > + virtual bool isObjectEnd(uint64_t address); > + > + /// Drop s bytes from the front of the stream, pushing the positions of the > + /// remaining bytes down by s. This is used to skip past the bitcode header, > + /// since we don't know a priori if it's present, and we can't put bytes > + /// back into the stream once we've read them. > + bool dropLeadingBytes(size_t s); > + > + /// If the data object size is known in advance, many of the operations can > + /// be made more efficient, so this method should be called before reading > + /// starts (although it can be called anytime). > + void setKnownObjectSize(size_t size); > + > +private: > + const static uint32_t kChunkSize = 4096 * 4; > + std::vector Bytes; > + OwningPtr Streamer; > + size_t BytesRead; // Bytes read from stream > + size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) > + size_t ObjectSize; // 0 if unknown, set if wrapper was seen or EOF reached > + bool EOFReached; > + > + // Fetch enough bytes such that Pos can be read or EOF is reached > + // (i.e. BytesRead > Pos). Return true if Pos can be read. > + // Unlike most of the functions in BitcodeReader, returns true on success. > + // Most of the requests will be small, but we fetch at kChunkSize bytes > + // at a time to avoid making too many potentially expensive GetBytes calls > + bool fetchToPos(size_t Pos) { > + if (EOFReached) return Pos < ObjectSize; > + while (Pos >= BytesRead) { > + Bytes.resize(BytesRead + kChunkSize); > + size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], > + kChunkSize); > + BytesRead += bytes; > + if (bytes < kChunkSize) { > + if (ObjectSize && BytesRead < Pos) > + assert(0 && "Unexpected short read fetching bitcode"); > + if (BytesRead <= Pos) { // reached EOF/ran out of bytes > + ObjectSize = BytesRead; > + EOFReached = true; > + return false; > + } > + } > + } > + return true; > + } > + > + StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT > + void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT > +}; > + > +StreamableMemoryObject *getNonStreamedMemoryObject( > + const unsigned char *Start, const unsigned char *End); > + > +} > +#endif // STREAMABLEMEMORYOBJECT_H_ > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 16:30:29 2012 > @@ -22,6 +22,7 @@ > #include "llvm/AutoUpgrade.h" > #include "llvm/ADT/SmallString.h" > #include "llvm/ADT/SmallVector.h" > +#include "llvm/Support/DataStream.h" > #include "llvm/Support/MathExtras.h" > #include "llvm/Support/MemoryBuffer.h" > #include "llvm/OperandTraits.h" > @@ -1409,8 +1410,36 @@ > return false; > } > > -bool BitcodeReader::ParseModule() { > - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > +bool BitcodeReader::GlobalCleanup() { > + // Patch the initializers for globals and aliases up. > + ResolveGlobalAndAliasInits(); > + if (!GlobalInits.empty() || !AliasInits.empty()) > + return Error("Malformed global initializer set"); > + > + // Look for intrinsic functions which need to be upgraded at some point > + for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); > + FI != FE; ++FI) { > + Function *NewFn; > + if (UpgradeIntrinsicFunction(FI, NewFn)) > + UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > + } > + > + // Look for global variables which need to be renamed. > + for (Module::global_iterator > + GI = TheModule->global_begin(), GE = TheModule->global_end(); > + GI != GE; ++GI) > + UpgradeGlobalVariable(GI); > + // Force deallocation of memory for these vectors to favor the client that > + // want lazy deserialization. > + std::vector >().swap(GlobalInits); > + std::vector >().swap(AliasInits); > + return false; > +} > + > +bool BitcodeReader::ParseModule(bool Resume) { > + if (Resume) > + Stream.JumpToBit(NextUnreadBit); > + else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > return Error("Malformed block record"); > > SmallVector Record; > @@ -1424,33 +1453,7 @@ > if (Stream.ReadBlockEnd()) > return Error("Error at end of module block"); > > - // Patch the initializers for globals and aliases up. > - ResolveGlobalAndAliasInits(); > - if (!GlobalInits.empty() || !AliasInits.empty()) > - return Error("Malformed global initializer set"); > - if (!FunctionsWithBodies.empty()) > - return Error("Too few function bodies found"); > - > - // Look for intrinsic functions which need to be upgraded at some point > - for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); > - FI != FE; ++FI) { > - Function* NewFn; > - if (UpgradeIntrinsicFunction(FI, NewFn)) > - UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > - } > - > - // Look for global variables which need to be renamed. > - for (Module::global_iterator > - GI = TheModule->global_begin(), GE = TheModule->global_end(); > - GI != GE; ++GI) > - UpgradeGlobalVariable(GI); > - > - // Force deallocation of memory for these vectors to favor the client that > - // want lazy deserialization. > - std::vector >().swap(GlobalInits); > - std::vector >().swap(AliasInits); > - std::vector().swap(FunctionsWithBodies); > - return false; > + return GlobalCleanup(); > } > > if (Code == bitc::ENTER_SUBBLOCK) { > @@ -1474,6 +1477,7 @@ > case bitc::VALUE_SYMTAB_BLOCK_ID: > if (ParseValueSymbolTable()) > return true; > + SeenValueSymbolTable = true; > break; > case bitc::CONSTANTS_BLOCK_ID: > if (ParseConstants() || ResolveGlobalAndAliasInits()) > @@ -1486,13 +1490,25 @@ > case bitc::FUNCTION_BLOCK_ID: > // If this is the first function body we've seen, reverse the > // FunctionsWithBodies list. > - if (!HasReversedFunctionsWithBodies) { > + if (!SeenFirstFunctionBody) { > std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); > - HasReversedFunctionsWithBodies = true; > + if (GlobalCleanup()) > + return true; > + SeenFirstFunctionBody = true; > } > > if (RememberAndSkipFunctionBody()) > return true; > + // For streaming bitcode, suspend parsing when we reach the function > + // bodies. Subsequent materialization calls will resume it when > + // necessary. For streaming, the function bodies must be at the end of > + // the bitcode. If the bitcode file is old, the symbol table will be > + // at the end instead and will not have been seen yet. In this case, > + // just finish the parse now. > + if (LazyStreamer && SeenValueSymbolTable) { > + NextUnreadBit = Stream.GetCurrentBitNo(); > + return false; > + } > break; > case bitc::USELIST_BLOCK_ID: > if (ParseUseLists()) > @@ -1651,8 +1667,10 @@ > > // If this is a function with a body, remember the prototype we are > // creating now, so that we can match up the body with them later. > - if (!isProto) > + if (!isProto) { > FunctionsWithBodies.push_back(Func); > + if (LazyStreamer) DeferredFunctionInfo[Func] = 0; > + } > break; > } > // ALIAS: [alias type, aliasee val#, linkage] > @@ -1691,24 +1709,7 @@ > bool BitcodeReader::ParseBitcodeInto(Module *M) { > TheModule = 0; > > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > - > - if (Buffer->getBufferSize() & 3) { > - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) > - return Error("Invalid bitcode signature"); > - else > - return Error("Bitcode stream should be a multiple of 4 bytes in length"); > - } > - > - // If we have a wrapper header, parse it and ignore the non-bc file contents. > - // The magic number is 0x0B17C0DE stored in little endian. > - if (isBitcodeWrapper(BufPtr, BufEnd)) > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > - return Error("Invalid bitcode wrapper header"); > - > - StreamFile.init(BufPtr, BufEnd); > - Stream.init(StreamFile); > + if (InitStream()) return true; > > // Sniff for the signature. > if (Stream.Read(8) != 'B' || > @@ -1750,8 +1751,9 @@ > if (TheModule) > return Error("Multiple MODULE_BLOCKs in same stream"); > TheModule = M; > - if (ParseModule()) > + if (ParseModule(false)) > return true; > + if (LazyStreamer) return false; > break; > default: > if (Stream.SkipBlock()) > @@ -1819,20 +1821,7 @@ > } > > bool BitcodeReader::ParseTriple(std::string &Triple) { > - if (Buffer->getBufferSize() & 3) > - return Error("Bitcode stream should be a multiple of 4 bytes in length"); > - > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > - > - // If we have a wrapper header, parse it and ignore the non-bc file contents. > - // The magic number is 0x0B17C0DE stored in little endian. > - if (isBitcodeWrapper(BufPtr, BufEnd)) > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > - return Error("Invalid bitcode wrapper header"); > - > - StreamFile.init(BufPtr, BufEnd); > - Stream.init(StreamFile); > + if (InitStream()) return true; > > // Sniff for the signature. > if (Stream.Read(8) != 'B' || > @@ -2708,6 +2697,19 @@ > return false; > } > > +/// FindFunctionInStream - Find the function body in the bitcode stream > +bool BitcodeReader::FindFunctionInStream(Function *F, > + DenseMap::iterator DeferredFunctionInfoIterator) { > + while (DeferredFunctionInfoIterator->second == 0) { > + if (Stream.AtEndOfStream()) > + return Error("Could not find Function in stream"); > + // ParseModule will parse the next body in the stream and set its > + // position in the DeferredFunctionInfo map. > + if (ParseModule(true)) return true; > + } > + return false; > +} > + > //===----------------------------------------------------------------------===// > // GVMaterializer implementation > //===----------------------------------------------------------------------===// > @@ -2728,6 +2730,10 @@ > > DenseMap::iterator DFII = DeferredFunctionInfo.find(F); > assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); > + // If its position is recorded as 0, its body is somewhere in the stream > + // but we haven't seen it yet. > + if (DFII->second == 0) > + if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; > > // Move the bit stream to the saved position of the deferred function body. > Stream.JumpToBit(DFII->second); > @@ -2805,6 +2811,57 @@ > return false; > } > > +bool BitcodeReader::InitStream() { > + if (LazyStreamer) return InitLazyStream(); > + return InitStreamFromBuffer(); > +} > + > +bool BitcodeReader::InitStreamFromBuffer() { > + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > + > + if (Buffer->getBufferSize() & 3) { > + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) > + return Error("Invalid bitcode signature"); > + else > + return Error("Bitcode stream should be a multiple of 4 bytes in length"); > + } > + > + // If we have a wrapper header, parse it and ignore the non-bc file contents. > + // The magic number is 0x0B17C0DE stored in little endian. > + if (isBitcodeWrapper(BufPtr, BufEnd)) > + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) > + return Error("Invalid bitcode wrapper header"); > + > + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); > + Stream.init(*StreamFile); > + > + return false; > +} > + > +bool BitcodeReader::InitLazyStream() { > + // Check and strip off the bitcode wrapper; BitstreamReader expects never to > + // see it. > + StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); > + StreamFile.reset(new BitstreamReader(Bytes)); > + Stream.init(*StreamFile); > + > + unsigned char buf[16]; > + if (Bytes->readBytes(0, 16, buf, NULL) == -1) > + return Error("Bitcode stream must be at least 16 bytes in length"); > + > + if (!isBitcode(buf, buf + 16)) > + return Error("Invalid bitcode signature"); > + > + if (isBitcodeWrapper(buf, buf + 4)) { > + const unsigned char *bitcodeStart = buf; > + const unsigned char *bitcodeEnd = buf + 16; > + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); > + Bytes->dropLeadingBytes(bitcodeStart - buf); > + Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); > + } > + return false; > +} > > //===----------------------------------------------------------------------===// > // External interface > @@ -2833,6 +2890,24 @@ > return M; > } > > + > +Module *llvm::getStreamedBitcodeModule(const std::string &name, > + DataStreamer *streamer, > + LLVMContext &Context, > + std::string *ErrMsg) { > + Module *M = new Module(name, Context); > + BitcodeReader *R = new BitcodeReader(streamer, Context); > + M->setMaterializer(R); > + if (R->ParseBitcodeInto(M)) { > + if (ErrMsg) > + *ErrMsg = R->getErrorString(); > + delete M; // Also deletes R. > + return 0; > + } > + R->setBufferOwned(false); // no buffer to delete > + return M; > +} > + > /// ParseBitcodeFile - Read the specified bitcode file, returning the module. > /// If an error occurs, return null and fill in *ErrMsg if non-null. > Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Mon Feb 6 16:30:29 2012 > @@ -126,8 +126,11 @@ > Module *TheModule; > MemoryBuffer *Buffer; > bool BufferOwned; > - BitstreamReader StreamFile; > + OwningPtr StreamFile; > BitstreamCursor Stream; > + DataStreamer *LazyStreamer; > + uint64_t NextUnreadBit; > + bool SeenValueSymbolTable; > > const char *ErrorString; > > @@ -161,9 +164,10 @@ > // Map the bitcode's custom MDKind ID to the Module's MDKind ID. > DenseMap MDKindMap; > > - // After the module header has been read, the FunctionsWithBodies list is > - // reversed. This keeps track of whether we've done this yet. > - bool HasReversedFunctionsWithBodies; > + // Several operations happen after the module header has been read, but > + // before function bodies are processed. This keeps track of whether > + // we've done this yet. > + bool SeenFirstFunctionBody; > > /// DeferredFunctionInfo - When function bodies are initially scanned, this > /// map contains info about where to find deferred function body in the > @@ -178,8 +182,13 @@ > public: > explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) > : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), > - ErrorString(0), ValueList(C), MDValueList(C) { > - HasReversedFunctionsWithBodies = false; > + LazyStreamer(0), SeenValueSymbolTable(false), ErrorString(0), > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > + } > + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) > + : Context(C), TheModule(0), Buffer(0), BufferOwned(false), > + LazyStreamer(streamer), SeenValueSymbolTable(false), ErrorString(0), > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > } > ~BitcodeReader() { > FreeState(); > @@ -258,7 +267,7 @@ > } > > > - bool ParseModule(); > + bool ParseModule(bool Resume); > bool ParseAttributeBlock(); > bool ParseTypeTable(); > bool ParseTypeTableBody(); > @@ -267,11 +276,17 @@ > bool ParseConstants(); > bool RememberAndSkipFunctionBody(); > bool ParseFunctionBody(Function *F); > + bool GlobalCleanup(); > bool ResolveGlobalAndAliasInits(); > bool ParseMetadata(); > bool ParseMetadataAttachment(); > bool ParseModuleTriple(std::string &Triple); > bool ParseUseLists(); > + bool InitStream(); > + bool InitStreamFromBuffer(); > + bool InitLazyStream(); > + bool FindFunctionInStream(Function *F, > + DenseMap::iterator DeferredFunctionInfoIterator); > }; > > } // End llvm namespace > > Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) > +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 6 16:30:29 2012 > @@ -1738,11 +1738,6 @@ > // Emit metadata. > WriteModuleMetadata(M, VE, Stream); > > - // Emit function bodies. > - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > - if (!F->isDeclaration()) > - WriteFunction(*F, VE, Stream); > - > // Emit metadata. > WriteModuleMetadataStore(M, Stream); > > @@ -1753,6 +1748,11 @@ > if (EnablePreserveUseListOrdering) > WriteModuleUseLists(M, VE, Stream); > > + // Emit function bodies. > + for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > + if (!F->isDeclaration()) > + WriteFunction(*F, VE, Stream); > + > Stream.ExitBlock(); > } > > > Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) > +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -100,9 +100,9 @@ > Bytes(bytes), Size(size), BasePC(basePC) {} > > uint64_t getBase() const { return BasePC; } > - uint64_t getExtent() const { return Size; } > + uint64_t getExtent() { return Size; } > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > + int readByte(uint64_t Addr, uint8_t *Byte) { > if (Addr - BasePC >= Size) > return -1; > *Byte = Bytes[Addr - BasePC]; > > Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) > +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -207,8 +207,8 @@ > void *arg) : Callback(callback), Arg(arg) { } > ~EDMemoryObject() { } > uint64_t getBase() const { return 0x0; } > - uint64_t getExtent() const { return (uint64_t)-1; } > - int readByte(uint64_t address, uint8_t *ptr) const { > + uint64_t getExtent() { return (uint64_t)-1; } > + int readByte(uint64_t address, uint8_t *ptr) { > if (!Callback) > return -1; > > > Modified: llvm/trunk/lib/Support/CMakeLists.txt > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Support/CMakeLists.txt (original) > +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Feb 6 16:30:29 2012 > @@ -16,6 +16,7 @@ > ConstantRange.cpp > CrashRecoveryContext.cpp > DataExtractor.cpp > + DataStream.cpp > Debug.cpp > DeltaAlgorithm.cpp > DAGDeltaAlgorithm.cpp > @@ -42,6 +43,7 @@ > SmallVector.cpp > SourceMgr.cpp > Statistic.cpp > + StreamableMemoryObject.cpp > StringExtras.cpp > StringMap.cpp > StringPool.cpp > > Added: llvm/trunk/lib/Support/DataStream.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149918&view=auto > ============================================================================== > --- llvm/trunk/lib/Support/DataStream.cpp (added) > +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 16:30:29 2012 > @@ -0,0 +1,96 @@ > +//===--- llvm/Support/DataStream.cpp - Lazy streamed Data ---===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > +// > +// This file implements DataStreamer, which fetches bytes of Data from > +// a stream source. It provides support for streaming (lazy reading) of > +// bitcode. An example implementation of streaming from a file or stdin > +// is included. > +// > +//===----------------------------------------------------------------------===// > + > +#define DEBUG_TYPE "Data-stream" > +#include "llvm/ADT/Statistic.h" > +#include "llvm/Support/DataStream.h" > +#include "llvm/Support/system_error.h" > +#include > +#include > +#include > +#if !defined(_MSC_VER) && !defined(__MINGW32__) > +#include > +#else > +#include > +#endif > +#include > +using namespace llvm; > + > +// Interface goals: > +// * StreamableMemoryObject doesn't care about complexities like using > +// threads/async callbacks to actually overlap download+compile > +// * Don't want to duplicate Data in memory > +// * Don't need to know total Data len in advance > +// Non-goals: > +// StreamableMemoryObject already has random access so this interface only does > +// in-order streaming (no arbitrary seeking, else we'd have to buffer all the > +// Data here in addition to MemoryObject). This also means that if we want > +// to be able to to free Data, BitstreamBytes/BitcodeReader will implement it > + > +STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); > + > +namespace llvm { > +DataStreamer::~DataStreamer() {} > +} > + > +namespace { > + > +const static error_code success; > + > +// Very simple stream backed by a file. Mostly useful for stdin and debugging; > +// actual file access is probably still best done with mmap. > +class DataFileStreamer : public DataStreamer { > + int Fd; > +public: > + DataFileStreamer() : Fd(0) {} > + virtual ~DataFileStreamer() { > + close(Fd); > + } > + virtual size_t GetBytes(unsigned char *buf, size_t len) { > + NumStreamFetches++; > + return read(Fd, buf, len); > + } > + > + error_code OpenFile(const std::string &Filename) { > + int OpenFlags = O_RDONLY; > +#ifdef O_BINARY > + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. > +#endif > + if (Filename == "-") > + Fd = 0; > + else > + Fd = ::open(Filename.c_str(), OpenFlags); > + if (Fd == -1) return error_code(errno, posix_category()); > + return success; > + } > +}; > + > +} > + > +namespace llvm { > +DataStreamer *getDataFileStreamer(const std::string &Filename, > + std::string *StrError) { > + DataFileStreamer *s = new DataFileStreamer(); > + error_code e = s->OpenFile(Filename); > + if (e != success) { > + *StrError = std::string("Could not open ") + Filename + ": " + > + e.message() + "\n"; > + return NULL; > + } > + return s; > +} > + > +} > > Modified: llvm/trunk/lib/Support/MemoryObject.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryObject.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Support/MemoryObject.cpp (original) > +++ llvm/trunk/lib/Support/MemoryObject.cpp Mon Feb 6 16:30:29 2012 > @@ -16,7 +16,7 @@ > int MemoryObject::readBytes(uint64_t address, > uint64_t size, > uint8_t* buf, > - uint64_t* copied) const { > + uint64_t* copied) { > uint64_t current = address; > uint64_t limit = getBase() + getExtent(); > > > Added: llvm/trunk/lib/Support/StreamableMemoryObject.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149918&view=auto > ============================================================================== > --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (added) > +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb 6 16:30:29 2012 > @@ -0,0 +1,137 @@ > +//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ -*-===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is distributed under the University of Illinois Open Source > +// License. See LICENSE.TXT for details. > +// > +//===----------------------------------------------------------------------===// > + > +#include "llvm/Support/StreamableMemoryObject.h" > +#include > +#include > + > + > +using namespace llvm; > + > +namespace { > + > +class RawMemoryObject : public StreamableMemoryObject { > +public: > + RawMemoryObject(const unsigned char *Start, const unsigned char *End) : > + FirstChar(Start), LastChar(End) { > + assert(LastChar > FirstChar && "Invalid start/end range"); > + } > + > + virtual uint64_t getBase() const { return 0; } > + virtual uint64_t getExtent() { return LastChar - FirstChar; } > + virtual int readByte(uint64_t address, uint8_t* ptr); > + virtual int readBytes(uint64_t address, > + uint64_t size, > + uint8_t* buf, > + uint64_t* copied); > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size); > + virtual bool isValidAddress(uint64_t address) {return validAddress(address);} > + virtual bool isObjectEnd(uint64_t address) {return objectEnd(address);} > + > +private: > + const uint8_t* const FirstChar; > + const uint8_t* const LastChar; > + > + // These are implemented as inline functions here to avoid multiple virtual > + // calls per public function > + bool validAddress(uint64_t address) { > + return static_cast(address) < LastChar - FirstChar; > + } > + bool objectEnd(uint64_t address) { > + return static_cast(address) == LastChar - FirstChar; > + } > + > + RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT > + void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT > +}; > + > +int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > + if (!validAddress(address)) return -1; > + *ptr = *((uint8_t *)(uintptr_t)(address + FirstChar)); > + return 0; > +} > + > +int RawMemoryObject::readBytes(uint64_t address, > + uint64_t size, > + uint8_t* buf, > + uint64_t* copied) { > + if (!validAddress(address) || !validAddress(address + size - 1)) return -1; > + memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); > + if (copied) *copied = size; > + return size; > +} > + > +const uint8_t *RawMemoryObject::getPointer(uint64_t address, uint64_t size) { > + return FirstChar + address; > +} > +} // anonymous namespace > + > +namespace llvm { > +// If the bitcode has a header, then its size is known, and we don't have to > +// block until we actually want to read it. > +bool StreamingMemoryObject::isValidAddress(uint64_t address) { > + if (ObjectSize && address < ObjectSize) return true; > + return fetchToPos(address); > +} > + > +bool StreamingMemoryObject::isObjectEnd(uint64_t address) { > + if (ObjectSize) return address == ObjectSize; > + fetchToPos(address); > + return address == ObjectSize && address != 0; > +} > + > +uint64_t StreamingMemoryObject::getExtent() { > + if (ObjectSize) return ObjectSize; > + size_t pos = BytesRead + kChunkSize; > + // keep fetching until we run out of bytes > + while (fetchToPos(pos)) pos += kChunkSize; > + return ObjectSize; > +} > + > +int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > + if (!fetchToPos(address)) return -1; > + *ptr = Bytes[address + BytesSkipped]; > + return 0; > +} > + > +int StreamingMemoryObject::readBytes(uint64_t address, > + uint64_t size, > + uint8_t* buf, > + uint64_t* copied) { > + if (!fetchToPos(address + size - 1)) return -1; > + memcpy(buf, &Bytes[address + BytesSkipped], size); > + if (copied) *copied = size; > + return 0; > +} > + > +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { > + if (BytesRead < s) return true; > + BytesSkipped = s; > + BytesRead -= s; > + return false; > +} > + > +void StreamingMemoryObject::setKnownObjectSize(size_t size) { > + ObjectSize = size; > + Bytes.reserve(size); > +} > + > +StreamableMemoryObject *getNonStreamedMemoryObject( > + const unsigned char *Start, const unsigned char *End) { > + return new RawMemoryObject(Start, End); > +} > + > +StreamableMemoryObject::~StreamableMemoryObject() { } > + > +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : > + Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), > + ObjectSize(0), EOFReached(false) { > + BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); > +} > +} > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original) > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -46,7 +46,7 @@ > /// getInstruction - See MCDisassembler. > DecodeStatus getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const; > @@ -71,7 +71,7 @@ > /// getInstruction - See MCDisassembler. > DecodeStatus getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const; > @@ -341,7 +341,7 @@ > } > > DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, > - const MemoryObject &Region, > + MemoryObject &Region, > uint64_t Address, > raw_ostream &os, > raw_ostream &cs) const { > @@ -691,7 +691,7 @@ > } > > DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, > - const MemoryObject &Region, > + MemoryObject &Region, > uint64_t Address, > raw_ostream &os, > raw_ostream &cs) const { > > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp (original) > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -502,7 +502,7 @@ > > MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const { > > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h (original) > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h Mon Feb 6 16:30:29 2012 > @@ -40,7 +40,7 @@ > /// getInstruction - See MCDisassembler. > MCDisassembler::DecodeStatus getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const; > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original) > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -112,7 +112,7 @@ > MCDisassembler::DecodeStatus > X86GenericDisassembler::getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const { > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Mon Feb 6 16:30:29 2012 > @@ -114,7 +114,7 @@ > /// getInstruction - See MCDisassembler. > DecodeStatus getInstruction(MCInst &instr, > uint64_t &size, > - const MemoryObject ®ion, > + MemoryObject ®ion, > uint64_t address, > raw_ostream &vStream, > raw_ostream &cStream) const; > > Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) > +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb 6 16:30:29 2012 > @@ -483,13 +483,13 @@ > if (MemBuf->getBufferSize() & 3) > return Error("Bitcode stream should be a multiple of 4 bytes in length"); > > - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); > - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > + const unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); > + const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > > // If we have a wrapper header, parse it and ignore the non-bc file contents. > // The magic number is 0x0B17C0DE stored in little endian. > if (isBitcodeWrapper(BufPtr, EndBufPtr)) > - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) > + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) > return Error("Invalid bitcode wrapper header"); > > BitstreamReader StreamFile(BufPtr, EndBufPtr); > > Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) > +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Feb 6 16:30:29 2012 > @@ -24,6 +24,7 @@ > #include "llvm/Analysis/DebugInfo.h" > #include "llvm/Assembly/AssemblyAnnotationWriter.h" > #include "llvm/Support/CommandLine.h" > +#include "llvm/Support/DataStream.h" > #include "llvm/Support/FormattedStream.h" > #include "llvm/Support/ManagedStatic.h" > #include "llvm/Support/MemoryBuffer.h" > @@ -126,12 +127,19 @@ > std::string ErrorMessage; > std::auto_ptr M; > > - { > - OwningPtr BufferPtr; > - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) > - ErrorMessage = ec.message(); > + // Use the bitcode streaming interface > + DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); > + if (streamer) { > + std::string DisplayFilename; > + if (InputFilename == "-") > + DisplayFilename = ""; > else > - M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); > + DisplayFilename = InputFilename; > + M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, > + &ErrorMessage)); > + if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { > + M.reset(); > + } > } > > if (M.get() == 0) { > @@ -183,4 +191,3 @@ > > return 0; > } > - > > Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) > +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Mon Feb 6 16:30:29 2012 > @@ -42,9 +42,9 @@ > VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} > > uint64_t getBase() const { return 0; } > - uint64_t getExtent() const { return Bytes.size(); } > + uint64_t getExtent() { return Bytes.size(); } > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > + int readByte(uint64_t Addr, uint8_t *Byte) { > if (Addr >= getExtent()) > return -1; > *Byte = Bytes[Addr].first; > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.cpp?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-objdump/MCFunction.cpp (original) > +++ llvm/trunk/tools/llvm-objdump/MCFunction.cpp Mon Feb 6 16:30:29 2012 > @@ -28,7 +28,7 @@ > > MCFunction > MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, > - const MemoryObject &Region, uint64_t Start, > + MemoryObject &Region, uint64_t Start, > uint64_t End, const MCInstrAnalysis *Ana, > raw_ostream &DebugOut, > SmallVectorImpl &Calls) { > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-objdump/MCFunction.h (original) > +++ llvm/trunk/tools/llvm-objdump/MCFunction.h Mon Feb 6 16:30:29 2012 > @@ -79,7 +79,7 @@ > // Create an MCFunction from a region of binary machine code. > static MCFunction > createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, > - const MemoryObject &Region, uint64_t Start, uint64_t End, > + MemoryObject &Region, uint64_t Start, uint64_t End, > const MCInstrAnalysis *Ana, raw_ostream &DebugOut, > SmallVectorImpl &Calls); > > > Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=149918&r1=149917&r2=149918&view=diff > ============================================================================== > --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original) > +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb 6 16:30:29 2012 > @@ -31,9 +31,9 @@ > StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} > > uint64_t getBase() const { return 0; } > - uint64_t getExtent() const { return Bytes.size(); } > + uint64_t getExtent() { return Bytes.size(); } > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > + int readByte(uint64_t Addr, uint8_t *Byte) { > if (Addr >= getExtent()) > return -1; > *Byte = Bytes[Addr]; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dschuff at google.com Tue Feb 7 13:29:35 2012 From: dschuff at google.com (Derek Schuff) Date: Tue, 7 Feb 2012 11:29:35 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ Message-ID: Hi Jim, Originally the patch was written such that the bitcode reader used a new container class to hold the bitcode, and get pieces of it using methods like getByte, getWord, etc. Chris asked me to use MemoryObject instead, which has a similar interface (readBytes et al), except that those methods are const. They definitely can't be const when each call can result in fetching more bytes from the stream, so all the MC constness changes are basically fallout from MemoryBuffer's readBytes method no longer being const. I'm not averse to going back to the other way, but I'd like to have some agreement from the relevant stakeholders as to the right approach before I put more work into it. -Derek On Tue, Feb 7, 2012 at 11:15 AM, Jim Grosbach wrote: > Hi Derek, > > I don't follow why this needs to change the MC disassemblers. Those have > nothing to do with bitcode. Can you elaborate? I'm uncomfortable with > removing the const'ness of the input to those methods, for example. > > -Jim > > On Feb 6, 2012, at 2:30 PM, Derek Schuff wrote: > > > Author: dschuff > > Date: Mon Feb 6 16:30:29 2012 > > New Revision: 149918 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=149918&view=rev > > Log: > > Enable streaming of bitcode > > > > This CL delays reading of function bodies from initial parse until > > materialization, allowing overlap of compilation with bitcode download. > > > > > > Added: > > llvm/trunk/include/llvm/Support/DataStream.h > > llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > > llvm/trunk/lib/Support/DataStream.cpp > > llvm/trunk/lib/Support/StreamableMemoryObject.cpp > > Modified: > > llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > > llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > > llvm/trunk/include/llvm/MC/MCDisassembler.h > > llvm/trunk/include/llvm/Support/MemoryObject.h > > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > > llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > > llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > > llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > > llvm/trunk/lib/Support/CMakeLists.txt > > llvm/trunk/lib/Support/MemoryObject.cpp > > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > > llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > > llvm/trunk/tools/llvm-dis/llvm-dis.cpp > > llvm/trunk/tools/llvm-mc/Disassembler.cpp > > llvm/trunk/tools/llvm-objdump/MCFunction.cpp > > llvm/trunk/tools/llvm-objdump/MCFunction.h > > llvm/trunk/tools/llvm-objdump/llvm-objdump.h > > > > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) > > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb 6 > 16:30:29 2012 > > @@ -15,10 +15,12 @@ > > #ifndef BITSTREAM_READER_H > > #define BITSTREAM_READER_H > > > > +#include "llvm/ADT/OwningPtr.h" > > #include "llvm/Bitcode/BitCodes.h" > > #include > > #include > > #include > > +#include "llvm/Support/StreamableMemoryObject.h" > > > > namespace llvm { > > > > @@ -36,9 +38,7 @@ > > std::vector > RecordNames; > > }; > > private: > > - /// FirstChar/LastChar - This remembers the first and last bytes of > the > > - /// stream. > > - const unsigned char *FirstChar, *LastChar; > > + OwningPtr BitcodeBytes; > > > > std::vector BlockInfoRecords; > > > > @@ -47,10 +47,10 @@ > > /// uses this. > > bool IgnoreBlockInfoNames; > > > > - BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED > > - void operator=(const BitstreamReader&); // NOT IMPLEMENTED > > + BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT > > + void operator=(const BitstreamReader&); // DO NOT IMPLEMENT > > public: > > - BitstreamReader() : FirstChar(0), LastChar(0), > IgnoreBlockInfoNames(true) { > > + BitstreamReader() : IgnoreBlockInfoNames(true) { > > } > > > > BitstreamReader(const unsigned char *Start, const unsigned char *End) { > > @@ -58,12 +58,17 @@ > > init(Start, End); > > } > > > > + BitstreamReader(StreamableMemoryObject *bytes) { > > + BitcodeBytes.reset(bytes); > > + } > > + > > void init(const unsigned char *Start, const unsigned char *End) { > > - FirstChar = Start; > > - LastChar = End; > > assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 > bytes"); > > + BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); > > } > > > > + StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } > > + > > ~BitstreamReader() { > > // Free the BlockInfoRecords. > > while (!BlockInfoRecords.empty()) { > > @@ -75,9 +80,6 @@ > > BlockInfoRecords.pop_back(); > > } > > } > > - > > - const unsigned char *getFirstChar() const { return FirstChar; } > > - const unsigned char *getLastChar() const { return LastChar; } > > > > /// CollectBlockInfoNames - This is called by clients that want > block/record > > /// name information. > > @@ -122,7 +124,7 @@ > > class BitstreamCursor { > > friend class Deserializer; > > BitstreamReader *BitStream; > > - const unsigned char *NextChar; > > + size_t NextChar; > > > > /// CurWord - This is the current data we have pulled from the stream > but have > > /// not returned to the client. > > @@ -156,8 +158,7 @@ > > } > > > > explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { > > - NextChar = R.getFirstChar(); > > - assert(NextChar && "Bitstream not initialized yet"); > > + NextChar = 0; > > CurWord = 0; > > BitsInCurWord = 0; > > CurCodeSize = 2; > > @@ -167,8 +168,7 @@ > > freeState(); > > > > BitStream = &R; > > - NextChar = R.getFirstChar(); > > - assert(NextChar && "Bitstream not initialized yet"); > > + NextChar = 0; > > CurWord = 0; > > BitsInCurWord = 0; > > CurCodeSize = 2; > > @@ -225,13 +225,38 @@ > > /// GetAbbrevIDWidth - Return the number of bits used to encode an > abbrev #. > > unsigned GetAbbrevIDWidth() const { return CurCodeSize; } > > > > - bool AtEndOfStream() const { > > - return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; > > + bool isEndPos(size_t pos) { > > + return > BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos)); > > + } > > + > > + bool canSkipToPos(size_t pos) const { > > + // pos can be skipped to if it is a valid address or one byte past > the end. > > + return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( > > + static_cast(pos - 1)); > > + } > > + > > + unsigned char getByte(size_t pos) { > > + uint8_t byte = -1; > > + BitStream->getBitcodeBytes().readByte(pos, &byte); > > + return byte; > > + } > > + > > + uint32_t getWord(size_t pos) { > > + uint32_t word = -1; > > + BitStream->getBitcodeBytes().readBytes(pos, > > + sizeof(word), > > + reinterpret_cast *>(&word), > > + NULL); > > + return word; > > + } > > + > > + bool AtEndOfStream() { > > + return isEndPos(NextChar) && BitsInCurWord == 0; > > } > > > > /// GetCurrentBitNo - Return the bit # of the bit we are reading. > > uint64_t GetCurrentBitNo() const { > > - return (NextChar-BitStream->getFirstChar())*CHAR_BIT - > BitsInCurWord; > > + return NextChar*CHAR_BIT - BitsInCurWord; > > } > > > > BitstreamReader *getBitStreamReader() { > > @@ -246,12 +271,10 @@ > > void JumpToBit(uint64_t BitNo) { > > uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; > > uintptr_t WordBitNo = uintptr_t(BitNo) & 31; > > - assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- > > - BitStream->getFirstChar()) && > > - "Invalid location"); > > + assert(canSkipToPos(ByteNo) && "Invalid location"); > > > > // Move the cursor to the right word. > > - NextChar = BitStream->getFirstChar()+ByteNo; > > + NextChar = ByteNo; > > BitsInCurWord = 0; > > CurWord = 0; > > > > @@ -272,7 +295,7 @@ > > } > > > > // If we run out of data, stop at the end of the stream. > > - if (NextChar == BitStream->getLastChar()) { > > + if (isEndPos(NextChar)) { > > CurWord = 0; > > BitsInCurWord = 0; > > return 0; > > @@ -281,8 +304,7 @@ > > unsigned R = CurWord; > > > > // Read the next word from the stream. > > - CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | > > - (NextChar[2] << 16) | (NextChar[3] << 24); > > + CurWord = getWord(NextChar); > > NextChar += 4; > > > > // Extract NumBits-BitsInCurWord from what we just read. > > @@ -376,9 +398,8 @@ > > > > // Check that the block wasn't partially defined, and that the > offset isn't > > // bogus. > > - const unsigned char *const SkipTo = NextChar + NumWords*4; > > - if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || > > - SkipTo < BitStream->getFirstChar()) > > + size_t SkipTo = NextChar + NumWords*4; > > + if (AtEndOfStream() || !canSkipToPos(SkipTo)) > > return true; > > > > NextChar = SkipTo; > > @@ -409,8 +430,7 @@ > > if (NumWordsP) *NumWordsP = NumWords; > > > > // Validate that this block is sane. > > - if (CurCodeSize == 0 || AtEndOfStream() || > > - NextChar+NumWords*4 > BitStream->getLastChar()) > > + if (CurCodeSize == 0 || AtEndOfStream()) > > return true; > > > > return false; > > @@ -512,24 +532,25 @@ > > SkipToWord(); // 32-bit alignment > > > > // Figure out where the end of this blob will be including tail > padding. > > - const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); > > + size_t NewEnd = NextChar+((NumElts+3)&~3); > > > > // If this would read off the end of the bitcode file, just set > the > > // record to empty and return. > > - if (NewEnd > BitStream->getLastChar()) { > > + if (!canSkipToPos(NewEnd)) { > > Vals.append(NumElts, 0); > > - NextChar = BitStream->getLastChar(); > > + NextChar = BitStream->getBitcodeBytes().getExtent(); > > break; > > } > > > > // Otherwise, read the number of bytes. If we can return a > reference to > > // the data, do so to avoid copying it. > > if (BlobStart) { > > - *BlobStart = (const char*)NextChar; > > + *BlobStart = (const > char*)BitStream->getBitcodeBytes().getPointer( > > + NextChar, NumElts); > > *BlobLen = NumElts; > > } else { > > for (; NumElts; ++NextChar, --NumElts) > > - Vals.push_back(*NextChar); > > + Vals.push_back(getByte(NextChar)); > > } > > // Skip over tail padding. > > NextChar = NewEnd; > > > > Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) > > +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Feb 6 16:30:29 > 2012 > > @@ -17,35 +17,45 @@ > > #include > > > > namespace llvm { > > - class Module; > > - class MemoryBuffer; > > - class ModulePass; > > class BitstreamWriter; > > + class MemoryBuffer; > > + class DataStreamer; > > class LLVMContext; > > + class Module; > > + class ModulePass; > > class raw_ostream; > > - > > + > > /// getLazyBitcodeModule - Read the header of the specified bitcode > buffer > > /// and prepare for lazy deserialization of function bodies. If > successful, > > /// this takes ownership of 'buffer' and returns a non-null pointer. > On > > /// error, this returns null, *does not* take ownership of Buffer, and > fills > > /// in *ErrMsg with an error description if ErrMsg is non-null. > > Module *getLazyBitcodeModule(MemoryBuffer *Buffer, > > - LLVMContext& Context, > > + LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > + /// getStreamedBitcodeModule - Read the header of the specified stream > > + /// and prepare for lazy deserialization and streaming of function > bodies. > > + /// On error, this returns null, and fills in *ErrMsg with an error > > + /// description if ErrMsg is non-null. > > + Module *getStreamedBitcodeModule(const std::string &name, > > + DataStreamer *streamer, > > + LLVMContext &Context, > > + std::string *ErrMsg = 0); > > + > > /// getBitcodeTargetTriple - Read the header of the specified bitcode > > /// buffer and extract just the triple information. If successful, > > /// this returns a string and *does not* take ownership > > /// of 'buffer'. On error, this returns "", and fills in *ErrMsg > > /// if ErrMsg is non-null. > > std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, > > - LLVMContext& Context, > > + LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > /// ParseBitcodeFile - Read the specified bitcode file, returning the > module. > > /// If an error occurs, this returns null and fills in *ErrMsg if it is > > /// non-null. This method *never* takes ownership of Buffer. > > - Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, > > + Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > /// WriteBitcodeToFile - Write the specified module to the specified > > @@ -60,8 +70,8 @@ > > /// createBitcodeWriterPass - Create and return a pass that writes the > module > > /// to the specified ostream. > > ModulePass *createBitcodeWriterPass(raw_ostream &Str); > > - > > - > > + > > + > > /// isBitcodeWrapper - Return true if the given bytes are the magic > bytes > > /// for an LLVM IR bitcode wrapper. > > /// > > @@ -109,21 +119,24 @@ > > /// uint32_t BitcodeSize; // Size of traditional bitcode file. > > /// ... potentially other gunk ... > > /// }; > > - /// > > + /// > > /// This function is called when we find a file with a matching magic > number. > > /// In this case, skip down to the subsection of the file that is > actually a > > /// BC file. > > - static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr, > > - unsigned char *&BufEnd) { > > + /// If 'VerifyBufferSize' is true, check that the buffer is large > enough to > > + /// contain the whole bitcode file. > > + static inline bool SkipBitcodeWrapperHeader(const unsigned char > *&BufPtr, > > + const unsigned char > *&BufEnd, > > + bool VerifyBufferSize) { > > enum { > > KnownHeaderSize = 4*4, // Size of header we read. > > OffsetField = 2*4, // Offset in bytes to Offset field. > > SizeField = 3*4 // Offset in bytes to Size field. > > }; > > - > > + > > // Must contain the header! > > if (BufEnd-BufPtr < KnownHeaderSize) return true; > > - > > + > > unsigned Offset = ( BufPtr[OffsetField ] | > > (BufPtr[OffsetField+1] << 8) | > > (BufPtr[OffsetField+2] << 16) | > > @@ -132,9 +145,9 @@ > > (BufPtr[SizeField +1] << 8) | > > (BufPtr[SizeField +2] << 16) | > > (BufPtr[SizeField +3] << 24)); > > - > > + > > // Verify that Offset+Size fits in the file. > > - if (Offset+Size > unsigned(BufEnd-BufPtr)) > > + if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) > > return true; > > BufPtr += Offset; > > BufEnd = BufPtr+Size; > > > > Modified: llvm/trunk/include/llvm/MC/MCDisassembler.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/MC/MCDisassembler.h (original) > > +++ llvm/trunk/include/llvm/MC/MCDisassembler.h Mon Feb 6 16:30:29 2012 > > @@ -79,7 +79,7 @@ > > /// MCDisassembler::Fail if the instruction was > invalid. > > virtual DecodeStatus getInstruction(MCInst& instr, > > uint64_t& size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const = 0; > > > > Added: llvm/trunk/include/llvm/Support/DataStream.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149918&view=auto > > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/DataStream.h (added) > > +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,38 @@ > > +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ > -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > > +//===----------------------------------------------------------------------===// > > +// > > +// This header defines DataStreamer, which fetches bytes of data from > > +// a stream source. It provides support for streaming (lazy reading) of > > +// data, e.g. bitcode > > +// > > > +//===----------------------------------------------------------------------===// > > + > > + > > +#ifndef LLVM_SUPPORT_DATASTREAM_H_ > > +#define LLVM_SUPPORT_DATASTREAM_H_ > > + > > +#include > > + > > +namespace llvm { > > + > > +class DataStreamer { > > +public: > > + /// Fetch bytes [start-end) from the stream, and write them to the > > + /// buffer pointed to by buf. Returns the number of bytes actually > written. > > + virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; > > + > > + virtual ~DataStreamer(); > > +}; > > + > > +DataStreamer *getDataFileStreamer(const std::string &Filename, > > + std::string *Err); > > + > > +} > > + > > +#endif // LLVM_SUPPORT_DATASTREAM_H_ > > > > Modified: llvm/trunk/include/llvm/Support/MemoryObject.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryObject.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/MemoryObject.h (original) > > +++ llvm/trunk/include/llvm/Support/MemoryObject.h Mon Feb 6 16:30:29 > 2012 > > @@ -34,7 +34,7 @@ > > /// is getBase() + getExtent() - 1). > > /// > > /// @result - The size of the region. > > - virtual uint64_t getExtent() const = 0; > > + virtual uint64_t getExtent() = 0; > > > > /// readByte - Tries to read a single byte from the region. > > /// > > @@ -42,7 +42,7 @@ > > /// @param ptr - A pointer to a byte to be filled in. Must be > non-NULL. > > /// @result - 0 if successful; -1 if not. Failure may be due > to a > > /// bounds violation or an implementation-specific > error. > > - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; > > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > > > > /// readBytes - Tries to read a contiguous range of bytes from > the > > /// region, up to the end of the region. > > @@ -61,7 +61,7 @@ > > virtual int readBytes(uint64_t address, > > uint64_t size, > > uint8_t* buf, > > - uint64_t* copied) const; > > + uint64_t* copied); > > }; > > > > } > > > > Added: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149918&view=auto > > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (added) > > +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb 6 > 16:30:29 2012 > > @@ -0,0 +1,181 @@ > > +//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ > -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > > +//===----------------------------------------------------------------------===// > > + > > + > > +#ifndef STREAMABLEMEMORYOBJECT_H_ > > +#define STREAMABLEMEMORYOBJECT_H_ > > + > > +#include "llvm/ADT/OwningPtr.h" > > +#include "llvm/Support/MemoryObject.h" > > +#include "llvm/Support/DataStream.h" > > +#include > > + > > +namespace llvm { > > + > > +/// StreamableMemoryObject - Interface to data which might be streamed. > > +/// Streamability has 2 important implications/restrictions. First, the > data > > +/// might not yet exist in memory when the request is made. This just > means > > +/// that readByte/readBytes might have to block or do some work to get > it. > > +/// More significantly, the exact size of the object might not be known > until > > +/// it has all been fetched. This means that to return the right result, > > +/// getExtent must also wait for all the data to arrive; therefore it > should > > +/// not be called on objects which are actually streamed (this would > defeat > > +/// the purpose of streaming). Instead, isValidAddress and isObjectEnd > can be > > +/// used to test addresses without knowing the exact size of the stream. > > +/// Finally, getPointer can be used instead of readBytes to avoid extra > copying. > > +class StreamableMemoryObject : public MemoryObject { > > + public: > > + /// Destructor - Override as necessary. > > + virtual ~StreamableMemoryObject(); > > + > > + /// getBase - Returns the lowest valid address in the region. > > + /// > > + /// @result - The lowest valid address. > > + virtual uint64_t getBase() const = 0; > > + > > + /// getExtent - Returns the size of the region in bytes. (The > region is > > + /// contiguous, so the highest valid address of the > region > > + /// is getBase() + getExtent() - 1). > > + /// May block until all bytes in the stream have > been read > > + /// > > + /// @result - The size of the region. > > + virtual uint64_t getExtent() = 0; > > + > > + /// readByte - Tries to read a single byte from the region. > > + /// May block until (address - base) bytes have > been read > > + /// @param address - The address of the byte, in the same space as > getBase(). > > + /// @param ptr - A pointer to a byte to be filled in. Must be > non-NULL. > > + /// @result - 0 if successful; -1 if not. Failure may be due > to a > > + /// bounds violation or an implementation-specific > error. > > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > > + > > + /// readBytes - Tries to read a contiguous range of bytes from > the > > + /// region, up to the end of the region. > > + /// May block until (address - base + size) bytes > have > > + /// been read. Additionally, > StreamableMemoryObjects will > > + /// not do partial reads - if size bytes cannot be > read, > > + /// readBytes will fail. > > + /// > > + /// @param address - The address of the first byte, in the same > space as > > + /// getBase(). > > + /// @param size - The maximum number of bytes to copy. > > + /// @param buf - A pointer to a buffer to be filled in. Must be > non-NULL > > + /// and large enough to hold size bytes. > > + /// @param copied - A pointer to a nunber that is filled in with > the number > > + /// of bytes actually read. May be NULL. > > + /// @result - 0 if successful; -1 if not. Failure may be due > to a > > + /// bounds violation or an implementation-specific > error. > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) = 0; > > + > > + /// getPointer - Ensures that the requested data is in memory, and > returns > > + /// A pointer to it. More efficient than using > readBytes if the > > + /// data is already in memory. > > + /// May block until (address - base + size) bytes have > been read > > + /// @param address - address of the byte, in the same space as > getBase() > > + /// @param size - amount of data that must be available on return > > + /// @result - valid pointer to the requested data > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) = > 0; > > + > > + /// isValidAddress - Returns true if the address is within the object > > + /// (i.e. between base and base + extent - 1 > inclusive) > > + /// May block until (address - base) bytes have been > read > > + /// @param address - address of the byte, in the same space as > getBase() > > + /// @result - true if the address may be read with readByte() > > + virtual bool isValidAddress(uint64_t address) = 0; > > + > > + /// isObjectEnd - Returns true if the address is one past the end > of the > > + /// object (i.e. if it is equal to base + extent) > > + /// May block until (address - base) bytes have been > read > > + /// @param address - address of the byte, in the same space as > getBase() > > + /// @result - true if the address is equal to base + extent > > + virtual bool isObjectEnd(uint64_t address) = 0; > > +}; > > + > > +/// StreamingMemoryObject - interface to data which is actually > streamed from > > +/// a DataStreamer. In addition to inherited members, it has the > > +/// dropLeadingBytes and setKnownObjectSize methods which are not > applicable > > +/// to non-streamed objects. > > +class StreamingMemoryObject : public StreamableMemoryObject { > > +public: > > + StreamingMemoryObject(DataStreamer *streamer); > > + virtual uint64_t getBase() const { return 0; } > > + virtual uint64_t getExtent(); > > + virtual int readByte(uint64_t address, uint8_t* ptr); > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied); > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) { > > + // This could be fixed by ensuring the bytes are fetched and making > a copy, > > + // requiring that the bitcode size be known, or otherwise ensuring > that > > + // the memory doesn't go away/get reallocated, but it's > > + // not currently necessary. Users that need the pointer don't > stream. > > + assert(0 && "getPointer in streaming memory objects not allowed"); > > + return NULL; > > + } > > + virtual bool isValidAddress(uint64_t address); > > + virtual bool isObjectEnd(uint64_t address); > > + > > + /// Drop s bytes from the front of the stream, pushing the positions > of the > > + /// remaining bytes down by s. This is used to skip past the bitcode > header, > > + /// since we don't know a priori if it's present, and we can't put > bytes > > + /// back into the stream once we've read them. > > + bool dropLeadingBytes(size_t s); > > + > > + /// If the data object size is known in advance, many of the > operations can > > + /// be made more efficient, so this method should be called before > reading > > + /// starts (although it can be called anytime). > > + void setKnownObjectSize(size_t size); > > + > > +private: > > + const static uint32_t kChunkSize = 4096 * 4; > > + std::vector Bytes; > > + OwningPtr Streamer; > > + size_t BytesRead; // Bytes read from stream > > + size_t BytesSkipped;// Bytes skipped at start of stream (e.g. > wrapper/header) > > + size_t ObjectSize; // 0 if unknown, set if wrapper was seen or EOF > reached > > + bool EOFReached; > > + > > + // Fetch enough bytes such that Pos can be read or EOF is reached > > + // (i.e. BytesRead > Pos). Return true if Pos can be read. > > + // Unlike most of the functions in BitcodeReader, returns true on > success. > > + // Most of the requests will be small, but we fetch at kChunkSize > bytes > > + // at a time to avoid making too many potentially expensive GetBytes > calls > > + bool fetchToPos(size_t Pos) { > > + if (EOFReached) return Pos < ObjectSize; > > + while (Pos >= BytesRead) { > > + Bytes.resize(BytesRead + kChunkSize); > > + size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + > BytesSkipped], > > + kChunkSize); > > + BytesRead += bytes; > > + if (bytes < kChunkSize) { > > + if (ObjectSize && BytesRead < Pos) > > + assert(0 && "Unexpected short read fetching bitcode"); > > + if (BytesRead <= Pos) { // reached EOF/ran out of bytes > > + ObjectSize = BytesRead; > > + EOFReached = true; > > + return false; > > + } > > + } > > + } > > + return true; > > + } > > + > > + StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT > IMPLEMENT > > + void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT > > +}; > > + > > +StreamableMemoryObject *getNonStreamedMemoryObject( > > + const unsigned char *Start, const unsigned char *End); > > + > > +} > > +#endif // STREAMABLEMEMORYOBJECT_H_ > > > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) > > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 16:30:29 > 2012 > > @@ -22,6 +22,7 @@ > > #include "llvm/AutoUpgrade.h" > > #include "llvm/ADT/SmallString.h" > > #include "llvm/ADT/SmallVector.h" > > +#include "llvm/Support/DataStream.h" > > #include "llvm/Support/MathExtras.h" > > #include "llvm/Support/MemoryBuffer.h" > > #include "llvm/OperandTraits.h" > > @@ -1409,8 +1410,36 @@ > > return false; > > } > > > > -bool BitcodeReader::ParseModule() { > > - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > > +bool BitcodeReader::GlobalCleanup() { > > + // Patch the initializers for globals and aliases up. > > + ResolveGlobalAndAliasInits(); > > + if (!GlobalInits.empty() || !AliasInits.empty()) > > + return Error("Malformed global initializer set"); > > + > > + // Look for intrinsic functions which need to be upgraded at some > point > > + for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); > > + FI != FE; ++FI) { > > + Function *NewFn; > > + if (UpgradeIntrinsicFunction(FI, NewFn)) > > + UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > > + } > > + > > + // Look for global variables which need to be renamed. > > + for (Module::global_iterator > > + GI = TheModule->global_begin(), GE = TheModule->global_end(); > > + GI != GE; ++GI) > > + UpgradeGlobalVariable(GI); > > + // Force deallocation of memory for these vectors to favor the client > that > > + // want lazy deserialization. > > + std::vector > >().swap(GlobalInits); > > + std::vector >().swap(AliasInits); > > + return false; > > +} > > + > > +bool BitcodeReader::ParseModule(bool Resume) { > > + if (Resume) > > + Stream.JumpToBit(NextUnreadBit); > > + else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > > return Error("Malformed block record"); > > > > SmallVector Record; > > @@ -1424,33 +1453,7 @@ > > if (Stream.ReadBlockEnd()) > > return Error("Error at end of module block"); > > > > - // Patch the initializers for globals and aliases up. > > - ResolveGlobalAndAliasInits(); > > - if (!GlobalInits.empty() || !AliasInits.empty()) > > - return Error("Malformed global initializer set"); > > - if (!FunctionsWithBodies.empty()) > > - return Error("Too few function bodies found"); > > - > > - // Look for intrinsic functions which need to be upgraded at some > point > > - for (Module::iterator FI = TheModule->begin(), FE = > TheModule->end(); > > - FI != FE; ++FI) { > > - Function* NewFn; > > - if (UpgradeIntrinsicFunction(FI, NewFn)) > > - UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > > - } > > - > > - // Look for global variables which need to be renamed. > > - for (Module::global_iterator > > - GI = TheModule->global_begin(), GE = > TheModule->global_end(); > > - GI != GE; ++GI) > > - UpgradeGlobalVariable(GI); > > - > > - // Force deallocation of memory for these vectors to favor the > client that > > - // want lazy deserialization. > > - std::vector > >().swap(GlobalInits); > > - std::vector > >().swap(AliasInits); > > - std::vector().swap(FunctionsWithBodies); > > - return false; > > + return GlobalCleanup(); > > } > > > > if (Code == bitc::ENTER_SUBBLOCK) { > > @@ -1474,6 +1477,7 @@ > > case bitc::VALUE_SYMTAB_BLOCK_ID: > > if (ParseValueSymbolTable()) > > return true; > > + SeenValueSymbolTable = true; > > break; > > case bitc::CONSTANTS_BLOCK_ID: > > if (ParseConstants() || ResolveGlobalAndAliasInits()) > > @@ -1486,13 +1490,25 @@ > > case bitc::FUNCTION_BLOCK_ID: > > // If this is the first function body we've seen, reverse the > > // FunctionsWithBodies list. > > - if (!HasReversedFunctionsWithBodies) { > > + if (!SeenFirstFunctionBody) { > > std::reverse(FunctionsWithBodies.begin(), > FunctionsWithBodies.end()); > > - HasReversedFunctionsWithBodies = true; > > + if (GlobalCleanup()) > > + return true; > > + SeenFirstFunctionBody = true; > > } > > > > if (RememberAndSkipFunctionBody()) > > return true; > > + // For streaming bitcode, suspend parsing when we reach the > function > > + // bodies. Subsequent materialization calls will resume it when > > + // necessary. For streaming, the function bodies must be at the > end of > > + // the bitcode. If the bitcode file is old, the symbol table > will be > > + // at the end instead and will not have been seen yet. In this > case, > > + // just finish the parse now. > > + if (LazyStreamer && SeenValueSymbolTable) { > > + NextUnreadBit = Stream.GetCurrentBitNo(); > > + return false; > > + } > > break; > > case bitc::USELIST_BLOCK_ID: > > if (ParseUseLists()) > > @@ -1651,8 +1667,10 @@ > > > > // If this is a function with a body, remember the prototype we are > > // creating now, so that we can match up the body with them later. > > - if (!isProto) > > + if (!isProto) { > > FunctionsWithBodies.push_back(Func); > > + if (LazyStreamer) DeferredFunctionInfo[Func] = 0; > > + } > > break; > > } > > // ALIAS: [alias type, aliasee val#, linkage] > > @@ -1691,24 +1709,7 @@ > > bool BitcodeReader::ParseBitcodeInto(Module *M) { > > TheModule = 0; > > > > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > - > > - if (Buffer->getBufferSize() & 3) { > > - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, > BufEnd)) > > - return Error("Invalid bitcode signature"); > > - else > > - return Error("Bitcode stream should be a multiple of 4 bytes in > length"); > > - } > > - > > - // If we have a wrapper header, parse it and ignore the non-bc file > contents. > > - // The magic number is 0x0B17C0DE stored in little endian. > > - if (isBitcodeWrapper(BufPtr, BufEnd)) > > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > > - return Error("Invalid bitcode wrapper header"); > > - > > - StreamFile.init(BufPtr, BufEnd); > > - Stream.init(StreamFile); > > + if (InitStream()) return true; > > > > // Sniff for the signature. > > if (Stream.Read(8) != 'B' || > > @@ -1750,8 +1751,9 @@ > > if (TheModule) > > return Error("Multiple MODULE_BLOCKs in same stream"); > > TheModule = M; > > - if (ParseModule()) > > + if (ParseModule(false)) > > return true; > > + if (LazyStreamer) return false; > > break; > > default: > > if (Stream.SkipBlock()) > > @@ -1819,20 +1821,7 @@ > > } > > > > bool BitcodeReader::ParseTriple(std::string &Triple) { > > - if (Buffer->getBufferSize() & 3) > > - return Error("Bitcode stream should be a multiple of 4 bytes in > length"); > > - > > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > - > > - // If we have a wrapper header, parse it and ignore the non-bc file > contents. > > - // The magic number is 0x0B17C0DE stored in little endian. > > - if (isBitcodeWrapper(BufPtr, BufEnd)) > > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > > - return Error("Invalid bitcode wrapper header"); > > - > > - StreamFile.init(BufPtr, BufEnd); > > - Stream.init(StreamFile); > > + if (InitStream()) return true; > > > > // Sniff for the signature. > > if (Stream.Read(8) != 'B' || > > @@ -2708,6 +2697,19 @@ > > return false; > > } > > > > +/// FindFunctionInStream - Find the function body in the bitcode stream > > +bool BitcodeReader::FindFunctionInStream(Function *F, > > + DenseMap::iterator > DeferredFunctionInfoIterator) { > > + while (DeferredFunctionInfoIterator->second == 0) { > > + if (Stream.AtEndOfStream()) > > + return Error("Could not find Function in stream"); > > + // ParseModule will parse the next body in the stream and set its > > + // position in the DeferredFunctionInfo map. > > + if (ParseModule(true)) return true; > > + } > > + return false; > > +} > > + > > > //===----------------------------------------------------------------------===// > > // GVMaterializer implementation > > > //===----------------------------------------------------------------------===// > > @@ -2728,6 +2730,10 @@ > > > > DenseMap::iterator DFII = > DeferredFunctionInfo.find(F); > > assert(DFII != DeferredFunctionInfo.end() && "Deferred function not > found!"); > > + // If its position is recorded as 0, its body is somewhere in the > stream > > + // but we haven't seen it yet. > > + if (DFII->second == 0) > > + if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; > > > > // Move the bit stream to the saved position of the deferred function > body. > > Stream.JumpToBit(DFII->second); > > @@ -2805,6 +2811,57 @@ > > return false; > > } > > > > +bool BitcodeReader::InitStream() { > > + if (LazyStreamer) return InitLazyStream(); > > + return InitStreamFromBuffer(); > > +} > > + > > +bool BitcodeReader::InitStreamFromBuffer() { > > + const unsigned char *BufPtr = (unsigned char > *)Buffer->getBufferStart(); > > + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > + > > + if (Buffer->getBufferSize() & 3) { > > + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, > BufEnd)) > > + return Error("Invalid bitcode signature"); > > + else > > + return Error("Bitcode stream should be a multiple of 4 bytes in > length"); > > + } > > + > > + // If we have a wrapper header, parse it and ignore the non-bc file > contents. > > + // The magic number is 0x0B17C0DE stored in little endian. > > + if (isBitcodeWrapper(BufPtr, BufEnd)) > > + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) > > + return Error("Invalid bitcode wrapper header"); > > + > > + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); > > + Stream.init(*StreamFile); > > + > > + return false; > > +} > > + > > +bool BitcodeReader::InitLazyStream() { > > + // Check and strip off the bitcode wrapper; BitstreamReader expects > never to > > + // see it. > > + StreamingMemoryObject *Bytes = new > StreamingMemoryObject(LazyStreamer); > > + StreamFile.reset(new BitstreamReader(Bytes)); > > + Stream.init(*StreamFile); > > + > > + unsigned char buf[16]; > > + if (Bytes->readBytes(0, 16, buf, NULL) == -1) > > + return Error("Bitcode stream must be at least 16 bytes in length"); > > + > > + if (!isBitcode(buf, buf + 16)) > > + return Error("Invalid bitcode signature"); > > + > > + if (isBitcodeWrapper(buf, buf + 4)) { > > + const unsigned char *bitcodeStart = buf; > > + const unsigned char *bitcodeEnd = buf + 16; > > + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); > > + Bytes->dropLeadingBytes(bitcodeStart - buf); > > + Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); > > + } > > + return false; > > +} > > > > > //===----------------------------------------------------------------------===// > > // External interface > > @@ -2833,6 +2890,24 @@ > > return M; > > } > > > > + > > +Module *llvm::getStreamedBitcodeModule(const std::string &name, > > + DataStreamer *streamer, > > + LLVMContext &Context, > > + std::string *ErrMsg) { > > + Module *M = new Module(name, Context); > > + BitcodeReader *R = new BitcodeReader(streamer, Context); > > + M->setMaterializer(R); > > + if (R->ParseBitcodeInto(M)) { > > + if (ErrMsg) > > + *ErrMsg = R->getErrorString(); > > + delete M; // Also deletes R. > > + return 0; > > + } > > + R->setBufferOwned(false); // no buffer to delete > > + return M; > > +} > > + > > /// ParseBitcodeFile - Read the specified bitcode file, returning the > module. > > /// If an error occurs, return null and fill in *ErrMsg if non-null. > > Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& > Context, > > > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) > > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Mon Feb 6 16:30:29 > 2012 > > @@ -126,8 +126,11 @@ > > Module *TheModule; > > MemoryBuffer *Buffer; > > bool BufferOwned; > > - BitstreamReader StreamFile; > > + OwningPtr StreamFile; > > BitstreamCursor Stream; > > + DataStreamer *LazyStreamer; > > + uint64_t NextUnreadBit; > > + bool SeenValueSymbolTable; > > > > const char *ErrorString; > > > > @@ -161,9 +164,10 @@ > > // Map the bitcode's custom MDKind ID to the Module's MDKind ID. > > DenseMap MDKindMap; > > > > - // After the module header has been read, the FunctionsWithBodies > list is > > - // reversed. This keeps track of whether we've done this yet. > > - bool HasReversedFunctionsWithBodies; > > + // Several operations happen after the module header has been read, > but > > + // before function bodies are processed. This keeps track of whether > > + // we've done this yet. > > + bool SeenFirstFunctionBody; > > > > /// DeferredFunctionInfo - When function bodies are initially scanned, > this > > /// map contains info about where to find deferred function body in the > > @@ -178,8 +182,13 @@ > > public: > > explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) > > : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), > > - ErrorString(0), ValueList(C), MDValueList(C) { > > - HasReversedFunctionsWithBodies = false; > > + LazyStreamer(0), SeenValueSymbolTable(false), ErrorString(0), > > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > > + } > > + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) > > + : Context(C), TheModule(0), Buffer(0), BufferOwned(false), > > + LazyStreamer(streamer), SeenValueSymbolTable(false), > ErrorString(0), > > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > > } > > ~BitcodeReader() { > > FreeState(); > > @@ -258,7 +267,7 @@ > > } > > > > > > - bool ParseModule(); > > + bool ParseModule(bool Resume); > > bool ParseAttributeBlock(); > > bool ParseTypeTable(); > > bool ParseTypeTableBody(); > > @@ -267,11 +276,17 @@ > > bool ParseConstants(); > > bool RememberAndSkipFunctionBody(); > > bool ParseFunctionBody(Function *F); > > + bool GlobalCleanup(); > > bool ResolveGlobalAndAliasInits(); > > bool ParseMetadata(); > > bool ParseMetadataAttachment(); > > bool ParseModuleTriple(std::string &Triple); > > bool ParseUseLists(); > > + bool InitStream(); > > + bool InitStreamFromBuffer(); > > + bool InitLazyStream(); > > + bool FindFunctionInStream(Function *F, > > + DenseMap::iterator > DeferredFunctionInfoIterator); > > }; > > > > } // End llvm namespace > > > > Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) > > +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 6 16:30:29 > 2012 > > @@ -1738,11 +1738,6 @@ > > // Emit metadata. > > WriteModuleMetadata(M, VE, Stream); > > > > - // Emit function bodies. > > - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > > - if (!F->isDeclaration()) > > - WriteFunction(*F, VE, Stream); > > - > > // Emit metadata. > > WriteModuleMetadataStore(M, Stream); > > > > @@ -1753,6 +1748,11 @@ > > if (EnablePreserveUseListOrdering) > > WriteModuleUseLists(M, VE, Stream); > > > > + // Emit function bodies. > > + for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > > + if (!F->isDeclaration()) > > + WriteFunction(*F, VE, Stream); > > + > > Stream.ExitBlock(); > > } > > > > > > Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) > > +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Feb 6 > 16:30:29 2012 > > @@ -100,9 +100,9 @@ > > Bytes(bytes), Size(size), BasePC(basePC) {} > > > > uint64_t getBase() const { return BasePC; } > > - uint64_t getExtent() const { return Size; } > > + uint64_t getExtent() { return Size; } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr - BasePC >= Size) > > return -1; > > *Byte = Bytes[Addr - BasePC]; > > > > Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) > > +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Mon Feb 6 > 16:30:29 2012 > > @@ -207,8 +207,8 @@ > > void *arg) : Callback(callback), Arg(arg) { } > > ~EDMemoryObject() { } > > uint64_t getBase() const { return 0x0; } > > - uint64_t getExtent() const { return (uint64_t)-1; } > > - int readByte(uint64_t address, uint8_t *ptr) const { > > + uint64_t getExtent() { return (uint64_t)-1; } > > + int readByte(uint64_t address, uint8_t *ptr) { > > if (!Callback) > > return -1; > > > > > > Modified: llvm/trunk/lib/Support/CMakeLists.txt > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Support/CMakeLists.txt (original) > > +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Feb 6 16:30:29 2012 > > @@ -16,6 +16,7 @@ > > ConstantRange.cpp > > CrashRecoveryContext.cpp > > DataExtractor.cpp > > + DataStream.cpp > > Debug.cpp > > DeltaAlgorithm.cpp > > DAGDeltaAlgorithm.cpp > > @@ -42,6 +43,7 @@ > > SmallVector.cpp > > SourceMgr.cpp > > Statistic.cpp > > + StreamableMemoryObject.cpp > > StringExtras.cpp > > StringMap.cpp > > StringPool.cpp > > > > Added: llvm/trunk/lib/Support/DataStream.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149918&view=auto > > > ============================================================================== > > --- llvm/trunk/lib/Support/DataStream.cpp (added) > > +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,96 @@ > > +//===--- llvm/Support/DataStream.cpp - Lazy streamed Data > ---===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > > +//===----------------------------------------------------------------------===// > > +// > > +// This file implements DataStreamer, which fetches bytes of Data from > > +// a stream source. It provides support for streaming (lazy reading) of > > +// bitcode. An example implementation of streaming from a file or stdin > > +// is included. > > +// > > > +//===----------------------------------------------------------------------===// > > + > > +#define DEBUG_TYPE "Data-stream" > > +#include "llvm/ADT/Statistic.h" > > +#include "llvm/Support/DataStream.h" > > +#include "llvm/Support/system_error.h" > > +#include > > +#include > > +#include > > +#if !defined(_MSC_VER) && !defined(__MINGW32__) > > +#include > > +#else > > +#include > > +#endif > > +#include > > +using namespace llvm; > > + > > +// Interface goals: > > +// * StreamableMemoryObject doesn't care about complexities like using > > +// threads/async callbacks to actually overlap download+compile > > +// * Don't want to duplicate Data in memory > > +// * Don't need to know total Data len in advance > > +// Non-goals: > > +// StreamableMemoryObject already has random access so this interface > only does > > +// in-order streaming (no arbitrary seeking, else we'd have to buffer > all the > > +// Data here in addition to MemoryObject). This also means that if we > want > > +// to be able to to free Data, BitstreamBytes/BitcodeReader will > implement it > > + > > +STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); > > + > > +namespace llvm { > > +DataStreamer::~DataStreamer() {} > > +} > > + > > +namespace { > > + > > +const static error_code success; > > + > > +// Very simple stream backed by a file. Mostly useful for stdin and > debugging; > > +// actual file access is probably still best done with mmap. > > +class DataFileStreamer : public DataStreamer { > > + int Fd; > > +public: > > + DataFileStreamer() : Fd(0) {} > > + virtual ~DataFileStreamer() { > > + close(Fd); > > + } > > + virtual size_t GetBytes(unsigned char *buf, size_t len) { > > + NumStreamFetches++; > > + return read(Fd, buf, len); > > + } > > + > > + error_code OpenFile(const std::string &Filename) { > > + int OpenFlags = O_RDONLY; > > +#ifdef O_BINARY > > + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. > > +#endif > > + if (Filename == "-") > > + Fd = 0; > > + else > > + Fd = ::open(Filename.c_str(), OpenFlags); > > + if (Fd == -1) return error_code(errno, posix_category()); > > + return success; > > + } > > +}; > > + > > +} > > + > > +namespace llvm { > > +DataStreamer *getDataFileStreamer(const std::string &Filename, > > + std::string *StrError) { > > + DataFileStreamer *s = new DataFileStreamer(); > > + error_code e = s->OpenFile(Filename); > > + if (e != success) { > > + *StrError = std::string("Could not open ") + Filename + ": " + > > + e.message() + "\n"; > > + return NULL; > > + } > > + return s; > > +} > > + > > +} > > > > Modified: llvm/trunk/lib/Support/MemoryObject.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryObject.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Support/MemoryObject.cpp (original) > > +++ llvm/trunk/lib/Support/MemoryObject.cpp Mon Feb 6 16:30:29 2012 > > @@ -16,7 +16,7 @@ > > int MemoryObject::readBytes(uint64_t address, > > uint64_t size, > > uint8_t* buf, > > - uint64_t* copied) const { > > + uint64_t* copied) { > > uint64_t current = address; > > uint64_t limit = getBase() + getExtent(); > > > > > > Added: llvm/trunk/lib/Support/StreamableMemoryObject.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149918&view=auto > > > ============================================================================== > > --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (added) > > +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb 6 > 16:30:29 2012 > > @@ -0,0 +1,137 @@ > > +//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ > -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > > +//===----------------------------------------------------------------------===// > > + > > +#include "llvm/Support/StreamableMemoryObject.h" > > +#include > > +#include > > + > > + > > +using namespace llvm; > > + > > +namespace { > > + > > +class RawMemoryObject : public StreamableMemoryObject { > > +public: > > + RawMemoryObject(const unsigned char *Start, const unsigned char *End) > : > > + FirstChar(Start), LastChar(End) { > > + assert(LastChar > FirstChar && "Invalid start/end range"); > > + } > > + > > + virtual uint64_t getBase() const { return 0; } > > + virtual uint64_t getExtent() { return LastChar - FirstChar; } > > + virtual int readByte(uint64_t address, uint8_t* ptr); > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied); > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size); > > + virtual bool isValidAddress(uint64_t address) {return > validAddress(address);} > > + virtual bool isObjectEnd(uint64_t address) {return > objectEnd(address);} > > + > > +private: > > + const uint8_t* const FirstChar; > > + const uint8_t* const LastChar; > > + > > + // These are implemented as inline functions here to avoid multiple > virtual > > + // calls per public function > > + bool validAddress(uint64_t address) { > > + return static_cast(address) < LastChar - FirstChar; > > + } > > + bool objectEnd(uint64_t address) { > > + return static_cast(address) == LastChar - FirstChar; > > + } > > + > > + RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT > > + void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT > > +}; > > + > > +int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > > + if (!validAddress(address)) return -1; > > + *ptr = *((uint8_t *)(uintptr_t)(address + FirstChar)); > > + return 0; > > +} > > + > > +int RawMemoryObject::readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) { > > + if (!validAddress(address) || !validAddress(address + size - 1)) > return -1; > > + memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); > > + if (copied) *copied = size; > > + return size; > > +} > > + > > +const uint8_t *RawMemoryObject::getPointer(uint64_t address, uint64_t > size) { > > + return FirstChar + address; > > +} > > +} // anonymous namespace > > + > > +namespace llvm { > > +// If the bitcode has a header, then its size is known, and we don't > have to > > +// block until we actually want to read it. > > +bool StreamingMemoryObject::isValidAddress(uint64_t address) { > > + if (ObjectSize && address < ObjectSize) return true; > > + return fetchToPos(address); > > +} > > + > > +bool StreamingMemoryObject::isObjectEnd(uint64_t address) { > > + if (ObjectSize) return address == ObjectSize; > > + fetchToPos(address); > > + return address == ObjectSize && address != 0; > > +} > > + > > +uint64_t StreamingMemoryObject::getExtent() { > > + if (ObjectSize) return ObjectSize; > > + size_t pos = BytesRead + kChunkSize; > > + // keep fetching until we run out of bytes > > + while (fetchToPos(pos)) pos += kChunkSize; > > + return ObjectSize; > > +} > > + > > +int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > > + if (!fetchToPos(address)) return -1; > > + *ptr = Bytes[address + BytesSkipped]; > > + return 0; > > +} > > + > > +int StreamingMemoryObject::readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) { > > + if (!fetchToPos(address + size - 1)) return -1; > > + memcpy(buf, &Bytes[address + BytesSkipped], size); > > + if (copied) *copied = size; > > + return 0; > > +} > > + > > +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { > > + if (BytesRead < s) return true; > > + BytesSkipped = s; > > + BytesRead -= s; > > + return false; > > +} > > + > > +void StreamingMemoryObject::setKnownObjectSize(size_t size) { > > + ObjectSize = size; > > + Bytes.reserve(size); > > +} > > + > > +StreamableMemoryObject *getNonStreamedMemoryObject( > > + const unsigned char *Start, const unsigned char *End) { > > + return new RawMemoryObject(Start, End); > > +} > > + > > +StreamableMemoryObject::~StreamableMemoryObject() { } > > + > > +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : > > + Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), > > + ObjectSize(0), EOFReached(false) { > > + BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); > > +} > > +} > > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original) > > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb > 6 16:30:29 2012 > > @@ -46,7 +46,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > @@ -71,7 +71,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > @@ -341,7 +341,7 @@ > > } > > > > DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, > > - const MemoryObject &Region, > > + MemoryObject &Region, > > uint64_t Address, > > raw_ostream &os, > > raw_ostream &cs) const { > > @@ -691,7 +691,7 @@ > > } > > > > DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t > &Size, > > - const MemoryObject > &Region, > > + MemoryObject &Region, > > uint64_t Address, > > raw_ostream &os, > > raw_ostream &cs) const { > > > > Modified: > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > (original) > > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon > Feb 6 16:30:29 2012 > > @@ -502,7 +502,7 @@ > > > > MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst > &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const { > > > > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > (original) > > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h Mon > Feb 6 16:30:29 2012 > > @@ -40,7 +40,7 @@ > > /// getInstruction - See MCDisassembler. > > MCDisassembler::DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original) > > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Feb > 6 16:30:29 2012 > > @@ -112,7 +112,7 @@ > > MCDisassembler::DecodeStatus > > X86GenericDisassembler::getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const { > > > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) > > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Mon Feb 6 > 16:30:29 2012 > > @@ -114,7 +114,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > > > Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) > > +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb 6 > 16:30:29 2012 > > @@ -483,13 +483,13 @@ > > if (MemBuf->getBufferSize() & 3) > > return Error("Bitcode stream should be a multiple of 4 bytes in > length"); > > > > - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); > > - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > > + const unsigned char *BufPtr = (unsigned char > *)MemBuf->getBufferStart(); > > + const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > > > > // If we have a wrapper header, parse it and ignore the non-bc file > contents. > > // The magic number is 0x0B17C0DE stored in little endian. > > if (isBitcodeWrapper(BufPtr, EndBufPtr)) > > - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) > > + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) > > return Error("Invalid bitcode wrapper header"); > > > > BitstreamReader StreamFile(BufPtr, EndBufPtr); > > > > Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) > > +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Feb 6 16:30:29 2012 > > @@ -24,6 +24,7 @@ > > #include "llvm/Analysis/DebugInfo.h" > > #include "llvm/Assembly/AssemblyAnnotationWriter.h" > > #include "llvm/Support/CommandLine.h" > > +#include "llvm/Support/DataStream.h" > > #include "llvm/Support/FormattedStream.h" > > #include "llvm/Support/ManagedStatic.h" > > #include "llvm/Support/MemoryBuffer.h" > > @@ -126,12 +127,19 @@ > > std::string ErrorMessage; > > std::auto_ptr M; > > > > - { > > - OwningPtr BufferPtr; > > - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, > BufferPtr)) > > - ErrorMessage = ec.message(); > > + // Use the bitcode streaming interface > > + DataStreamer *streamer = getDataFileStreamer(InputFilename, > &ErrorMessage); > > + if (streamer) { > > + std::string DisplayFilename; > > + if (InputFilename == "-") > > + DisplayFilename = ""; > > else > > - M.reset(ParseBitcodeFile(BufferPtr.get(), Context, > &ErrorMessage)); > > + DisplayFilename = InputFilename; > > + M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, > > + &ErrorMessage)); > > + if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { > > + M.reset(); > > + } > > } > > > > if (M.get() == 0) { > > @@ -183,4 +191,3 @@ > > > > return 0; > > } > > - > > > > Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) > > +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -42,9 +42,9 @@ > > VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} > > > > uint64_t getBase() const { return 0; } > > - uint64_t getExtent() const { return Bytes.size(); } > > + uint64_t getExtent() { return Bytes.size(); } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr >= getExtent()) > > return -1; > > *Byte = Bytes[Addr].first; > > > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.cpp?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/MCFunction.cpp (original) > > +++ llvm/trunk/tools/llvm-objdump/MCFunction.cpp Mon Feb 6 16:30:29 2012 > > @@ -28,7 +28,7 @@ > > > > MCFunction > > MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler > *DisAsm, > > - const MemoryObject &Region, uint64_t > Start, > > + MemoryObject &Region, uint64_t Start, > > uint64_t End, const MCInstrAnalysis > *Ana, > > raw_ostream &DebugOut, > > SmallVectorImpl &Calls) { > > > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/MCFunction.h (original) > > +++ llvm/trunk/tools/llvm-objdump/MCFunction.h Mon Feb 6 16:30:29 2012 > > @@ -79,7 +79,7 @@ > > // Create an MCFunction from a region of binary machine code. > > static MCFunction > > createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, > > - const MemoryObject &Region, uint64_t Start, > uint64_t End, > > + MemoryObject &Region, uint64_t Start, uint64_t > End, > > const MCInstrAnalysis *Ana, raw_ostream &DebugOut, > > SmallVectorImpl &Calls); > > > > > > Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=149918&r1=149917&r2=149918&view=diff > > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original) > > +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb 6 16:30:29 2012 > > @@ -31,9 +31,9 @@ > > StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} > > > > uint64_t getBase() const { return 0; } > > - uint64_t getExtent() const { return Bytes.size(); } > > + uint64_t getExtent() { return Bytes.size(); } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr >= getExtent()) > > return -1; > > *Byte = Bytes[Addr]; > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/f6e2ddb1/attachment-0001.html From dblaikie at gmail.com Tue Feb 7 13:36:02 2012 From: dblaikie at gmail.com (David Blaikie) Date: Tue, 07 Feb 2012 19:36:02 -0000 Subject: [llvm-commits] [llvm] r149999 - in /llvm/trunk: include/llvm/Support/CommandLine.h lib/Support/CommandLine.cpp Message-ID: <20120207193602.8E3422A6C12C@llvm.org> Author: dblaikie Date: Tue Feb 7 13:36:01 2012 New Revision: 149999 URL: http://llvm.org/viewvc/llvm-project?rev=149999&view=rev Log: Correct use of const in ParseCommandLineOptions Modified: llvm/trunk/include/llvm/Support/CommandLine.h llvm/trunk/lib/Support/CommandLine.cpp Modified: llvm/trunk/include/llvm/Support/CommandLine.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/CommandLine.h?rev=149999&r1=149998&r2=149999&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/CommandLine.h (original) +++ llvm/trunk/include/llvm/Support/CommandLine.h Tue Feb 7 13:36:01 2012 @@ -40,7 +40,7 @@ //===----------------------------------------------------------------------===// // ParseCommandLineOptions - Command line option processing entry point. // -void ParseCommandLineOptions(int argc, char **argv, +void ParseCommandLineOptions(int argc, const char * const *argv, const char *Overview = 0, bool ReadResponseFiles = false); Modified: llvm/trunk/lib/Support/CommandLine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CommandLine.cpp?rev=149999&r1=149998&r2=149999&view=diff ============================================================================== --- llvm/trunk/lib/Support/CommandLine.cpp (original) +++ llvm/trunk/lib/Support/CommandLine.cpp Tue Feb 7 13:36:01 2012 @@ -266,8 +266,8 @@ /// and a null value (StringRef()). The later is accepted for arguments that /// don't allow a value (-foo) the former is rejected (-foo=). static inline bool ProvideOption(Option *Handler, StringRef ArgName, - StringRef Value, int argc, char **argv, - int &i) { + StringRef Value, int argc, + const char *const *argv, int &i) { // Is this a multi-argument option? unsigned NumAdditionalVals = Handler->getNumAdditionalVals(); @@ -495,10 +495,10 @@ /// ExpandResponseFiles - Copy the contents of argv into newArgv, /// substituting the contents of the response files for the arguments /// of type @file. -static void ExpandResponseFiles(unsigned argc, char** argv, +static void ExpandResponseFiles(unsigned argc, const char*const* argv, std::vector& newArgv) { for (unsigned i = 1; i != argc; ++i) { - char *arg = argv[i]; + const char *arg = argv[i]; if (arg[0] == '@') { sys::PathWithStatus respFile(++arg); @@ -528,7 +528,7 @@ } } -void cl::ParseCommandLineOptions(int argc, char **argv, +void cl::ParseCommandLineOptions(int argc, const char * const *argv, const char *Overview, bool ReadResponseFiles) { // Process all registered options. SmallVector PositionalOpts; From rjmccall at apple.com Tue Feb 7 13:42:03 2012 From: rjmccall at apple.com (John McCall) Date: Tue, 07 Feb 2012 11:42:03 -0800 Subject: [llvm-commits] [llvm] r148553 - in /llvm/trunk: docs/LangRef.html include/llvm-c/Core.h include/llvm/Attributes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeReader.cpp lib/Bitcode/Writer/BitcodeWriter.cpp lib/CodeGen/Analysis.cpp lib/Transforms/InstCombine/InstCombineCalls.cpp lib/Transforms/Scalar/CodeGenPrepare.cpp lib/VMCore/Attributes.cpp lib/VMCore/Core.cpp lib/VMCore/Verifier.cpp utils/llvm.grm In-Reply-To: <20120120175618.E48FD2A6C12C@llvm.org> References: <20120120175618.E48FD2A6C12C@llvm.org> Message-ID: <2189DF12-2FEE-4F41-86A8-475CF105DC03@apple.com> On Jan 20, 2012, at 9:56 AM, Kostya Serebryany wrote: > Author: kcc > Date: Fri Jan 20 11:56:17 2012 > New Revision: 148553 > > URL: http://llvm.org/viewvc/llvm-project?rev=148553&view=rev > Log: > Extend Attributes to 64 bits > > Problem: LLVM needs more function attributes than currently available (32 bits). > One such proposed attribute is "address_safety", which shows that a function is being checked for address safety (by AddressSanitizer, SAFECode, etc). > > Solution: > - extend the Attributes from 32 bits to 64-bits > - wrap the object into a class so that unsigned is never erroneously used instead > - change "unsigned" to "Attributes" throughout the code, including one place in clang. > - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to support packing/unpacking. > - the class has "safe operator bool()" to support the common idiom: if (Attributes attr = getAttrs()) useAttrs(attr); > - The CTOR from uint64_t is marked explicit, so I had to add a few explicit CTOR calls > - Add the new attribute "address_safety". Doing it in the same commit to check that attributes beyond first 32 bits actually work. > - Some of the functions from the Attribute namespace are worth moving inside the class, but I'd prefer to have it as a separate commit. > > Tested: > "make check" on Linux (32-bit and 64-bit) and Mac (10.6) > built/run spec CPU 2006 on Linux with clang -O2. Using a class here is introducing global initializers into every translation unit that includes llvm/Attributes.h. Those initializers are optimized out at -O1 (by clang, at least), but it's still bad practice. If you remove all the constructors from the class, you can use list-initialization instead, which (in this case) is essentially guaranteed to not require a global initializer; the only other alternative (given MSVC's limitations) is to give up on type-safety and use a typedef for uint64_t, which I think is the easiest answer, if also the most dissatisfying. John. From greened at obbligato.org Tue Feb 7 13:57:28 2012 From: greened at obbligato.org (David A. Greene) Date: Tue, 7 Feb 2012 13:57:28 -0600 Subject: [llvm-commits] [PATCH 01/13] Add For Loop Structures In-Reply-To: <408C9E85-535E-4F73-B721-A681029F347E@2pi.dk> (Jakob Stoklund Olesen's message of "Tue, 7 Feb 2012 12:28:40 -0600") References: <87mx8uvcyw.fsf@smith.obbligato.org> <8C4644C6-E42C-498B-9634-E33EC1E04E5F@2pi.dk> <87ehu6tt1g.fsf@smith.obbligato.org> <408C9E85-535E-4F73-B721-A681029F347E@2pi.dk> Message-ID: <87aa4uto0n.fsf@smith.obbligato.org> Jakob Stoklund Olesen writes: >> Ah. I'm assuming I should submit the patch as review, not break >> it up. Is that right? > > Yes. I don't think it makes sense to review a series of commit-sized > changes. A single patch can be quite large as long as it is doing just > one thing, see for example Hal's vectorizer. Ok, makes sense. >> Ok. I thought zip was a no-go. I'm going to wait on it anyway while I >> work out how various things might work. It may or may not come back. > > Let's discuss the design before you put too much work into it. The > example you pasted looked like it would require a laundry list of > syntax and type system extensions. I don't want to do that for > something that probably won't be used much. Yep. > Back in October, we discussed something much simpler: "foreach x = > [?], y = [?] in ?". That's a fairly simple extension to your first > patch, and it doesn't require you to invent tuple types and generic > zip operators. I think that would be fine to add. Yes, I am leaning that way. Originally I thought zip would be better as it is more general and can be used anytime one wants a list of tuples. But I think it will really mainly be used for iteration and I like the above syntax better than having !zip() all over that obscures the values being iterated over. !zip() also has the complexity of potentially being an nary operator and that would require some work. So I'll do the foreach extension instead, once I come across a need. I have some ideas I want to pass by you and others but I'm still working out the details. We can always add zip later. Thanks! -Dave From kcc at google.com Tue Feb 7 14:12:46 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 12:12:46 -0800 Subject: [llvm-commits] [llvm] r148553 - in /llvm/trunk: docs/LangRef.html include/llvm-c/Core.h include/llvm/Attributes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeRead Message-ID: On Tue, Feb 7, 2012 at 11:42 AM, John McCall wrote: > On Jan 20, 2012, at 9:56 AM, Kostya Serebryany wrote: > > Author: kcc > > Date: Fri Jan 20 11:56:17 2012 > > New Revision: 148553 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=148553&view=rev > > Log: > > Extend Attributes to 64 bits > > > > Problem: LLVM needs more function attributes than currently available > (32 bits). > > One such proposed attribute is "address_safety", which shows that a > function is being checked for address safety (by AddressSanitizer, > SAFECode, etc). > > > > Solution: > > - extend the Attributes from 32 bits to 64-bits > > - wrap the object into a class so that unsigned is never erroneously > used instead > > - change "unsigned" to "Attributes" throughout the code, including one > place in clang. > > - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to > support packing/unpacking. > > - the class has "safe operator bool()" to support the common idiom: if > (Attributes attr = getAttrs()) useAttrs(attr); > > - The CTOR from uint64_t is marked explicit, so I had to add a few > explicit CTOR calls > > - Add the new attribute "address_safety". Doing it in the same commit to > check that attributes beyond first 32 bits actually work. > > - Some of the functions from the Attribute namespace are worth moving > inside the class, but I'd prefer to have it as a separate commit. > > > > Tested: > > "make check" on Linux (32-bit and 64-bit) and Mac (10.6) > > built/run spec CPU 2006 on Linux with clang -O2. > > Using a class here is introducing global initializers into every > translation unit that includes llvm/Attributes.h. Those initializers are > optimized out at -O1 (by clang, at least), but it's still bad practice. Why? This code looks clean and effective (with >=O1). > If you remove all the constructors from the class, you can use > list-initialization instead, which (in this case) is essentially guaranteed > to not require a global initializer; the only other alternative (given > MSVC's limitations) What are these limitations? We can probably come up with something like a proxy class to initialize the Attribute constans, not sure if it's worth doing so. What are your suggestions? --kcc > is to give up on type-safety and use a typedef for uint64_t, which I think > is the easiest answer, if also the most dissatisfying. > > John. > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/bd431dfc/attachment.html From peter at pcc.me.uk Tue Feb 7 14:16:23 2012 From: peter at pcc.me.uk (Peter Collingbourne) Date: Tue, 7 Feb 2012 20:16:23 +0000 Subject: [llvm-commits] [cfe-commits] Patch: Add get_global_id builtin/intrinsic In-Reply-To: <20120203222438.GB2310@L7-CNU1252LKR-172027226155.amd.com> References: <20120203211902.GC1710@L7-CNU1252LKR-172027226155.amd.com> <7DE70FDACDE4CD4887C4278C12A2E305081425@HASMSX104.ger.corp.intel.com> <20120203215531.GD1710@L7-CNU1252LKR-172027226155.amd.com> <7DE70FDACDE4CD4887C4278C12A2E3050814C5@HASMSX104.ger.corp.intel.com> <20120203222438.GB2310@L7-CNU1252LKR-172027226155.amd.com> Message-ID: <20120207201623.GA30525@pcc.me.uk> On Fri, Feb 03, 2012 at 05:24:38PM -0500, Tom Stellard wrote: > On Fri, Feb 03, 2012 at 10:07:03PM +0000, Rotem, Nadav wrote: > > Tom, > > > > Our OpenCL implementation of get_global_id is not target specific and we don't resolve it in the backend. I think that get_global_id should be implemented as a simple library call. However, this is something that needs to be discussed with Tanya Lattner, Peter Collingbourne, Anton Lokhmotov, etc. > > > > Nadav > > Nadav, > > Sorry, I guess I should be more clear. When I say target specific I'm > talking about GPU targets. The get_global_id() implementation > on the GPUs we've written a backend for (Evergreen, Northern Islands) > requires reading values from special registers that are preloaded by the > hardware. I'm guessing other GPUs do something similar, so I do think > it is something that would need to be resolved in the backend. Hi Tom, I disagree. There is no need to resolve these functions in the backend, as the register reads can simply be made part of the get_global_id implementation. The libclc OpenCL C standard library already targets NVIDIA GPUs, and it implements get_global_id and the other work-item functions in exactly this way: http://git.pcc.me.uk/?p=~peter/libclc.git;a=blob;f=ptx-nvidiacl/include/clc/workitem/get_global_id.h Your way, we leak language-specific details into the backends, details which can be dealt with by the frontend and standard library, so that the backends can be kept language independent. Also, there is no one way of implementing functions like get_global_id on (say) PTX. One thing that is missing from the get_global_id implementation in libclc is global offsets. The precise details of how those offsets are passed to the kernel have varied over time (for example, at one point a global array was used, and now special registers are used). If we encode these sorts of details in the backend we reduce overall flexibility and deny optimisation opportunities to the optimisers. For example, say the kernel computes: get_global_id(0) - get_global_offset(0) On PTX the optimisers should be able to eliminate the global offset access altogether, but they might not be able to if get_global_id and get_global_offset are opaque intrinsic calls. Thanks, -- Peter From dmalyshev at accesssoftek.com Tue Feb 7 14:24:25 2012 From: dmalyshev at accesssoftek.com (Danil Malyshev) Date: Tue, 7 Feb 2012 12:24:25 -0800 Subject: [llvm-commits] RuntimeDyLd new features Message-ID: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> Hello everyone, Please review the RuntimeDyLd-01.patch. This patch makes the following changes: 1. The main works will made in the RuntimeDyLdImpl with uses the ObjectFile class. RuntimeDyLdMachO and RuntimeDyLdELF now only parses relocations and resolve it. This is allows to make improvements of the RuntimeDyLd more easily. In addition the support for COFF can be easily added. 2. Added ARM relocations to RuntimeDyLdELF. 3. Added support for stub functions for the ARM, allowing to do a long branch. 4. Added support for external functions that are not loaded from the object files, but can be loaded from external libraries. Now MCJIT can correctly execute the code containing the printf, putc, and etc. 5. The sections emitted instead functions, thanks Jim Grosbach. MemoryManager.startFunctionBody() and MemoryManager.endFunctionBody() have been removed. 6. MCJITMemoryManager.allocateDataSection() and MCJITMemoryManager. allocateCodeSection() used JMM->allocateSpace() instead of JMM->allocateCodeSection() and JMM->allocateDataSection(), because I got an error: "Cannot allocate an allocated block!" with object file contains more than one code or data sections. 7. Fixed ELF::R_X86_64_PC32 relocation for the case when RealOffset is negative value. 8. Added new testing folder: ExecutionEngine/MCJIT because mcjit tests can be running only for x86 and arm and it's can be filtered with dg.exp. Tested in Ubuntu x86_64, Ubuntu armv7 and MacOS 64. Thank you, Danil -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/b30e5c41/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: RuntimeDyLd-01.patch Type: application/octet-stream Size: 85193 bytes Desc: RuntimeDyLd-01.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/b30e5c41/attachment-0001.obj From grosbach at apple.com Tue Feb 7 14:30:51 2012 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 07 Feb 2012 12:30:51 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ In-Reply-To: References: Message-ID: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> On Feb 7, 2012, at 11:29 AM, Derek Schuff wrote: > Hi Jim, > Originally the patch was written such that the bitcode reader used a new container class to hold the bitcode, and get pieces of it using methods like getByte, getWord, etc. Chris asked me to use MemoryObject instead, which has a similar interface (readBytes et al), except that those methods are const. They definitely can't be const when each call can result in fetching more bytes from the stream, so all the MC constness changes are basically fallout from MemoryBuffer's readBytes method no longer being const. I'm not averse to going back to the other way, but I'd like to have some agreement from the relevant stakeholders as to the right approach before I put more work into it. I don't know the history of what Chris asked, so I can't effectively comment on that. This patch, however, removes our ability to express the existence of a MemoryObject that is immutable. That's not a good thing and I'd like to avoid it. Why can't a const StreamableMemoryObject read in more information to satisfy a request? As I understand it, 'const' there is saying that the data won't be modified and not necessarily anything about what actions need to be taken to read it. >From an implementation detail point of view, consider the following contrived example: $ cat foo.cpp #include #include class myClass { unsigned *storage; public: myClass(unsigned *buffer) { storage = buffer; } void write(unsigned val) const { *storage = val; } unsigned read() const { return *storage; } void set(unsigned *buffer) { storage = buffer; } }; void foo(const myClass *p) { p->write(5); std::cout << p->read() << std::endl; p->write(4); std::cout << p->read() << std::endl; // Can't do this due to 'const' // error: member function 'set' not viable: 'this' argument has type 'const myClass', but function is not marked const //unsigned newbuf; //p->set(&newbuf); } int main(int argc, char *argv[]) { unsigned val; myClass X(&val); foo(&X); } $ clang++ foo.cpp -o foo $ ./foo 5 4 In this example, the 'const' on our instance of myClass indicates that the underlying storage can't be changed, but says nothing about what's actually in that storage, as indicated by the fact that our write() method is const qualified. If we wanted the interface to have the data itself also be const, then we would just remove the const from the write() declaration. Yes, this is a bit funky and plays some games w/ 'const', but it allows us to express our intent with the interfaces. Copious commenting is recommended. :) -Jim > -Derek > > > On Tue, Feb 7, 2012 at 11:15 AM, Jim Grosbach wrote: > Hi Derek, > > I don't follow why this needs to change the MC disassemblers. Those have nothing to do with bitcode. Can you elaborate? I'm uncomfortable with removing the const'ness of the input to those methods, for example. > > -Jim > > On Feb 6, 2012, at 2:30 PM, Derek Schuff wrote: > > > Author: dschuff > > Date: Mon Feb 6 16:30:29 2012 > > New Revision: 149918 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=149918&view=rev > > Log: > > Enable streaming of bitcode > > > > This CL delays reading of function bodies from initial parse until > > materialization, allowing overlap of compilation with bitcode download. > > > > > > Added: > > llvm/trunk/include/llvm/Support/DataStream.h > > llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > > llvm/trunk/lib/Support/DataStream.cpp > > llvm/trunk/lib/Support/StreamableMemoryObject.cpp > > Modified: > > llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > > llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > > llvm/trunk/include/llvm/MC/MCDisassembler.h > > llvm/trunk/include/llvm/Support/MemoryObject.h > > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > > llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > > llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > > llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > > llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > > llvm/trunk/lib/Support/CMakeLists.txt > > llvm/trunk/lib/Support/MemoryObject.cpp > > llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > > llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > > llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > > llvm/trunk/tools/llvm-dis/llvm-dis.cpp > > llvm/trunk/tools/llvm-mc/Disassembler.cpp > > llvm/trunk/tools/llvm-objdump/MCFunction.cpp > > llvm/trunk/tools/llvm-objdump/MCFunction.h > > llvm/trunk/tools/llvm-objdump/llvm-objdump.h > > > > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) > > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb 6 16:30:29 2012 > > @@ -15,10 +15,12 @@ > > #ifndef BITSTREAM_READER_H > > #define BITSTREAM_READER_H > > > > +#include "llvm/ADT/OwningPtr.h" > > #include "llvm/Bitcode/BitCodes.h" > > #include > > #include > > #include > > +#include "llvm/Support/StreamableMemoryObject.h" > > > > namespace llvm { > > > > @@ -36,9 +38,7 @@ > > std::vector > RecordNames; > > }; > > private: > > - /// FirstChar/LastChar - This remembers the first and last bytes of the > > - /// stream. > > - const unsigned char *FirstChar, *LastChar; > > + OwningPtr BitcodeBytes; > > > > std::vector BlockInfoRecords; > > > > @@ -47,10 +47,10 @@ > > /// uses this. > > bool IgnoreBlockInfoNames; > > > > - BitstreamReader(const BitstreamReader&); // NOT IMPLEMENTED > > - void operator=(const BitstreamReader&); // NOT IMPLEMENTED > > + BitstreamReader(const BitstreamReader&); // DO NOT IMPLEMENT > > + void operator=(const BitstreamReader&); // DO NOT IMPLEMENT > > public: > > - BitstreamReader() : FirstChar(0), LastChar(0), IgnoreBlockInfoNames(true) { > > + BitstreamReader() : IgnoreBlockInfoNames(true) { > > } > > > > BitstreamReader(const unsigned char *Start, const unsigned char *End) { > > @@ -58,12 +58,17 @@ > > init(Start, End); > > } > > > > + BitstreamReader(StreamableMemoryObject *bytes) { > > + BitcodeBytes.reset(bytes); > > + } > > + > > void init(const unsigned char *Start, const unsigned char *End) { > > - FirstChar = Start; > > - LastChar = End; > > assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes"); > > + BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); > > } > > > > + StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } > > + > > ~BitstreamReader() { > > // Free the BlockInfoRecords. > > while (!BlockInfoRecords.empty()) { > > @@ -75,9 +80,6 @@ > > BlockInfoRecords.pop_back(); > > } > > } > > - > > - const unsigned char *getFirstChar() const { return FirstChar; } > > - const unsigned char *getLastChar() const { return LastChar; } > > > > /// CollectBlockInfoNames - This is called by clients that want block/record > > /// name information. > > @@ -122,7 +124,7 @@ > > class BitstreamCursor { > > friend class Deserializer; > > BitstreamReader *BitStream; > > - const unsigned char *NextChar; > > + size_t NextChar; > > > > /// CurWord - This is the current data we have pulled from the stream but have > > /// not returned to the client. > > @@ -156,8 +158,7 @@ > > } > > > > explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { > > - NextChar = R.getFirstChar(); > > - assert(NextChar && "Bitstream not initialized yet"); > > + NextChar = 0; > > CurWord = 0; > > BitsInCurWord = 0; > > CurCodeSize = 2; > > @@ -167,8 +168,7 @@ > > freeState(); > > > > BitStream = &R; > > - NextChar = R.getFirstChar(); > > - assert(NextChar && "Bitstream not initialized yet"); > > + NextChar = 0; > > CurWord = 0; > > BitsInCurWord = 0; > > CurCodeSize = 2; > > @@ -225,13 +225,38 @@ > > /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #. > > unsigned GetAbbrevIDWidth() const { return CurCodeSize; } > > > > - bool AtEndOfStream() const { > > - return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; > > + bool isEndPos(size_t pos) { > > + return BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos)); > > + } > > + > > + bool canSkipToPos(size_t pos) const { > > + // pos can be skipped to if it is a valid address or one byte past the end. > > + return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( > > + static_cast(pos - 1)); > > + } > > + > > + unsigned char getByte(size_t pos) { > > + uint8_t byte = -1; > > + BitStream->getBitcodeBytes().readByte(pos, &byte); > > + return byte; > > + } > > + > > + uint32_t getWord(size_t pos) { > > + uint32_t word = -1; > > + BitStream->getBitcodeBytes().readBytes(pos, > > + sizeof(word), > > + reinterpret_cast(&word), > > + NULL); > > + return word; > > + } > > + > > + bool AtEndOfStream() { > > + return isEndPos(NextChar) && BitsInCurWord == 0; > > } > > > > /// GetCurrentBitNo - Return the bit # of the bit we are reading. > > uint64_t GetCurrentBitNo() const { > > - return (NextChar-BitStream->getFirstChar())*CHAR_BIT - BitsInCurWord; > > + return NextChar*CHAR_BIT - BitsInCurWord; > > } > > > > BitstreamReader *getBitStreamReader() { > > @@ -246,12 +271,10 @@ > > void JumpToBit(uint64_t BitNo) { > > uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; > > uintptr_t WordBitNo = uintptr_t(BitNo) & 31; > > - assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- > > - BitStream->getFirstChar()) && > > - "Invalid location"); > > + assert(canSkipToPos(ByteNo) && "Invalid location"); > > > > // Move the cursor to the right word. > > - NextChar = BitStream->getFirstChar()+ByteNo; > > + NextChar = ByteNo; > > BitsInCurWord = 0; > > CurWord = 0; > > > > @@ -272,7 +295,7 @@ > > } > > > > // If we run out of data, stop at the end of the stream. > > - if (NextChar == BitStream->getLastChar()) { > > + if (isEndPos(NextChar)) { > > CurWord = 0; > > BitsInCurWord = 0; > > return 0; > > @@ -281,8 +304,7 @@ > > unsigned R = CurWord; > > > > // Read the next word from the stream. > > - CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) | > > - (NextChar[2] << 16) | (NextChar[3] << 24); > > + CurWord = getWord(NextChar); > > NextChar += 4; > > > > // Extract NumBits-BitsInCurWord from what we just read. > > @@ -376,9 +398,8 @@ > > > > // Check that the block wasn't partially defined, and that the offset isn't > > // bogus. > > - const unsigned char *const SkipTo = NextChar + NumWords*4; > > - if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || > > - SkipTo < BitStream->getFirstChar()) > > + size_t SkipTo = NextChar + NumWords*4; > > + if (AtEndOfStream() || !canSkipToPos(SkipTo)) > > return true; > > > > NextChar = SkipTo; > > @@ -409,8 +430,7 @@ > > if (NumWordsP) *NumWordsP = NumWords; > > > > // Validate that this block is sane. > > - if (CurCodeSize == 0 || AtEndOfStream() || > > - NextChar+NumWords*4 > BitStream->getLastChar()) > > + if (CurCodeSize == 0 || AtEndOfStream()) > > return true; > > > > return false; > > @@ -512,24 +532,25 @@ > > SkipToWord(); // 32-bit alignment > > > > // Figure out where the end of this blob will be including tail padding. > > - const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); > > + size_t NewEnd = NextChar+((NumElts+3)&~3); > > > > // If this would read off the end of the bitcode file, just set the > > // record to empty and return. > > - if (NewEnd > BitStream->getLastChar()) { > > + if (!canSkipToPos(NewEnd)) { > > Vals.append(NumElts, 0); > > - NextChar = BitStream->getLastChar(); > > + NextChar = BitStream->getBitcodeBytes().getExtent(); > > break; > > } > > > > // Otherwise, read the number of bytes. If we can return a reference to > > // the data, do so to avoid copying it. > > if (BlobStart) { > > - *BlobStart = (const char*)NextChar; > > + *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer( > > + NextChar, NumElts); > > *BlobLen = NumElts; > > } else { > > for (; NumElts; ++NextChar, --NumElts) > > - Vals.push_back(*NextChar); > > + Vals.push_back(getByte(NextChar)); > > } > > // Skip over tail padding. > > NextChar = NewEnd; > > > > Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) > > +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Feb 6 16:30:29 2012 > > @@ -17,35 +17,45 @@ > > #include > > > > namespace llvm { > > - class Module; > > - class MemoryBuffer; > > - class ModulePass; > > class BitstreamWriter; > > + class MemoryBuffer; > > + class DataStreamer; > > class LLVMContext; > > + class Module; > > + class ModulePass; > > class raw_ostream; > > - > > + > > /// getLazyBitcodeModule - Read the header of the specified bitcode buffer > > /// and prepare for lazy deserialization of function bodies. If successful, > > /// this takes ownership of 'buffer' and returns a non-null pointer. On > > /// error, this returns null, *does not* take ownership of Buffer, and fills > > /// in *ErrMsg with an error description if ErrMsg is non-null. > > Module *getLazyBitcodeModule(MemoryBuffer *Buffer, > > - LLVMContext& Context, > > + LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > + /// getStreamedBitcodeModule - Read the header of the specified stream > > + /// and prepare for lazy deserialization and streaming of function bodies. > > + /// On error, this returns null, and fills in *ErrMsg with an error > > + /// description if ErrMsg is non-null. > > + Module *getStreamedBitcodeModule(const std::string &name, > > + DataStreamer *streamer, > > + LLVMContext &Context, > > + std::string *ErrMsg = 0); > > + > > /// getBitcodeTargetTriple - Read the header of the specified bitcode > > /// buffer and extract just the triple information. If successful, > > /// this returns a string and *does not* take ownership > > /// of 'buffer'. On error, this returns "", and fills in *ErrMsg > > /// if ErrMsg is non-null. > > std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, > > - LLVMContext& Context, > > + LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > /// ParseBitcodeFile - Read the specified bitcode file, returning the module. > > /// If an error occurs, this returns null and fills in *ErrMsg if it is > > /// non-null. This method *never* takes ownership of Buffer. > > - Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, > > + Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context, > > std::string *ErrMsg = 0); > > > > /// WriteBitcodeToFile - Write the specified module to the specified > > @@ -60,8 +70,8 @@ > > /// createBitcodeWriterPass - Create and return a pass that writes the module > > /// to the specified ostream. > > ModulePass *createBitcodeWriterPass(raw_ostream &Str); > > - > > - > > + > > + > > /// isBitcodeWrapper - Return true if the given bytes are the magic bytes > > /// for an LLVM IR bitcode wrapper. > > /// > > @@ -109,21 +119,24 @@ > > /// uint32_t BitcodeSize; // Size of traditional bitcode file. > > /// ... potentially other gunk ... > > /// }; > > - /// > > + /// > > /// This function is called when we find a file with a matching magic number. > > /// In this case, skip down to the subsection of the file that is actually a > > /// BC file. > > - static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr, > > - unsigned char *&BufEnd) { > > + /// If 'VerifyBufferSize' is true, check that the buffer is large enough to > > + /// contain the whole bitcode file. > > + static inline bool SkipBitcodeWrapperHeader(const unsigned char *&BufPtr, > > + const unsigned char *&BufEnd, > > + bool VerifyBufferSize) { > > enum { > > KnownHeaderSize = 4*4, // Size of header we read. > > OffsetField = 2*4, // Offset in bytes to Offset field. > > SizeField = 3*4 // Offset in bytes to Size field. > > }; > > - > > + > > // Must contain the header! > > if (BufEnd-BufPtr < KnownHeaderSize) return true; > > - > > + > > unsigned Offset = ( BufPtr[OffsetField ] | > > (BufPtr[OffsetField+1] << 8) | > > (BufPtr[OffsetField+2] << 16) | > > @@ -132,9 +145,9 @@ > > (BufPtr[SizeField +1] << 8) | > > (BufPtr[SizeField +2] << 16) | > > (BufPtr[SizeField +3] << 24)); > > - > > + > > // Verify that Offset+Size fits in the file. > > - if (Offset+Size > unsigned(BufEnd-BufPtr)) > > + if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) > > return true; > > BufPtr += Offset; > > BufEnd = BufPtr+Size; > > > > Modified: llvm/trunk/include/llvm/MC/MCDisassembler.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/include/llvm/MC/MCDisassembler.h (original) > > +++ llvm/trunk/include/llvm/MC/MCDisassembler.h Mon Feb 6 16:30:29 2012 > > @@ -79,7 +79,7 @@ > > /// MCDisassembler::Fail if the instruction was invalid. > > virtual DecodeStatus getInstruction(MCInst& instr, > > uint64_t& size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const = 0; > > > > Added: llvm/trunk/include/llvm/Support/DataStream.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149918&view=auto > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/DataStream.h (added) > > +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,38 @@ > > +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > +//===----------------------------------------------------------------------===// > > +// > > +// This header defines DataStreamer, which fetches bytes of data from > > +// a stream source. It provides support for streaming (lazy reading) of > > +// data, e.g. bitcode > > +// > > +//===----------------------------------------------------------------------===// > > + > > + > > +#ifndef LLVM_SUPPORT_DATASTREAM_H_ > > +#define LLVM_SUPPORT_DATASTREAM_H_ > > + > > +#include > > + > > +namespace llvm { > > + > > +class DataStreamer { > > +public: > > + /// Fetch bytes [start-end) from the stream, and write them to the > > + /// buffer pointed to by buf. Returns the number of bytes actually written. > > + virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; > > + > > + virtual ~DataStreamer(); > > +}; > > + > > +DataStreamer *getDataFileStreamer(const std::string &Filename, > > + std::string *Err); > > + > > +} > > + > > +#endif // LLVM_SUPPORT_DATASTREAM_H_ > > > > Modified: llvm/trunk/include/llvm/Support/MemoryObject.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryObject.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/MemoryObject.h (original) > > +++ llvm/trunk/include/llvm/Support/MemoryObject.h Mon Feb 6 16:30:29 2012 > > @@ -34,7 +34,7 @@ > > /// is getBase() + getExtent() - 1). > > /// > > /// @result - The size of the region. > > - virtual uint64_t getExtent() const = 0; > > + virtual uint64_t getExtent() = 0; > > > > /// readByte - Tries to read a single byte from the region. > > /// > > @@ -42,7 +42,7 @@ > > /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. > > /// @result - 0 if successful; -1 if not. Failure may be due to a > > /// bounds violation or an implementation-specific error. > > - virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; > > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > > > > /// readBytes - Tries to read a contiguous range of bytes from the > > /// region, up to the end of the region. > > @@ -61,7 +61,7 @@ > > virtual int readBytes(uint64_t address, > > uint64_t size, > > uint8_t* buf, > > - uint64_t* copied) const; > > + uint64_t* copied); > > }; > > > > } > > > > Added: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149918&view=auto > > ============================================================================== > > --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (added) > > +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,181 @@ > > +//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > +//===----------------------------------------------------------------------===// > > + > > + > > +#ifndef STREAMABLEMEMORYOBJECT_H_ > > +#define STREAMABLEMEMORYOBJECT_H_ > > + > > +#include "llvm/ADT/OwningPtr.h" > > +#include "llvm/Support/MemoryObject.h" > > +#include "llvm/Support/DataStream.h" > > +#include > > + > > +namespace llvm { > > + > > +/// StreamableMemoryObject - Interface to data which might be streamed. > > +/// Streamability has 2 important implications/restrictions. First, the data > > +/// might not yet exist in memory when the request is made. This just means > > +/// that readByte/readBytes might have to block or do some work to get it. > > +/// More significantly, the exact size of the object might not be known until > > +/// it has all been fetched. This means that to return the right result, > > +/// getExtent must also wait for all the data to arrive; therefore it should > > +/// not be called on objects which are actually streamed (this would defeat > > +/// the purpose of streaming). Instead, isValidAddress and isObjectEnd can be > > +/// used to test addresses without knowing the exact size of the stream. > > +/// Finally, getPointer can be used instead of readBytes to avoid extra copying. > > +class StreamableMemoryObject : public MemoryObject { > > + public: > > + /// Destructor - Override as necessary. > > + virtual ~StreamableMemoryObject(); > > + > > + /// getBase - Returns the lowest valid address in the region. > > + /// > > + /// @result - The lowest valid address. > > + virtual uint64_t getBase() const = 0; > > + > > + /// getExtent - Returns the size of the region in bytes. (The region is > > + /// contiguous, so the highest valid address of the region > > + /// is getBase() + getExtent() - 1). > > + /// May block until all bytes in the stream have been read > > + /// > > + /// @result - The size of the region. > > + virtual uint64_t getExtent() = 0; > > + > > + /// readByte - Tries to read a single byte from the region. > > + /// May block until (address - base) bytes have been read > > + /// @param address - The address of the byte, in the same space as getBase(). > > + /// @param ptr - A pointer to a byte to be filled in. Must be non-NULL. > > + /// @result - 0 if successful; -1 if not. Failure may be due to a > > + /// bounds violation or an implementation-specific error. > > + virtual int readByte(uint64_t address, uint8_t* ptr) = 0; > > + > > + /// readBytes - Tries to read a contiguous range of bytes from the > > + /// region, up to the end of the region. > > + /// May block until (address - base + size) bytes have > > + /// been read. Additionally, StreamableMemoryObjects will > > + /// not do partial reads - if size bytes cannot be read, > > + /// readBytes will fail. > > + /// > > + /// @param address - The address of the first byte, in the same space as > > + /// getBase(). > > + /// @param size - The maximum number of bytes to copy. > > + /// @param buf - A pointer to a buffer to be filled in. Must be non-NULL > > + /// and large enough to hold size bytes. > > + /// @param copied - A pointer to a nunber that is filled in with the number > > + /// of bytes actually read. May be NULL. > > + /// @result - 0 if successful; -1 if not. Failure may be due to a > > + /// bounds violation or an implementation-specific error. > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) = 0; > > + > > + /// getPointer - Ensures that the requested data is in memory, and returns > > + /// A pointer to it. More efficient than using readBytes if the > > + /// data is already in memory. > > + /// May block until (address - base + size) bytes have been read > > + /// @param address - address of the byte, in the same space as getBase() > > + /// @param size - amount of data that must be available on return > > + /// @result - valid pointer to the requested data > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) = 0; > > + > > + /// isValidAddress - Returns true if the address is within the object > > + /// (i.e. between base and base + extent - 1 inclusive) > > + /// May block until (address - base) bytes have been read > > + /// @param address - address of the byte, in the same space as getBase() > > + /// @result - true if the address may be read with readByte() > > + virtual bool isValidAddress(uint64_t address) = 0; > > + > > + /// isObjectEnd - Returns true if the address is one past the end of the > > + /// object (i.e. if it is equal to base + extent) > > + /// May block until (address - base) bytes have been read > > + /// @param address - address of the byte, in the same space as getBase() > > + /// @result - true if the address is equal to base + extent > > + virtual bool isObjectEnd(uint64_t address) = 0; > > +}; > > + > > +/// StreamingMemoryObject - interface to data which is actually streamed from > > +/// a DataStreamer. In addition to inherited members, it has the > > +/// dropLeadingBytes and setKnownObjectSize methods which are not applicable > > +/// to non-streamed objects. > > +class StreamingMemoryObject : public StreamableMemoryObject { > > +public: > > + StreamingMemoryObject(DataStreamer *streamer); > > + virtual uint64_t getBase() const { return 0; } > > + virtual uint64_t getExtent(); > > + virtual int readByte(uint64_t address, uint8_t* ptr); > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied); > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size) { > > + // This could be fixed by ensuring the bytes are fetched and making a copy, > > + // requiring that the bitcode size be known, or otherwise ensuring that > > + // the memory doesn't go away/get reallocated, but it's > > + // not currently necessary. Users that need the pointer don't stream. > > + assert(0 && "getPointer in streaming memory objects not allowed"); > > + return NULL; > > + } > > + virtual bool isValidAddress(uint64_t address); > > + virtual bool isObjectEnd(uint64_t address); > > + > > + /// Drop s bytes from the front of the stream, pushing the positions of the > > + /// remaining bytes down by s. This is used to skip past the bitcode header, > > + /// since we don't know a priori if it's present, and we can't put bytes > > + /// back into the stream once we've read them. > > + bool dropLeadingBytes(size_t s); > > + > > + /// If the data object size is known in advance, many of the operations can > > + /// be made more efficient, so this method should be called before reading > > + /// starts (although it can be called anytime). > > + void setKnownObjectSize(size_t size); > > + > > +private: > > + const static uint32_t kChunkSize = 4096 * 4; > > + std::vector Bytes; > > + OwningPtr Streamer; > > + size_t BytesRead; // Bytes read from stream > > + size_t BytesSkipped;// Bytes skipped at start of stream (e.g. wrapper/header) > > + size_t ObjectSize; // 0 if unknown, set if wrapper was seen or EOF reached > > + bool EOFReached; > > + > > + // Fetch enough bytes such that Pos can be read or EOF is reached > > + // (i.e. BytesRead > Pos). Return true if Pos can be read. > > + // Unlike most of the functions in BitcodeReader, returns true on success. > > + // Most of the requests will be small, but we fetch at kChunkSize bytes > > + // at a time to avoid making too many potentially expensive GetBytes calls > > + bool fetchToPos(size_t Pos) { > > + if (EOFReached) return Pos < ObjectSize; > > + while (Pos >= BytesRead) { > > + Bytes.resize(BytesRead + kChunkSize); > > + size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + BytesSkipped], > > + kChunkSize); > > + BytesRead += bytes; > > + if (bytes < kChunkSize) { > > + if (ObjectSize && BytesRead < Pos) > > + assert(0 && "Unexpected short read fetching bitcode"); > > + if (BytesRead <= Pos) { // reached EOF/ran out of bytes > > + ObjectSize = BytesRead; > > + EOFReached = true; > > + return false; > > + } > > + } > > + } > > + return true; > > + } > > + > > + StreamingMemoryObject(const StreamingMemoryObject&); // DO NOT IMPLEMENT > > + void operator=(const StreamingMemoryObject&); // DO NOT IMPLEMENT > > +}; > > + > > +StreamableMemoryObject *getNonStreamedMemoryObject( > > + const unsigned char *Start, const unsigned char *End); > > + > > +} > > +#endif // STREAMABLEMEMORYOBJECT_H_ > > > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) > > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb 6 16:30:29 2012 > > @@ -22,6 +22,7 @@ > > #include "llvm/AutoUpgrade.h" > > #include "llvm/ADT/SmallString.h" > > #include "llvm/ADT/SmallVector.h" > > +#include "llvm/Support/DataStream.h" > > #include "llvm/Support/MathExtras.h" > > #include "llvm/Support/MemoryBuffer.h" > > #include "llvm/OperandTraits.h" > > @@ -1409,8 +1410,36 @@ > > return false; > > } > > > > -bool BitcodeReader::ParseModule() { > > - if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > > +bool BitcodeReader::GlobalCleanup() { > > + // Patch the initializers for globals and aliases up. > > + ResolveGlobalAndAliasInits(); > > + if (!GlobalInits.empty() || !AliasInits.empty()) > > + return Error("Malformed global initializer set"); > > + > > + // Look for intrinsic functions which need to be upgraded at some point > > + for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); > > + FI != FE; ++FI) { > > + Function *NewFn; > > + if (UpgradeIntrinsicFunction(FI, NewFn)) > > + UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > > + } > > + > > + // Look for global variables which need to be renamed. > > + for (Module::global_iterator > > + GI = TheModule->global_begin(), GE = TheModule->global_end(); > > + GI != GE; ++GI) > > + UpgradeGlobalVariable(GI); > > + // Force deallocation of memory for these vectors to favor the client that > > + // want lazy deserialization. > > + std::vector >().swap(GlobalInits); > > + std::vector >().swap(AliasInits); > > + return false; > > +} > > + > > +bool BitcodeReader::ParseModule(bool Resume) { > > + if (Resume) > > + Stream.JumpToBit(NextUnreadBit); > > + else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) > > return Error("Malformed block record"); > > > > SmallVector Record; > > @@ -1424,33 +1453,7 @@ > > if (Stream.ReadBlockEnd()) > > return Error("Error at end of module block"); > > > > - // Patch the initializers for globals and aliases up. > > - ResolveGlobalAndAliasInits(); > > - if (!GlobalInits.empty() || !AliasInits.empty()) > > - return Error("Malformed global initializer set"); > > - if (!FunctionsWithBodies.empty()) > > - return Error("Too few function bodies found"); > > - > > - // Look for intrinsic functions which need to be upgraded at some point > > - for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); > > - FI != FE; ++FI) { > > - Function* NewFn; > > - if (UpgradeIntrinsicFunction(FI, NewFn)) > > - UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); > > - } > > - > > - // Look for global variables which need to be renamed. > > - for (Module::global_iterator > > - GI = TheModule->global_begin(), GE = TheModule->global_end(); > > - GI != GE; ++GI) > > - UpgradeGlobalVariable(GI); > > - > > - // Force deallocation of memory for these vectors to favor the client that > > - // want lazy deserialization. > > - std::vector >().swap(GlobalInits); > > - std::vector >().swap(AliasInits); > > - std::vector().swap(FunctionsWithBodies); > > - return false; > > + return GlobalCleanup(); > > } > > > > if (Code == bitc::ENTER_SUBBLOCK) { > > @@ -1474,6 +1477,7 @@ > > case bitc::VALUE_SYMTAB_BLOCK_ID: > > if (ParseValueSymbolTable()) > > return true; > > + SeenValueSymbolTable = true; > > break; > > case bitc::CONSTANTS_BLOCK_ID: > > if (ParseConstants() || ResolveGlobalAndAliasInits()) > > @@ -1486,13 +1490,25 @@ > > case bitc::FUNCTION_BLOCK_ID: > > // If this is the first function body we've seen, reverse the > > // FunctionsWithBodies list. > > - if (!HasReversedFunctionsWithBodies) { > > + if (!SeenFirstFunctionBody) { > > std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); > > - HasReversedFunctionsWithBodies = true; > > + if (GlobalCleanup()) > > + return true; > > + SeenFirstFunctionBody = true; > > } > > > > if (RememberAndSkipFunctionBody()) > > return true; > > + // For streaming bitcode, suspend parsing when we reach the function > > + // bodies. Subsequent materialization calls will resume it when > > + // necessary. For streaming, the function bodies must be at the end of > > + // the bitcode. If the bitcode file is old, the symbol table will be > > + // at the end instead and will not have been seen yet. In this case, > > + // just finish the parse now. > > + if (LazyStreamer && SeenValueSymbolTable) { > > + NextUnreadBit = Stream.GetCurrentBitNo(); > > + return false; > > + } > > break; > > case bitc::USELIST_BLOCK_ID: > > if (ParseUseLists()) > > @@ -1651,8 +1667,10 @@ > > > > // If this is a function with a body, remember the prototype we are > > // creating now, so that we can match up the body with them later. > > - if (!isProto) > > + if (!isProto) { > > FunctionsWithBodies.push_back(Func); > > + if (LazyStreamer) DeferredFunctionInfo[Func] = 0; > > + } > > break; > > } > > // ALIAS: [alias type, aliasee val#, linkage] > > @@ -1691,24 +1709,7 @@ > > bool BitcodeReader::ParseBitcodeInto(Module *M) { > > TheModule = 0; > > > > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > - > > - if (Buffer->getBufferSize() & 3) { > > - if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) > > - return Error("Invalid bitcode signature"); > > - else > > - return Error("Bitcode stream should be a multiple of 4 bytes in length"); > > - } > > - > > - // If we have a wrapper header, parse it and ignore the non-bc file contents. > > - // The magic number is 0x0B17C0DE stored in little endian. > > - if (isBitcodeWrapper(BufPtr, BufEnd)) > > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > > - return Error("Invalid bitcode wrapper header"); > > - > > - StreamFile.init(BufPtr, BufEnd); > > - Stream.init(StreamFile); > > + if (InitStream()) return true; > > > > // Sniff for the signature. > > if (Stream.Read(8) != 'B' || > > @@ -1750,8 +1751,9 @@ > > if (TheModule) > > return Error("Multiple MODULE_BLOCKs in same stream"); > > TheModule = M; > > - if (ParseModule()) > > + if (ParseModule(false)) > > return true; > > + if (LazyStreamer) return false; > > break; > > default: > > if (Stream.SkipBlock()) > > @@ -1819,20 +1821,7 @@ > > } > > > > bool BitcodeReader::ParseTriple(std::string &Triple) { > > - if (Buffer->getBufferSize() & 3) > > - return Error("Bitcode stream should be a multiple of 4 bytes in length"); > > - > > - unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > > - unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > - > > - // If we have a wrapper header, parse it and ignore the non-bc file contents. > > - // The magic number is 0x0B17C0DE stored in little endian. > > - if (isBitcodeWrapper(BufPtr, BufEnd)) > > - if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) > > - return Error("Invalid bitcode wrapper header"); > > - > > - StreamFile.init(BufPtr, BufEnd); > > - Stream.init(StreamFile); > > + if (InitStream()) return true; > > > > // Sniff for the signature. > > if (Stream.Read(8) != 'B' || > > @@ -2708,6 +2697,19 @@ > > return false; > > } > > > > +/// FindFunctionInStream - Find the function body in the bitcode stream > > +bool BitcodeReader::FindFunctionInStream(Function *F, > > + DenseMap::iterator DeferredFunctionInfoIterator) { > > + while (DeferredFunctionInfoIterator->second == 0) { > > + if (Stream.AtEndOfStream()) > > + return Error("Could not find Function in stream"); > > + // ParseModule will parse the next body in the stream and set its > > + // position in the DeferredFunctionInfo map. > > + if (ParseModule(true)) return true; > > + } > > + return false; > > +} > > + > > //===----------------------------------------------------------------------===// > > // GVMaterializer implementation > > //===----------------------------------------------------------------------===// > > @@ -2728,6 +2730,10 @@ > > > > DenseMap::iterator DFII = DeferredFunctionInfo.find(F); > > assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); > > + // If its position is recorded as 0, its body is somewhere in the stream > > + // but we haven't seen it yet. > > + if (DFII->second == 0) > > + if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; > > > > // Move the bit stream to the saved position of the deferred function body. > > Stream.JumpToBit(DFII->second); > > @@ -2805,6 +2811,57 @@ > > return false; > > } > > > > +bool BitcodeReader::InitStream() { > > + if (LazyStreamer) return InitLazyStream(); > > + return InitStreamFromBuffer(); > > +} > > + > > +bool BitcodeReader::InitStreamFromBuffer() { > > + const unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); > > + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); > > + > > + if (Buffer->getBufferSize() & 3) { > > + if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, BufEnd)) > > + return Error("Invalid bitcode signature"); > > + else > > + return Error("Bitcode stream should be a multiple of 4 bytes in length"); > > + } > > + > > + // If we have a wrapper header, parse it and ignore the non-bc file contents. > > + // The magic number is 0x0B17C0DE stored in little endian. > > + if (isBitcodeWrapper(BufPtr, BufEnd)) > > + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) > > + return Error("Invalid bitcode wrapper header"); > > + > > + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); > > + Stream.init(*StreamFile); > > + > > + return false; > > +} > > + > > +bool BitcodeReader::InitLazyStream() { > > + // Check and strip off the bitcode wrapper; BitstreamReader expects never to > > + // see it. > > + StreamingMemoryObject *Bytes = new StreamingMemoryObject(LazyStreamer); > > + StreamFile.reset(new BitstreamReader(Bytes)); > > + Stream.init(*StreamFile); > > + > > + unsigned char buf[16]; > > + if (Bytes->readBytes(0, 16, buf, NULL) == -1) > > + return Error("Bitcode stream must be at least 16 bytes in length"); > > + > > + if (!isBitcode(buf, buf + 16)) > > + return Error("Invalid bitcode signature"); > > + > > + if (isBitcodeWrapper(buf, buf + 4)) { > > + const unsigned char *bitcodeStart = buf; > > + const unsigned char *bitcodeEnd = buf + 16; > > + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); > > + Bytes->dropLeadingBytes(bitcodeStart - buf); > > + Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); > > + } > > + return false; > > +} > > > > //===----------------------------------------------------------------------===// > > // External interface > > @@ -2833,6 +2890,24 @@ > > return M; > > } > > > > + > > +Module *llvm::getStreamedBitcodeModule(const std::string &name, > > + DataStreamer *streamer, > > + LLVMContext &Context, > > + std::string *ErrMsg) { > > + Module *M = new Module(name, Context); > > + BitcodeReader *R = new BitcodeReader(streamer, Context); > > + M->setMaterializer(R); > > + if (R->ParseBitcodeInto(M)) { > > + if (ErrMsg) > > + *ErrMsg = R->getErrorString(); > > + delete M; // Also deletes R. > > + return 0; > > + } > > + R->setBufferOwned(false); // no buffer to delete > > + return M; > > +} > > + > > /// ParseBitcodeFile - Read the specified bitcode file, returning the module. > > /// If an error occurs, return null and fill in *ErrMsg if non-null. > > Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, > > > > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) > > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Mon Feb 6 16:30:29 2012 > > @@ -126,8 +126,11 @@ > > Module *TheModule; > > MemoryBuffer *Buffer; > > bool BufferOwned; > > - BitstreamReader StreamFile; > > + OwningPtr StreamFile; > > BitstreamCursor Stream; > > + DataStreamer *LazyStreamer; > > + uint64_t NextUnreadBit; > > + bool SeenValueSymbolTable; > > > > const char *ErrorString; > > > > @@ -161,9 +164,10 @@ > > // Map the bitcode's custom MDKind ID to the Module's MDKind ID. > > DenseMap MDKindMap; > > > > - // After the module header has been read, the FunctionsWithBodies list is > > - // reversed. This keeps track of whether we've done this yet. > > - bool HasReversedFunctionsWithBodies; > > + // Several operations happen after the module header has been read, but > > + // before function bodies are processed. This keeps track of whether > > + // we've done this yet. > > + bool SeenFirstFunctionBody; > > > > /// DeferredFunctionInfo - When function bodies are initially scanned, this > > /// map contains info about where to find deferred function body in the > > @@ -178,8 +182,13 @@ > > public: > > explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) > > : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), > > - ErrorString(0), ValueList(C), MDValueList(C) { > > - HasReversedFunctionsWithBodies = false; > > + LazyStreamer(0), SeenValueSymbolTable(false), ErrorString(0), > > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > > + } > > + explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) > > + : Context(C), TheModule(0), Buffer(0), BufferOwned(false), > > + LazyStreamer(streamer), SeenValueSymbolTable(false), ErrorString(0), > > + ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { > > } > > ~BitcodeReader() { > > FreeState(); > > @@ -258,7 +267,7 @@ > > } > > > > > > - bool ParseModule(); > > + bool ParseModule(bool Resume); > > bool ParseAttributeBlock(); > > bool ParseTypeTable(); > > bool ParseTypeTableBody(); > > @@ -267,11 +276,17 @@ > > bool ParseConstants(); > > bool RememberAndSkipFunctionBody(); > > bool ParseFunctionBody(Function *F); > > + bool GlobalCleanup(); > > bool ResolveGlobalAndAliasInits(); > > bool ParseMetadata(); > > bool ParseMetadataAttachment(); > > bool ParseModuleTriple(std::string &Triple); > > bool ParseUseLists(); > > + bool InitStream(); > > + bool InitStreamFromBuffer(); > > + bool InitLazyStream(); > > + bool FindFunctionInStream(Function *F, > > + DenseMap::iterator DeferredFunctionInfoIterator); > > }; > > > > } // End llvm namespace > > > > Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) > > +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb 6 16:30:29 2012 > > @@ -1738,11 +1738,6 @@ > > // Emit metadata. > > WriteModuleMetadata(M, VE, Stream); > > > > - // Emit function bodies. > > - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > > - if (!F->isDeclaration()) > > - WriteFunction(*F, VE, Stream); > > - > > // Emit metadata. > > WriteModuleMetadataStore(M, Stream); > > > > @@ -1753,6 +1748,11 @@ > > if (EnablePreserveUseListOrdering) > > WriteModuleUseLists(M, VE, Stream); > > > > + // Emit function bodies. > > + for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) > > + if (!F->isDeclaration()) > > + WriteFunction(*F, VE, Stream); > > + > > Stream.ExitBlock(); > > } > > > > > > Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) > > +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -100,9 +100,9 @@ > > Bytes(bytes), Size(size), BasePC(basePC) {} > > > > uint64_t getBase() const { return BasePC; } > > - uint64_t getExtent() const { return Size; } > > + uint64_t getExtent() { return Size; } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr - BasePC >= Size) > > return -1; > > *Byte = Bytes[Addr - BasePC]; > > > > Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) > > +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -207,8 +207,8 @@ > > void *arg) : Callback(callback), Arg(arg) { } > > ~EDMemoryObject() { } > > uint64_t getBase() const { return 0x0; } > > - uint64_t getExtent() const { return (uint64_t)-1; } > > - int readByte(uint64_t address, uint8_t *ptr) const { > > + uint64_t getExtent() { return (uint64_t)-1; } > > + int readByte(uint64_t address, uint8_t *ptr) { > > if (!Callback) > > return -1; > > > > > > Modified: llvm/trunk/lib/Support/CMakeLists.txt > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Support/CMakeLists.txt (original) > > +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Feb 6 16:30:29 2012 > > @@ -16,6 +16,7 @@ > > ConstantRange.cpp > > CrashRecoveryContext.cpp > > DataExtractor.cpp > > + DataStream.cpp > > Debug.cpp > > DeltaAlgorithm.cpp > > DAGDeltaAlgorithm.cpp > > @@ -42,6 +43,7 @@ > > SmallVector.cpp > > SourceMgr.cpp > > Statistic.cpp > > + StreamableMemoryObject.cpp > > StringExtras.cpp > > StringMap.cpp > > StringPool.cpp > > > > Added: llvm/trunk/lib/Support/DataStream.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149918&view=auto > > ============================================================================== > > --- llvm/trunk/lib/Support/DataStream.cpp (added) > > +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,96 @@ > > +//===--- llvm/Support/DataStream.cpp - Lazy streamed Data ---===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > +//===----------------------------------------------------------------------===// > > +// > > +// This file implements DataStreamer, which fetches bytes of Data from > > +// a stream source. It provides support for streaming (lazy reading) of > > +// bitcode. An example implementation of streaming from a file or stdin > > +// is included. > > +// > > +//===----------------------------------------------------------------------===// > > + > > +#define DEBUG_TYPE "Data-stream" > > +#include "llvm/ADT/Statistic.h" > > +#include "llvm/Support/DataStream.h" > > +#include "llvm/Support/system_error.h" > > +#include > > +#include > > +#include > > +#if !defined(_MSC_VER) && !defined(__MINGW32__) > > +#include > > +#else > > +#include > > +#endif > > +#include > > +using namespace llvm; > > + > > +// Interface goals: > > +// * StreamableMemoryObject doesn't care about complexities like using > > +// threads/async callbacks to actually overlap download+compile > > +// * Don't want to duplicate Data in memory > > +// * Don't need to know total Data len in advance > > +// Non-goals: > > +// StreamableMemoryObject already has random access so this interface only does > > +// in-order streaming (no arbitrary seeking, else we'd have to buffer all the > > +// Data here in addition to MemoryObject). This also means that if we want > > +// to be able to to free Data, BitstreamBytes/BitcodeReader will implement it > > + > > +STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); > > + > > +namespace llvm { > > +DataStreamer::~DataStreamer() {} > > +} > > + > > +namespace { > > + > > +const static error_code success; > > + > > +// Very simple stream backed by a file. Mostly useful for stdin and debugging; > > +// actual file access is probably still best done with mmap. > > +class DataFileStreamer : public DataStreamer { > > + int Fd; > > +public: > > + DataFileStreamer() : Fd(0) {} > > + virtual ~DataFileStreamer() { > > + close(Fd); > > + } > > + virtual size_t GetBytes(unsigned char *buf, size_t len) { > > + NumStreamFetches++; > > + return read(Fd, buf, len); > > + } > > + > > + error_code OpenFile(const std::string &Filename) { > > + int OpenFlags = O_RDONLY; > > +#ifdef O_BINARY > > + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. > > +#endif > > + if (Filename == "-") > > + Fd = 0; > > + else > > + Fd = ::open(Filename.c_str(), OpenFlags); > > + if (Fd == -1) return error_code(errno, posix_category()); > > + return success; > > + } > > +}; > > + > > +} > > + > > +namespace llvm { > > +DataStreamer *getDataFileStreamer(const std::string &Filename, > > + std::string *StrError) { > > + DataFileStreamer *s = new DataFileStreamer(); > > + error_code e = s->OpenFile(Filename); > > + if (e != success) { > > + *StrError = std::string("Could not open ") + Filename + ": " + > > + e.message() + "\n"; > > + return NULL; > > + } > > + return s; > > +} > > + > > +} > > > > Modified: llvm/trunk/lib/Support/MemoryObject.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryObject.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Support/MemoryObject.cpp (original) > > +++ llvm/trunk/lib/Support/MemoryObject.cpp Mon Feb 6 16:30:29 2012 > > @@ -16,7 +16,7 @@ > > int MemoryObject::readBytes(uint64_t address, > > uint64_t size, > > uint8_t* buf, > > - uint64_t* copied) const { > > + uint64_t* copied) { > > uint64_t current = address; > > uint64_t limit = getBase() + getExtent(); > > > > > > Added: llvm/trunk/lib/Support/StreamableMemoryObject.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149918&view=auto > > ============================================================================== > > --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (added) > > +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb 6 16:30:29 2012 > > @@ -0,0 +1,137 @@ > > +//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ -*-===// > > +// > > +// The LLVM Compiler Infrastructure > > +// > > +// This file is distributed under the University of Illinois Open Source > > +// License. See LICENSE.TXT for details. > > +// > > +//===----------------------------------------------------------------------===// > > + > > +#include "llvm/Support/StreamableMemoryObject.h" > > +#include > > +#include > > + > > + > > +using namespace llvm; > > + > > +namespace { > > + > > +class RawMemoryObject : public StreamableMemoryObject { > > +public: > > + RawMemoryObject(const unsigned char *Start, const unsigned char *End) : > > + FirstChar(Start), LastChar(End) { > > + assert(LastChar > FirstChar && "Invalid start/end range"); > > + } > > + > > + virtual uint64_t getBase() const { return 0; } > > + virtual uint64_t getExtent() { return LastChar - FirstChar; } > > + virtual int readByte(uint64_t address, uint8_t* ptr); > > + virtual int readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied); > > + virtual const uint8_t *getPointer(uint64_t address, uint64_t size); > > + virtual bool isValidAddress(uint64_t address) {return validAddress(address);} > > + virtual bool isObjectEnd(uint64_t address) {return objectEnd(address);} > > + > > +private: > > + const uint8_t* const FirstChar; > > + const uint8_t* const LastChar; > > + > > + // These are implemented as inline functions here to avoid multiple virtual > > + // calls per public function > > + bool validAddress(uint64_t address) { > > + return static_cast(address) < LastChar - FirstChar; > > + } > > + bool objectEnd(uint64_t address) { > > + return static_cast(address) == LastChar - FirstChar; > > + } > > + > > + RawMemoryObject(const RawMemoryObject&); // DO NOT IMPLEMENT > > + void operator=(const RawMemoryObject&); // DO NOT IMPLEMENT > > +}; > > + > > +int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > > + if (!validAddress(address)) return -1; > > + *ptr = *((uint8_t *)(uintptr_t)(address + FirstChar)); > > + return 0; > > +} > > + > > +int RawMemoryObject::readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) { > > + if (!validAddress(address) || !validAddress(address + size - 1)) return -1; > > + memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); > > + if (copied) *copied = size; > > + return size; > > +} > > + > > +const uint8_t *RawMemoryObject::getPointer(uint64_t address, uint64_t size) { > > + return FirstChar + address; > > +} > > +} // anonymous namespace > > + > > +namespace llvm { > > +// If the bitcode has a header, then its size is known, and we don't have to > > +// block until we actually want to read it. > > +bool StreamingMemoryObject::isValidAddress(uint64_t address) { > > + if (ObjectSize && address < ObjectSize) return true; > > + return fetchToPos(address); > > +} > > + > > +bool StreamingMemoryObject::isObjectEnd(uint64_t address) { > > + if (ObjectSize) return address == ObjectSize; > > + fetchToPos(address); > > + return address == ObjectSize && address != 0; > > +} > > + > > +uint64_t StreamingMemoryObject::getExtent() { > > + if (ObjectSize) return ObjectSize; > > + size_t pos = BytesRead + kChunkSize; > > + // keep fetching until we run out of bytes > > + while (fetchToPos(pos)) pos += kChunkSize; > > + return ObjectSize; > > +} > > + > > +int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) { > > + if (!fetchToPos(address)) return -1; > > + *ptr = Bytes[address + BytesSkipped]; > > + return 0; > > +} > > + > > +int StreamingMemoryObject::readBytes(uint64_t address, > > + uint64_t size, > > + uint8_t* buf, > > + uint64_t* copied) { > > + if (!fetchToPos(address + size - 1)) return -1; > > + memcpy(buf, &Bytes[address + BytesSkipped], size); > > + if (copied) *copied = size; > > + return 0; > > +} > > + > > +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { > > + if (BytesRead < s) return true; > > + BytesSkipped = s; > > + BytesRead -= s; > > + return false; > > +} > > + > > +void StreamingMemoryObject::setKnownObjectSize(size_t size) { > > + ObjectSize = size; > > + Bytes.reserve(size); > > +} > > + > > +StreamableMemoryObject *getNonStreamedMemoryObject( > > + const unsigned char *Start, const unsigned char *End) { > > + return new RawMemoryObject(Start, End); > > +} > > + > > +StreamableMemoryObject::~StreamableMemoryObject() { } > > + > > +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : > > + Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), > > + ObjectSize(0), EOFReached(false) { > > + BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); > > +} > > +} > > > > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp (original) > > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -46,7 +46,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > @@ -71,7 +71,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > @@ -341,7 +341,7 @@ > > } > > > > DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, > > - const MemoryObject &Region, > > + MemoryObject &Region, > > uint64_t Address, > > raw_ostream &os, > > raw_ostream &cs) const { > > @@ -691,7 +691,7 @@ > > } > > > > DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size, > > - const MemoryObject &Region, > > + MemoryObject &Region, > > uint64_t Address, > > raw_ostream &os, > > raw_ostream &cs) const { > > > > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp (original) > > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -502,7 +502,7 @@ > > > > MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const { > > > > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h (original) > > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h Mon Feb 6 16:30:29 2012 > > @@ -40,7 +40,7 @@ > > /// getInstruction - See MCDisassembler. > > MCDisassembler::DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp (original) > > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -112,7 +112,7 @@ > > MCDisassembler::DecodeStatus > > X86GenericDisassembler::getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const { > > > > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) > > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Mon Feb 6 16:30:29 2012 > > @@ -114,7 +114,7 @@ > > /// getInstruction - See MCDisassembler. > > DecodeStatus getInstruction(MCInst &instr, > > uint64_t &size, > > - const MemoryObject ®ion, > > + MemoryObject ®ion, > > uint64_t address, > > raw_ostream &vStream, > > raw_ostream &cStream) const; > > > > Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) > > +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb 6 16:30:29 2012 > > @@ -483,13 +483,13 @@ > > if (MemBuf->getBufferSize() & 3) > > return Error("Bitcode stream should be a multiple of 4 bytes in length"); > > > > - unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); > > - unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > > + const unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); > > + const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); > > > > // If we have a wrapper header, parse it and ignore the non-bc file contents. > > // The magic number is 0x0B17C0DE stored in little endian. > > if (isBitcodeWrapper(BufPtr, EndBufPtr)) > > - if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) > > + if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) > > return Error("Invalid bitcode wrapper header"); > > > > BitstreamReader StreamFile(BufPtr, EndBufPtr); > > > > Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) > > +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Feb 6 16:30:29 2012 > > @@ -24,6 +24,7 @@ > > #include "llvm/Analysis/DebugInfo.h" > > #include "llvm/Assembly/AssemblyAnnotationWriter.h" > > #include "llvm/Support/CommandLine.h" > > +#include "llvm/Support/DataStream.h" > > #include "llvm/Support/FormattedStream.h" > > #include "llvm/Support/ManagedStatic.h" > > #include "llvm/Support/MemoryBuffer.h" > > @@ -126,12 +127,19 @@ > > std::string ErrorMessage; > > std::auto_ptr M; > > > > - { > > - OwningPtr BufferPtr; > > - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) > > - ErrorMessage = ec.message(); > > + // Use the bitcode streaming interface > > + DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); > > + if (streamer) { > > + std::string DisplayFilename; > > + if (InputFilename == "-") > > + DisplayFilename = ""; > > else > > - M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); > > + DisplayFilename = InputFilename; > > + M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, > > + &ErrorMessage)); > > + if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { > > + M.reset(); > > + } > > } > > > > if (M.get() == 0) { > > @@ -183,4 +191,3 @@ > > > > return 0; > > } > > - > > > > Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) > > +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Mon Feb 6 16:30:29 2012 > > @@ -42,9 +42,9 @@ > > VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} > > > > uint64_t getBase() const { return 0; } > > - uint64_t getExtent() const { return Bytes.size(); } > > + uint64_t getExtent() { return Bytes.size(); } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr >= getExtent()) > > return -1; > > *Byte = Bytes[Addr].first; > > > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.cpp > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.cpp?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/MCFunction.cpp (original) > > +++ llvm/trunk/tools/llvm-objdump/MCFunction.cpp Mon Feb 6 16:30:29 2012 > > @@ -28,7 +28,7 @@ > > > > MCFunction > > MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, > > - const MemoryObject &Region, uint64_t Start, > > + MemoryObject &Region, uint64_t Start, > > uint64_t End, const MCInstrAnalysis *Ana, > > raw_ostream &DebugOut, > > SmallVectorImpl &Calls) { > > > > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/MCFunction.h (original) > > +++ llvm/trunk/tools/llvm-objdump/MCFunction.h Mon Feb 6 16:30:29 2012 > > @@ -79,7 +79,7 @@ > > // Create an MCFunction from a region of binary machine code. > > static MCFunction > > createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, > > - const MemoryObject &Region, uint64_t Start, uint64_t End, > > + MemoryObject &Region, uint64_t Start, uint64_t End, > > const MCInstrAnalysis *Ana, raw_ostream &DebugOut, > > SmallVectorImpl &Calls); > > > > > > Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h > > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=149918&r1=149917&r2=149918&view=diff > > ============================================================================== > > --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original) > > +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb 6 16:30:29 2012 > > @@ -31,9 +31,9 @@ > > StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} > > > > uint64_t getBase() const { return 0; } > > - uint64_t getExtent() const { return Bytes.size(); } > > + uint64_t getExtent() { return Bytes.size(); } > > > > - int readByte(uint64_t Addr, uint8_t *Byte) const { > > + int readByte(uint64_t Addr, uint8_t *Byte) { > > if (Addr >= getExtent()) > > return -1; > > *Byte = Bytes[Addr]; > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/6019fe95/attachment-0001.html From dblaikie at gmail.com Tue Feb 7 14:40:40 2012 From: dblaikie at gmail.com (David Blaikie) Date: Tue, 7 Feb 2012 12:40:40 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ In-Reply-To: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> References: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> Message-ID: On Tue, Feb 7, 2012 at 12:30 PM, Jim Grosbach wrote: > > On Feb 7, 2012, at 11:29 AM, Derek Schuff wrote: > > Hi Jim, > Originally the patch was written such that the bitcode reader used a new > container class to hold the bitcode, and get pieces of it using methods like > getByte, getWord, etc. Chris asked me to use MemoryObject instead, which has > a similar interface (readBytes et al), except that those methods are const. > They definitely can't be const when each call can result in fetching more > bytes from the stream, so all the MC constness changes are basically fallout > from MemoryBuffer's readBytes method no longer being const. I'm not averse > to going back to the other way, but I'd like to have some agreement from the > relevant stakeholders as to the right approach before I put more work into > it. > > > I don't know the history of what Chris asked, so I can't effectively comment > on that. This patch, however, removes our ability to express the existence > of a MemoryObject that is immutable. That's not a good thing and I'd like to > avoid it. > > Why can't a const StreamableMemoryObject read in more information to satisfy > a request? As I understand it, 'const' there is saying that the data won't > be modified and not necessarily anything about what actions need to be taken > to read it. > > From an implementation detail point of view, consider the following > contrived example: > > $ cat foo.cpp > #include > > #include > > class myClass { > > ? unsigned *storage; > > public: > > ? myClass(unsigned *buffer) { storage = buffer; } > > > > ? void write(unsigned val) const { *storage = val; } > > ? unsigned read() const { return *storage; } > > ? void set(unsigned *buffer) { storage = buffer; } > > }; > > > > void foo(const myClass *p) { > > ? p->write(5); > > ? std::cout << p->read() << std::endl; > > ? p->write(4); > > ? std::cout << p->read() << std::endl; > > ? // Can't do this due to 'const' > > ? //?error: member function 'set' not viable: 'this' argument has type > 'const myClass', but function is not marked const > ? //unsigned newbuf; > > ? //p->set(&newbuf); > > } > > > > int main(int argc, char *argv[]) { > > ? unsigned val; > > ? myClass X(&val); > > ? foo(&X); > > } > $ clang++ foo.cpp -o foo > $ ./foo > 5 > 4 > > In this example, the 'const' on our instance of myClass indicates that the > underlying storage can't be changed, but says nothing about what's actually > in that storage, as indicated by the fact that our write() method is const > qualified. If we wanted the interface to have the data itself also be const, > then we would just remove the const from the write() declaration. > > Yes, this is a bit funky and plays some games w/ 'const', but it allows us > to express our intent with the interfaces. Copious commenting is > recommended. :) If it helps any - another example/analogy for what you're talking about is the difference between std::vector and llvm::MutableArrayRef (nevermind the "Mutable" in the name - there are other ways to do this with specialization that avoid the weird naming). Vector has value semantics & owns the underlying data - MutableArrayRef has reference semantics - you can read/write to the underlying data of a const MutableArrayRef, but you can't rebind it (eg: assign another MutableArrayRef (referring to a different array) to that const MutableArrayRef). - David > > -Jim > > -Derek > > > On Tue, Feb 7, 2012 at 11:15 AM, Jim Grosbach wrote: >> >> Hi Derek, >> >> I don't follow why this needs to change the MC disassemblers. Those have >> nothing to do with bitcode. Can you elaborate? I'm uncomfortable with >> removing the const'ness of the input to those methods, for example. >> >> -Jim >> >> On Feb 6, 2012, at 2:30 PM, Derek Schuff wrote: >> >> > Author: dschuff >> > Date: Mon Feb ?6 16:30:29 2012 >> > New Revision: 149918 >> > >> > URL: http://llvm.org/viewvc/llvm-project?rev=149918&view=rev >> > Log: >> > Enable streaming of bitcode >> > >> > This CL delays reading of function bodies from initial parse until >> > materialization, allowing overlap of compilation with bitcode download. >> > >> > >> > Added: >> > ? ?llvm/trunk/include/llvm/Support/DataStream.h >> > ? ?llvm/trunk/include/llvm/Support/StreamableMemoryObject.h >> > ? ?llvm/trunk/lib/Support/DataStream.cpp >> > ? ?llvm/trunk/lib/Support/StreamableMemoryObject.cpp >> > Modified: >> > ? ?llvm/trunk/include/llvm/Bitcode/BitstreamReader.h >> > ? ?llvm/trunk/include/llvm/Bitcode/ReaderWriter.h >> > ? ?llvm/trunk/include/llvm/MC/MCDisassembler.h >> > ? ?llvm/trunk/include/llvm/Support/MemoryObject.h >> > ? ?llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp >> > ? ?llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h >> > ? ?llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp >> > ? ?llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp >> > ? ?llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp >> > ? ?llvm/trunk/lib/Support/CMakeLists.txt >> > ? ?llvm/trunk/lib/Support/MemoryObject.cpp >> > ? ?llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp >> > ? ?llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp >> > ? ?llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h >> > ? ?llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp >> > ? ?llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h >> > ? ?llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp >> > ? ?llvm/trunk/tools/llvm-dis/llvm-dis.cpp >> > ? ?llvm/trunk/tools/llvm-mc/Disassembler.cpp >> > ? ?llvm/trunk/tools/llvm-objdump/MCFunction.cpp >> > ? ?llvm/trunk/tools/llvm-objdump/MCFunction.h >> > ? ?llvm/trunk/tools/llvm-objdump/llvm-objdump.h >> > >> > Modified: llvm/trunk/include/llvm/Bitcode/BitstreamReader.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/BitstreamReader.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/Bitcode/BitstreamReader.h (original) >> > +++ llvm/trunk/include/llvm/Bitcode/BitstreamReader.h Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -15,10 +15,12 @@ >> > #ifndef BITSTREAM_READER_H >> > #define BITSTREAM_READER_H >> > >> > +#include "llvm/ADT/OwningPtr.h" >> > #include "llvm/Bitcode/BitCodes.h" >> > #include >> > #include >> > #include >> > +#include "llvm/Support/StreamableMemoryObject.h" >> > >> > namespace llvm { >> > >> > @@ -36,9 +38,7 @@ >> > ? ? std::vector > RecordNames; >> > ? }; >> > private: >> > - ?/// FirstChar/LastChar - This remembers the first and last bytes of >> > the >> > - ?/// stream. >> > - ?const unsigned char *FirstChar, *LastChar; >> > + ?OwningPtr BitcodeBytes; >> > >> > ? std::vector BlockInfoRecords; >> > >> > @@ -47,10 +47,10 @@ >> > ? /// uses this. >> > ? bool IgnoreBlockInfoNames; >> > >> > - ?BitstreamReader(const BitstreamReader&); ?// NOT IMPLEMENTED >> > - ?void operator=(const BitstreamReader&); ?// NOT IMPLEMENTED >> > + ?BitstreamReader(const BitstreamReader&); ?// DO NOT IMPLEMENT >> > + ?void operator=(const BitstreamReader&); ?// DO NOT IMPLEMENT >> > public: >> > - ?BitstreamReader() : FirstChar(0), LastChar(0), >> > IgnoreBlockInfoNames(true) { >> > + ?BitstreamReader() : IgnoreBlockInfoNames(true) { >> > ? } >> > >> > ? BitstreamReader(const unsigned char *Start, const unsigned char *End) >> > { >> > @@ -58,12 +58,17 @@ >> > ? ? init(Start, End); >> > ? } >> > >> > + ?BitstreamReader(StreamableMemoryObject *bytes) { >> > + ? ?BitcodeBytes.reset(bytes); >> > + ?} >> > + >> > ? void init(const unsigned char *Start, const unsigned char *End) { >> > - ? ?FirstChar = Start; >> > - ? ?LastChar = End; >> > ? ? assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 >> > bytes"); >> > + ? ?BitcodeBytes.reset(getNonStreamedMemoryObject(Start, End)); >> > ? } >> > >> > + ?StreamableMemoryObject &getBitcodeBytes() { return *BitcodeBytes; } >> > + >> > ? ~BitstreamReader() { >> > ? ? // Free the BlockInfoRecords. >> > ? ? while (!BlockInfoRecords.empty()) { >> > @@ -75,9 +80,6 @@ >> > ? ? ? BlockInfoRecords.pop_back(); >> > ? ? } >> > ? } >> > - >> > - ?const unsigned char *getFirstChar() const { return FirstChar; } >> > - ?const unsigned char *getLastChar() const { return LastChar; } >> > >> > ? /// CollectBlockInfoNames - This is called by clients that want >> > block/record >> > ? /// name information. >> > @@ -122,7 +124,7 @@ >> > class BitstreamCursor { >> > ? friend class Deserializer; >> > ? BitstreamReader *BitStream; >> > - ?const unsigned char *NextChar; >> > + ?size_t NextChar; >> > >> > ? /// CurWord - This is the current data we have pulled from the stream >> > but have >> > ? /// not returned to the client. >> > @@ -156,8 +158,7 @@ >> > ? } >> > >> > ? explicit BitstreamCursor(BitstreamReader &R) : BitStream(&R) { >> > - ? ?NextChar = R.getFirstChar(); >> > - ? ?assert(NextChar && "Bitstream not initialized yet"); >> > + ? ?NextChar = 0; >> > ? ? CurWord = 0; >> > ? ? BitsInCurWord = 0; >> > ? ? CurCodeSize = 2; >> > @@ -167,8 +168,7 @@ >> > ? ? freeState(); >> > >> > ? ? BitStream = &R; >> > - ? ?NextChar = R.getFirstChar(); >> > - ? ?assert(NextChar && "Bitstream not initialized yet"); >> > + ? ?NextChar = 0; >> > ? ? CurWord = 0; >> > ? ? BitsInCurWord = 0; >> > ? ? CurCodeSize = 2; >> > @@ -225,13 +225,38 @@ >> > ? /// GetAbbrevIDWidth - Return the number of bits used to encode an >> > abbrev #. >> > ? unsigned GetAbbrevIDWidth() const { return CurCodeSize; } >> > >> > - ?bool AtEndOfStream() const { >> > - ? ?return NextChar == BitStream->getLastChar() && BitsInCurWord == 0; >> > + ?bool isEndPos(size_t pos) { >> > + ? ?return >> > BitStream->getBitcodeBytes().isObjectEnd(static_cast(pos)); >> > + ?} >> > + >> > + ?bool canSkipToPos(size_t pos) const { >> > + ? ?// pos can be skipped to if it is a valid address or one byte past >> > the end. >> > + ? ?return pos == 0 || BitStream->getBitcodeBytes().isValidAddress( >> > + ? ? ? ?static_cast(pos - 1)); >> > + ?} >> > + >> > + ?unsigned char getByte(size_t pos) { >> > + ? ?uint8_t byte = -1; >> > + ? ?BitStream->getBitcodeBytes().readByte(pos, &byte); >> > + ? ?return byte; >> > + ?} >> > + >> > + ?uint32_t getWord(size_t pos) { >> > + ? ?uint32_t word = -1; >> > + ? ?BitStream->getBitcodeBytes().readBytes(pos, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sizeof(word), >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? reinterpret_cast> > *>(&word), >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL); >> > + ? ?return word; >> > + ?} >> > + >> > + ?bool AtEndOfStream() { >> > + ? ?return isEndPos(NextChar) && BitsInCurWord == 0; >> > ? } >> > >> > ? /// GetCurrentBitNo - Return the bit # of the bit we are reading. >> > ? uint64_t GetCurrentBitNo() const { >> > - ? ?return (NextChar-BitStream->getFirstChar())*CHAR_BIT - >> > BitsInCurWord; >> > + ? ?return NextChar*CHAR_BIT - BitsInCurWord; >> > ? } >> > >> > ? BitstreamReader *getBitStreamReader() { >> > @@ -246,12 +271,10 @@ >> > ? void JumpToBit(uint64_t BitNo) { >> > ? ? uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3; >> > ? ? uintptr_t WordBitNo = uintptr_t(BitNo) & 31; >> > - ? ?assert(ByteNo <= (uintptr_t)(BitStream->getLastChar()- >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BitStream->getFirstChar()) && >> > - ? ? ? ? ? "Invalid location"); >> > + ? ?assert(canSkipToPos(ByteNo) && "Invalid location"); >> > >> > ? ? // Move the cursor to the right word. >> > - ? ?NextChar = BitStream->getFirstChar()+ByteNo; >> > + ? ?NextChar = ByteNo; >> > ? ? BitsInCurWord = 0; >> > ? ? CurWord = 0; >> > >> > @@ -272,7 +295,7 @@ >> > ? ? } >> > >> > ? ? // If we run out of data, stop at the end of the stream. >> > - ? ?if (NextChar == BitStream->getLastChar()) { >> > + ? ?if (isEndPos(NextChar)) { >> > ? ? ? CurWord = 0; >> > ? ? ? BitsInCurWord = 0; >> > ? ? ? return 0; >> > @@ -281,8 +304,7 @@ >> > ? ? unsigned R = CurWord; >> > >> > ? ? // Read the next word from the stream. >> > - ? ?CurWord = (NextChar[0] << ?0) | (NextChar[1] << 8) | >> > - ? ? ? ? ? ? ?(NextChar[2] << 16) | (NextChar[3] << 24); >> > + ? ?CurWord = getWord(NextChar); >> > ? ? NextChar += 4; >> > >> > ? ? // Extract NumBits-BitsInCurWord from what we just read. >> > @@ -376,9 +398,8 @@ >> > >> > ? ? // Check that the block wasn't partially defined, and that the >> > offset isn't >> > ? ? // bogus. >> > - ? ?const unsigned char *const SkipTo = NextChar + NumWords*4; >> > - ? ?if (AtEndOfStream() || SkipTo > BitStream->getLastChar() || >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? SkipTo < BitStream->getFirstChar()) >> > + ? ?size_t SkipTo = NextChar + NumWords*4; >> > + ? ?if (AtEndOfStream() || !canSkipToPos(SkipTo)) >> > ? ? ? return true; >> > >> > ? ? NextChar = SkipTo; >> > @@ -409,8 +430,7 @@ >> > ? ? if (NumWordsP) *NumWordsP = NumWords; >> > >> > ? ? // Validate that this block is sane. >> > - ? ?if (CurCodeSize == 0 || AtEndOfStream() || >> > - ? ? ? ?NextChar+NumWords*4 > BitStream->getLastChar()) >> > + ? ?if (CurCodeSize == 0 || AtEndOfStream()) >> > ? ? ? return true; >> > >> > ? ? return false; >> > @@ -512,24 +532,25 @@ >> > ? ? ? ? SkipToWord(); ?// 32-bit alignment >> > >> > ? ? ? ? // Figure out where the end of this blob will be including tail >> > padding. >> > - ? ? ? ?const unsigned char *NewEnd = NextChar+((NumElts+3)&~3); >> > + ? ? ? ?size_t NewEnd = NextChar+((NumElts+3)&~3); >> > >> > ? ? ? ? // If this would read off the end of the bitcode file, just set >> > the >> > ? ? ? ? // record to empty and return. >> > - ? ? ? ?if (NewEnd > BitStream->getLastChar()) { >> > + ? ? ? ?if (!canSkipToPos(NewEnd)) { >> > ? ? ? ? ? Vals.append(NumElts, 0); >> > - ? ? ? ? ?NextChar = BitStream->getLastChar(); >> > + ? ? ? ? ?NextChar = BitStream->getBitcodeBytes().getExtent(); >> > ? ? ? ? ? break; >> > ? ? ? ? } >> > >> > ? ? ? ? // Otherwise, read the number of bytes. ?If we can return a >> > reference to >> > ? ? ? ? // the data, do so to avoid copying it. >> > ? ? ? ? if (BlobStart) { >> > - ? ? ? ? ?*BlobStart = (const char*)NextChar; >> > + ? ? ? ? ?*BlobStart = (const >> > char*)BitStream->getBitcodeBytes().getPointer( >> > + ? ? ? ? ? ? ?NextChar, NumElts); >> > ? ? ? ? ? *BlobLen = NumElts; >> > ? ? ? ? } else { >> > ? ? ? ? ? for (; NumElts; ++NextChar, --NumElts) >> > - ? ? ? ? ? ?Vals.push_back(*NextChar); >> > + ? ? ? ? ? ?Vals.push_back(getByte(NextChar)); >> > ? ? ? ? } >> > ? ? ? ? // Skip over tail padding. >> > ? ? ? ? NextChar = NewEnd; >> > >> > Modified: llvm/trunk/include/llvm/Bitcode/ReaderWriter.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/ReaderWriter.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/Bitcode/ReaderWriter.h (original) >> > +++ llvm/trunk/include/llvm/Bitcode/ReaderWriter.h Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -17,35 +17,45 @@ >> > #include >> > >> > namespace llvm { >> > - ?class Module; >> > - ?class MemoryBuffer; >> > - ?class ModulePass; >> > ? class BitstreamWriter; >> > + ?class MemoryBuffer; >> > + ?class DataStreamer; >> > ? class LLVMContext; >> > + ?class Module; >> > + ?class ModulePass; >> > ? class raw_ostream; >> > - >> > + >> > ? /// getLazyBitcodeModule - Read the header of the specified bitcode >> > buffer >> > ? /// and prepare for lazy deserialization of function bodies. ?If >> > successful, >> > ? /// this takes ownership of 'buffer' and returns a non-null pointer. >> > ?On >> > ? /// error, this returns null, *does not* take ownership of Buffer, and >> > fills >> > ? /// in *ErrMsg with an error description if ErrMsg is non-null. >> > ? Module *getLazyBitcodeModule(MemoryBuffer *Buffer, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext& Context, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext &Context, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?std::string *ErrMsg = 0); >> > >> > + ?/// getStreamedBitcodeModule - Read the header of the specified >> > stream >> > + ?/// and prepare for lazy deserialization and streaming of function >> > bodies. >> > + ?/// On error, this returns null, and fills in *ErrMsg with an error >> > + ?/// description if ErrMsg is non-null. >> > + ?Module *getStreamedBitcodeModule(const std::string &name, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DataStreamer *streamer, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext &Context, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? std::string *ErrMsg = 0); >> > + >> > ? /// getBitcodeTargetTriple - Read the header of the specified bitcode >> > ? /// buffer and extract just the triple information. If successful, >> > ? /// this returns a string and *does not* take ownership >> > ? /// of 'buffer'. On error, this returns "", and fills in *ErrMsg >> > ? /// if ErrMsg is non-null. >> > ? std::string getBitcodeTargetTriple(MemoryBuffer *Buffer, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext& Context, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext &Context, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?std::string *ErrMsg = 0); >> > >> > ? /// ParseBitcodeFile - Read the specified bitcode file, returning the >> > module. >> > ? /// If an error occurs, this returns null and fills in *ErrMsg if it >> > is >> > ? /// non-null. ?This method *never* takes ownership of Buffer. >> > - ?Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& Context, >> > + ?Module *ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext &Context, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ?std::string *ErrMsg = 0); >> > >> > ? /// WriteBitcodeToFile - Write the specified module to the specified >> > @@ -60,8 +70,8 @@ >> > ? /// createBitcodeWriterPass - Create and return a pass that writes the >> > module >> > ? /// to the specified ostream. >> > ? ModulePass *createBitcodeWriterPass(raw_ostream &Str); >> > - >> > - >> > + >> > + >> > ? /// isBitcodeWrapper - Return true if the given bytes are the magic >> > bytes >> > ? /// for an LLVM IR bitcode wrapper. >> > ? /// >> > @@ -109,21 +119,24 @@ >> > ? /// ? uint32_t BitcodeSize; ? // Size of traditional bitcode file. >> > ? /// ? ... potentially other gunk ... >> > ? /// }; >> > - ?/// >> > + ?/// >> > ? /// This function is called when we find a file with a matching magic >> > number. >> > ? /// In this case, skip down to the subsection of the file that is >> > actually a >> > ? /// BC file. >> > - ?static inline bool SkipBitcodeWrapperHeader(unsigned char *&BufPtr, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?unsigned char *&BufEnd) { >> > + ?/// If 'VerifyBufferSize' is true, check that the buffer is large >> > enough to >> > + ?/// contain the whole bitcode file. >> > + ?static inline bool SkipBitcodeWrapperHeader(const unsigned char >> > *&BufPtr, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const unsigned char >> > *&BufEnd, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?bool VerifyBufferSize) { >> > ? ? enum { >> > ? ? ? KnownHeaderSize = 4*4, ?// Size of header we read. >> > ? ? ? OffsetField = 2*4, ? ? ?// Offset in bytes to Offset field. >> > ? ? ? SizeField = 3*4 ? ? ? ? // Offset in bytes to Size field. >> > ? ? }; >> > - >> > + >> > ? ? // Must contain the header! >> > ? ? if (BufEnd-BufPtr < KnownHeaderSize) return true; >> > - >> > + >> > ? ? unsigned Offset = ( BufPtr[OffsetField ?] ? ? ? ?| >> > ? ? ? ? ? ? ? ? ? ? ? ?(BufPtr[OffsetField+1] << 8) ?| >> > ? ? ? ? ? ? ? ? ? ? ? ?(BufPtr[OffsetField+2] << 16) | >> > @@ -132,9 +145,9 @@ >> > ? ? ? ? ? ? ? ? ? ? ? ?(BufPtr[SizeField ?+1] << 8) ?| >> > ? ? ? ? ? ? ? ? ? ? ? ?(BufPtr[SizeField ?+2] << 16) | >> > ? ? ? ? ? ? ? ? ? ? ? ?(BufPtr[SizeField ?+3] << 24)); >> > - >> > + >> > ? ? // Verify that Offset+Size fits in the file. >> > - ? ?if (Offset+Size > unsigned(BufEnd-BufPtr)) >> > + ? ?if (VerifyBufferSize && Offset+Size > unsigned(BufEnd-BufPtr)) >> > ? ? ? return true; >> > ? ? BufPtr += Offset; >> > ? ? BufEnd = BufPtr+Size; >> > >> > Modified: llvm/trunk/include/llvm/MC/MCDisassembler.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/MC/MCDisassembler.h (original) >> > +++ llvm/trunk/include/llvm/MC/MCDisassembler.h Mon Feb ?6 16:30:29 2012 >> > @@ -79,7 +79,7 @@ >> > ? /// ? ? ? ? ? ? ? ? ? MCDisassembler::Fail if the instruction was >> > invalid. >> > ? virtual DecodeStatus ?getInstruction(MCInst& instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t& size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &cStream) const = 0; >> > >> > Added: llvm/trunk/include/llvm/Support/DataStream.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DataStream.h?rev=149918&view=auto >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/Support/DataStream.h (added) >> > +++ llvm/trunk/include/llvm/Support/DataStream.h Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -0,0 +1,38 @@ >> > +//===---- llvm/Support/DataStream.h - Lazy bitcode streaming -*- C++ >> > -*-===// >> > +// >> > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure >> > +// >> > +// This file is distributed under the University of Illinois Open >> > Source >> > +// License. See LICENSE.TXT for details. >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > +// >> > +// This header defines DataStreamer, which fetches bytes of data from >> > +// a stream source. It provides support for streaming (lazy reading) of >> > +// data, e.g. bitcode >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > + >> > + >> > +#ifndef LLVM_SUPPORT_DATASTREAM_H_ >> > +#define LLVM_SUPPORT_DATASTREAM_H_ >> > + >> > +#include >> > + >> > +namespace llvm { >> > + >> > +class DataStreamer { >> > +public: >> > + ?/// Fetch bytes [start-end) from the stream, and write them to the >> > + ?/// buffer pointed to by buf. Returns the number of bytes actually >> > written. >> > + ?virtual size_t GetBytes(unsigned char *buf, size_t len) = 0; >> > + >> > + ?virtual ~DataStreamer(); >> > +}; >> > + >> > +DataStreamer *getDataFileStreamer(const std::string &Filename, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?std::string *Err); >> > + >> > +} >> > + >> > +#endif ?// LLVM_SUPPORT_DATASTREAM_H_ >> > >> > Modified: llvm/trunk/include/llvm/Support/MemoryObject.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MemoryObject.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/Support/MemoryObject.h (original) >> > +++ llvm/trunk/include/llvm/Support/MemoryObject.h Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -34,7 +34,7 @@ >> > ? /// ? ? ? ? ? ? ? ? ? is getBase() + getExtent() - 1). >> > ? /// >> > ? /// @result ? ? ? ? - The size of the region. >> > - ?virtual uint64_t getExtent() const = 0; >> > + ?virtual uint64_t getExtent() = 0; >> > >> > ? /// readByte ? ? ? ?- Tries to read a single byte from the region. >> > ? /// >> > @@ -42,7 +42,7 @@ >> > ? /// @param ptr ? ? ?- A pointer to a byte to be filled in. ?Must be >> > non-NULL. >> > ? /// @result ? ? ? ? - 0 if successful; -1 if not. ?Failure may be due >> > to a >> > ? /// ? ? ? ? ? ? ? ? ? bounds violation or an implementation-specific >> > error. >> > - ?virtual int readByte(uint64_t address, uint8_t* ptr) const = 0; >> > + ?virtual int readByte(uint64_t address, uint8_t* ptr) = 0; >> > >> > ? /// readBytes ? ? ? - Tries to read a contiguous range of bytes from >> > the >> > ? /// ? ? ? ? ? ? ? ? ? region, up to the end of the region. >> > @@ -61,7 +61,7 @@ >> > ? virtual int readBytes(uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? uint64_t size, >> > ? ? ? ? ? ? ? ? ? ? ? ? uint8_t* buf, >> > - ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied) const; >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied); >> > }; >> > >> > } >> > >> > Added: llvm/trunk/include/llvm/Support/StreamableMemoryObject.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StreamableMemoryObject.h?rev=149918&view=auto >> > >> > ============================================================================== >> > --- llvm/trunk/include/llvm/Support/StreamableMemoryObject.h (added) >> > +++ llvm/trunk/include/llvm/Support/StreamableMemoryObject.h Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -0,0 +1,181 @@ >> > +//===- StreamableMemoryObject.h - Streamable data interface - -*- C++ >> > -*-===// >> > +// >> > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure >> > +// >> > +// This file is distributed under the University of Illinois Open >> > Source >> > +// License. See LICENSE.TXT for details. >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > + >> > + >> > +#ifndef STREAMABLEMEMORYOBJECT_H_ >> > +#define STREAMABLEMEMORYOBJECT_H_ >> > + >> > +#include "llvm/ADT/OwningPtr.h" >> > +#include "llvm/Support/MemoryObject.h" >> > +#include "llvm/Support/DataStream.h" >> > +#include >> > + >> > +namespace llvm { >> > + >> > +/// StreamableMemoryObject - Interface to data which might be streamed. >> > +/// Streamability has 2 important implications/restrictions. First, the >> > data >> > +/// might not yet exist in memory when the request is made. This just >> > means >> > +/// that readByte/readBytes might have to block or do some work to get >> > it. >> > +/// More significantly, the exact size of the object might not be known >> > until >> > +/// it has all been fetched. This means that to return the right >> > result, >> > +/// getExtent must also wait for all the data to arrive; therefore it >> > should >> > +/// not be called on objects which are actually streamed (this would >> > defeat >> > +/// the purpose of streaming). Instead, isValidAddress and isObjectEnd >> > can be >> > +/// used to test addresses without knowing the exact size of the >> > stream. >> > +/// Finally, getPointer can be used instead of readBytes to avoid extra >> > copying. >> > +class StreamableMemoryObject : public MemoryObject { >> > + public: >> > + ?/// Destructor ? ? ?- Override as necessary. >> > + ?virtual ~StreamableMemoryObject(); >> > + >> > + ?/// getBase ? ? ? ? - Returns the lowest valid address in the region. >> > + ?/// >> > + ?/// @result ? ? ? ? - The lowest valid address. >> > + ?virtual uint64_t getBase() const = 0; >> > + >> > + ?/// getExtent ? ? ? - Returns the size of the region in bytes. ?(The >> > region is >> > + ?/// ? ? ? ? ? ? ? ? ? contiguous, so the highest valid address of the >> > region >> > + ?/// ? ? ? ? ? ? ? ? ? is getBase() + getExtent() - 1). >> > + ?/// ? ? ? ? ? ? ? ? ? May block until all bytes in the stream have >> > been read >> > + ?/// >> > + ?/// @result ? ? ? ? - The size of the region. >> > + ?virtual uint64_t getExtent() = 0; >> > + >> > + ?/// readByte ? ? ? ?- Tries to read a single byte from the region. >> > + ?/// ? ? ? ? ? ? ? ? ? May block until (address - base) bytes have >> > been read >> > + ?/// @param address ?- The address of the byte, in the same space as >> > getBase(). >> > + ?/// @param ptr ? ? ?- A pointer to a byte to be filled in. ?Must be >> > non-NULL. >> > + ?/// @result ? ? ? ? - 0 if successful; -1 if not. ?Failure may be due >> > to a >> > + ?/// ? ? ? ? ? ? ? ? ? bounds violation or an implementation-specific >> > error. >> > + ?virtual int readByte(uint64_t address, uint8_t* ptr) = 0; >> > + >> > + ?/// readBytes ? ? ? - Tries to read a contiguous range of bytes from >> > the >> > + ?/// ? ? ? ? ? ? ? ? ? region, up to the end of the region. >> > + ?/// ? ? ? ? ? ? ? ? ? May block until (address - base + size) bytes >> > have >> > + ?/// ? ? ? ? ? ? ? ? ? been read. Additionally, >> > StreamableMemoryObjects will >> > + ?/// ? ? ? ? ? ? ? ? ? not do partial reads - if size bytes cannot be >> > read, >> > + ?/// ? ? ? ? ? ? ? ? ? readBytes will fail. >> > + ?/// >> > + ?/// @param address ?- The address of the first byte, in the same >> > space as >> > + ?/// ? ? ? ? ? ? ? ? ? getBase(). >> > + ?/// @param size ? ? - The maximum number of bytes to copy. >> > + ?/// @param buf ? ? ?- A pointer to a buffer to be filled in. ?Must be >> > non-NULL >> > + ?/// ? ? ? ? ? ? ? ? ? and large enough to hold size bytes. >> > + ?/// @param copied ? - A pointer to a nunber that is filled in with >> > the number >> > + ?/// ? ? ? ? ? ? ? ? ? of bytes actually read. ?May be NULL. >> > + ?/// @result ? ? ? ? - 0 if successful; -1 if not. ?Failure may be due >> > to a >> > + ?/// ? ? ? ? ? ? ? ? ? bounds violation or an implementation-specific >> > error. >> > + ?virtual int readBytes(uint64_t address, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t size, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint8_t* buf, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied) = 0; >> > + >> > + ?/// getPointer ?- Ensures that the requested data is in memory, and >> > returns >> > + ?/// ? ? ? ? ? ? ? A pointer to it. More efficient than using >> > readBytes if the >> > + ?/// ? ? ? ? ? ? ? data is already in memory. >> > + ?/// ? ? ? ? ? ? ? May block until (address - base + size) bytes have >> > been read >> > + ?/// @param address - address of the byte, in the same space as >> > getBase() >> > + ?/// @param size ? ?- amount of data that must be available on return >> > + ?/// @result ? ? ? ?- valid pointer to the requested data >> > + ?virtual const uint8_t *getPointer(uint64_t address, uint64_t size) = >> > 0; >> > + >> > + ?/// isValidAddress - Returns true if the address is within the object >> > + ?/// ? ? ? ? ? ? ? ? ?(i.e. between base and base + extent - 1 >> > inclusive) >> > + ?/// ? ? ? ? ? ? ? ? ?May block until (address - base) bytes have been >> > read >> > + ?/// @param address - address of the byte, in the same space as >> > getBase() >> > + ?/// @result ? ? ? ?- true if the address may be read with readByte() >> > + ?virtual bool isValidAddress(uint64_t address) = 0; >> > + >> > + ?/// isObjectEnd ? ?- Returns true if the address is one past the end >> > of the >> > + ?/// ? ? ? ? ? ? ? ? ?object (i.e. if it is equal to base + extent) >> > + ?/// ? ? ? ? ? ? ? ? ?May block until (address - base) bytes have been >> > read >> > + ?/// @param address - address of the byte, in the same space as >> > getBase() >> > + ?/// @result ? ? ? ?- true if the address is equal to base + extent >> > + ?virtual bool isObjectEnd(uint64_t address) = 0; >> > +}; >> > + >> > +/// StreamingMemoryObject - interface to data which is actually >> > streamed from >> > +/// a DataStreamer. In addition to inherited members, it has the >> > +/// dropLeadingBytes and setKnownObjectSize methods which are not >> > applicable >> > +/// to non-streamed objects. >> > +class StreamingMemoryObject : public StreamableMemoryObject { >> > +public: >> > + ?StreamingMemoryObject(DataStreamer *streamer); >> > + ?virtual uint64_t getBase() const { return 0; } >> > + ?virtual uint64_t getExtent(); >> > + ?virtual int readByte(uint64_t address, uint8_t* ptr); >> > + ?virtual int readBytes(uint64_t address, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t size, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint8_t* buf, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied); >> > + ?virtual const uint8_t *getPointer(uint64_t address, uint64_t size) { >> > + ? ?// This could be fixed by ensuring the bytes are fetched and making >> > a copy, >> > + ? ?// requiring that the bitcode size be known, or otherwise ensuring >> > that >> > + ? ?// the memory doesn't go away/get reallocated, but it's >> > + ? ?// not currently necessary. Users that need the pointer don't >> > stream. >> > + ? ?assert(0 && "getPointer in streaming memory objects not allowed"); >> > + ? ?return NULL; >> > + ?} >> > + ?virtual bool isValidAddress(uint64_t address); >> > + ?virtual bool isObjectEnd(uint64_t address); >> > + >> > + ?/// Drop s bytes from the front of the stream, pushing the positions >> > of the >> > + ?/// remaining bytes down by s. This is used to skip past the bitcode >> > header, >> > + ?/// since we don't know a priori if it's present, and we can't put >> > bytes >> > + ?/// back into the stream once we've read them. >> > + ?bool dropLeadingBytes(size_t s); >> > + >> > + ?/// If the data object size is known in advance, many of the >> > operations can >> > + ?/// be made more efficient, so this method should be called before >> > reading >> > + ?/// starts (although it can be called anytime). >> > + ?void setKnownObjectSize(size_t size); >> > + >> > +private: >> > + ?const static uint32_t kChunkSize = 4096 * 4; >> > + ?std::vector Bytes; >> > + ?OwningPtr Streamer; >> > + ?size_t BytesRead; ? // Bytes read from stream >> > + ?size_t BytesSkipped;// Bytes skipped at start of stream (e.g. >> > wrapper/header) >> > + ?size_t ObjectSize; // 0 if unknown, set if wrapper was seen or EOF >> > reached >> > + ?bool EOFReached; >> > + >> > + ?// Fetch enough bytes such that Pos can be read or EOF is reached >> > + ?// (i.e. BytesRead > Pos). Return true if Pos can be read. >> > + ?// Unlike most of the functions in BitcodeReader, returns true on >> > success. >> > + ?// Most of the requests will be small, but we fetch at kChunkSize >> > bytes >> > + ?// at a time to avoid making too many potentially expensive GetBytes >> > calls >> > + ?bool fetchToPos(size_t Pos) { >> > + ? ?if (EOFReached) return Pos < ObjectSize; >> > + ? ?while (Pos >= BytesRead) { >> > + ? ? ?Bytes.resize(BytesRead + kChunkSize); >> > + ? ? ?size_t bytes = Streamer->GetBytes(&Bytes[BytesRead + >> > BytesSkipped], >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?kChunkSize); >> > + ? ? ?BytesRead += bytes; >> > + ? ? ?if (bytes < kChunkSize) { >> > + ? ? ? ?if (ObjectSize && BytesRead < Pos) >> > + ? ? ? ? ?assert(0 && "Unexpected short read fetching bitcode"); >> > + ? ? ? ?if (BytesRead <= Pos) { // reached EOF/ran out of bytes >> > + ? ? ? ? ?ObjectSize = BytesRead; >> > + ? ? ? ? ?EOFReached = true; >> > + ? ? ? ? ?return false; >> > + ? ? ? ?} >> > + ? ? ?} >> > + ? ?} >> > + ? ?return true; >> > + ?} >> > + >> > + ?StreamingMemoryObject(const StreamingMemoryObject&); ?// DO NOT >> > IMPLEMENT >> > + ?void operator=(const StreamingMemoryObject&); ?// DO NOT IMPLEMENT >> > +}; >> > + >> > +StreamableMemoryObject *getNonStreamedMemoryObject( >> > + ? ?const unsigned char *Start, const unsigned char *End); >> > + >> > +} >> > +#endif ?// STREAMABLEMEMORYOBJECT_H_ >> > >> > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original) >> > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -22,6 +22,7 @@ >> > #include "llvm/AutoUpgrade.h" >> > #include "llvm/ADT/SmallString.h" >> > #include "llvm/ADT/SmallVector.h" >> > +#include "llvm/Support/DataStream.h" >> > #include "llvm/Support/MathExtras.h" >> > #include "llvm/Support/MemoryBuffer.h" >> > #include "llvm/OperandTraits.h" >> > @@ -1409,8 +1410,36 @@ >> > ? return false; >> > } >> > >> > -bool BitcodeReader::ParseModule() { >> > - ?if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) >> > +bool BitcodeReader::GlobalCleanup() { >> > + ?// Patch the initializers for globals and aliases up. >> > + ?ResolveGlobalAndAliasInits(); >> > + ?if (!GlobalInits.empty() || !AliasInits.empty()) >> > + ? ?return Error("Malformed global initializer set"); >> > + >> > + ?// Look for intrinsic functions which need to be upgraded at some >> > point >> > + ?for (Module::iterator FI = TheModule->begin(), FE = TheModule->end(); >> > + ? ? ? FI != FE; ++FI) { >> > + ? ?Function *NewFn; >> > + ? ?if (UpgradeIntrinsicFunction(FI, NewFn)) >> > + ? ? ?UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); >> > + ?} >> > + >> > + ?// Look for global variables which need to be renamed. >> > + ?for (Module::global_iterator >> > + ? ? ? ? GI = TheModule->global_begin(), GE = TheModule->global_end(); >> > + ? ? ? GI != GE; ++GI) >> > + ? ?UpgradeGlobalVariable(GI); >> > + ?// Force deallocation of memory for these vectors to favor the client >> > that >> > + ?// want lazy deserialization. >> > + ?std::vector >> > >().swap(GlobalInits); >> > + ?std::vector >().swap(AliasInits); >> > + ?return false; >> > +} >> > + >> > +bool BitcodeReader::ParseModule(bool Resume) { >> > + ?if (Resume) >> > + ? ?Stream.JumpToBit(NextUnreadBit); >> > + ?else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) >> > ? ? return Error("Malformed block record"); >> > >> > ? SmallVector Record; >> > @@ -1424,33 +1453,7 @@ >> > ? ? ? if (Stream.ReadBlockEnd()) >> > ? ? ? ? return Error("Error at end of module block"); >> > >> > - ? ? ?// Patch the initializers for globals and aliases up. >> > - ? ? ?ResolveGlobalAndAliasInits(); >> > - ? ? ?if (!GlobalInits.empty() || !AliasInits.empty()) >> > - ? ? ? ?return Error("Malformed global initializer set"); >> > - ? ? ?if (!FunctionsWithBodies.empty()) >> > - ? ? ? ?return Error("Too few function bodies found"); >> > - >> > - ? ? ?// Look for intrinsic functions which need to be upgraded at some >> > point >> > - ? ? ?for (Module::iterator FI = TheModule->begin(), FE = >> > TheModule->end(); >> > - ? ? ? ? ? FI != FE; ++FI) { >> > - ? ? ? ?Function* NewFn; >> > - ? ? ? ?if (UpgradeIntrinsicFunction(FI, NewFn)) >> > - ? ? ? ? ?UpgradedIntrinsics.push_back(std::make_pair(FI, NewFn)); >> > - ? ? ?} >> > - >> > - ? ? ?// Look for global variables which need to be renamed. >> > - ? ? ?for (Module::global_iterator >> > - ? ? ? ? ? ? GI = TheModule->global_begin(), GE = >> > TheModule->global_end(); >> > - ? ? ? ? ? GI != GE; ++GI) >> > - ? ? ? ?UpgradeGlobalVariable(GI); >> > - >> > - ? ? ?// Force deallocation of memory for these vectors to favor the >> > client that >> > - ? ? ?// want lazy deserialization. >> > - ? ? ?std::vector >> > >().swap(GlobalInits); >> > - ? ? ?std::vector >> > >().swap(AliasInits); >> > - ? ? ?std::vector().swap(FunctionsWithBodies); >> > - ? ? ?return false; >> > + ? ? ?return GlobalCleanup(); >> > ? ? } >> > >> > ? ? if (Code == bitc::ENTER_SUBBLOCK) { >> > @@ -1474,6 +1477,7 @@ >> > ? ? ? case bitc::VALUE_SYMTAB_BLOCK_ID: >> > ? ? ? ? if (ParseValueSymbolTable()) >> > ? ? ? ? ? return true; >> > + ? ? ? ?SeenValueSymbolTable = true; >> > ? ? ? ? break; >> > ? ? ? case bitc::CONSTANTS_BLOCK_ID: >> > ? ? ? ? if (ParseConstants() || ResolveGlobalAndAliasInits()) >> > @@ -1486,13 +1490,25 @@ >> > ? ? ? case bitc::FUNCTION_BLOCK_ID: >> > ? ? ? ? // If this is the first function body we've seen, reverse the >> > ? ? ? ? // FunctionsWithBodies list. >> > - ? ? ? ?if (!HasReversedFunctionsWithBodies) { >> > + ? ? ? ?if (!SeenFirstFunctionBody) { >> > ? ? ? ? ? std::reverse(FunctionsWithBodies.begin(), >> > FunctionsWithBodies.end()); >> > - ? ? ? ? ?HasReversedFunctionsWithBodies = true; >> > + ? ? ? ? ?if (GlobalCleanup()) >> > + ? ? ? ? ? ?return true; >> > + ? ? ? ? ?SeenFirstFunctionBody = true; >> > ? ? ? ? } >> > >> > ? ? ? ? if (RememberAndSkipFunctionBody()) >> > ? ? ? ? ? return true; >> > + ? ? ? ?// For streaming bitcode, suspend parsing when we reach the >> > function >> > + ? ? ? ?// bodies. Subsequent materialization calls will resume it when >> > + ? ? ? ?// necessary. For streaming, the function bodies must be at the >> > end of >> > + ? ? ? ?// the bitcode. If the bitcode file is old, the symbol table >> > will be >> > + ? ? ? ?// at the end instead and will not have been seen yet. In this >> > case, >> > + ? ? ? ?// just finish the parse now. >> > + ? ? ? ?if (LazyStreamer && SeenValueSymbolTable) { >> > + ? ? ? ? ?NextUnreadBit = Stream.GetCurrentBitNo(); >> > + ? ? ? ? ?return false; >> > + ? ? ? ?} >> > ? ? ? ? break; >> > ? ? ? case bitc::USELIST_BLOCK_ID: >> > ? ? ? ? if (ParseUseLists()) >> > @@ -1651,8 +1667,10 @@ >> > >> > ? ? ? // If this is a function with a body, remember the prototype we >> > are >> > ? ? ? // creating now, so that we can match up the body with them later. >> > - ? ? ?if (!isProto) >> > + ? ? ?if (!isProto) { >> > ? ? ? ? FunctionsWithBodies.push_back(Func); >> > + ? ? ? ?if (LazyStreamer) DeferredFunctionInfo[Func] = 0; >> > + ? ? ?} >> > ? ? ? break; >> > ? ? } >> > ? ? // ALIAS: [alias type, aliasee val#, linkage] >> > @@ -1691,24 +1709,7 @@ >> > bool BitcodeReader::ParseBitcodeInto(Module *M) { >> > ? TheModule = 0; >> > >> > - ?unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); >> > - ?unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); >> > - >> > - ?if (Buffer->getBufferSize() & 3) { >> > - ? ?if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, >> > BufEnd)) >> > - ? ? ?return Error("Invalid bitcode signature"); >> > - ? ?else >> > - ? ? ?return Error("Bitcode stream should be a multiple of 4 bytes in >> > length"); >> > - ?} >> > - >> > - ?// If we have a wrapper header, parse it and ignore the non-bc file >> > contents. >> > - ?// The magic number is 0x0B17C0DE stored in little endian. >> > - ?if (isBitcodeWrapper(BufPtr, BufEnd)) >> > - ? ?if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) >> > - ? ? ?return Error("Invalid bitcode wrapper header"); >> > - >> > - ?StreamFile.init(BufPtr, BufEnd); >> > - ?Stream.init(StreamFile); >> > + ?if (InitStream()) return true; >> > >> > ? // Sniff for the signature. >> > ? if (Stream.Read(8) != 'B' || >> > @@ -1750,8 +1751,9 @@ >> > ? ? ? if (TheModule) >> > ? ? ? ? return Error("Multiple MODULE_BLOCKs in same stream"); >> > ? ? ? TheModule = M; >> > - ? ? ?if (ParseModule()) >> > + ? ? ?if (ParseModule(false)) >> > ? ? ? ? return true; >> > + ? ? ?if (LazyStreamer) return false; >> > ? ? ? break; >> > ? ? default: >> > ? ? ? if (Stream.SkipBlock()) >> > @@ -1819,20 +1821,7 @@ >> > } >> > >> > bool BitcodeReader::ParseTriple(std::string &Triple) { >> > - ?if (Buffer->getBufferSize() & 3) >> > - ? ?return Error("Bitcode stream should be a multiple of 4 bytes in >> > length"); >> > - >> > - ?unsigned char *BufPtr = (unsigned char *)Buffer->getBufferStart(); >> > - ?unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); >> > - >> > - ?// If we have a wrapper header, parse it and ignore the non-bc file >> > contents. >> > - ?// The magic number is 0x0B17C0DE stored in little endian. >> > - ?if (isBitcodeWrapper(BufPtr, BufEnd)) >> > - ? ?if (SkipBitcodeWrapperHeader(BufPtr, BufEnd)) >> > - ? ? ?return Error("Invalid bitcode wrapper header"); >> > - >> > - ?StreamFile.init(BufPtr, BufEnd); >> > - ?Stream.init(StreamFile); >> > + ?if (InitStream()) return true; >> > >> > ? // Sniff for the signature. >> > ? if (Stream.Read(8) != 'B' || >> > @@ -2708,6 +2697,19 @@ >> > ? return false; >> > } >> > >> > +/// FindFunctionInStream - Find the function body in the bitcode stream >> > +bool BitcodeReader::FindFunctionInStream(Function *F, >> > + ? ? ? DenseMap::iterator >> > DeferredFunctionInfoIterator) { >> > + ?while (DeferredFunctionInfoIterator->second == 0) { >> > + ? ?if (Stream.AtEndOfStream()) >> > + ? ? ?return Error("Could not find Function in stream"); >> > + ? ?// ParseModule will parse the next body in the stream and set its >> > + ? ?// position in the DeferredFunctionInfo map. >> > + ? ?if (ParseModule(true)) return true; >> > + ?} >> > + ?return false; >> > +} >> > + >> > >> > //===----------------------------------------------------------------------===// >> > // GVMaterializer implementation >> > >> > //===----------------------------------------------------------------------===// >> > @@ -2728,6 +2730,10 @@ >> > >> > ? DenseMap::iterator DFII = >> > DeferredFunctionInfo.find(F); >> > ? assert(DFII != DeferredFunctionInfo.end() && "Deferred function not >> > found!"); >> > + ?// If its position is recorded as 0, its body is somewhere in the >> > stream >> > + ?// but we haven't seen it yet. >> > + ?if (DFII->second == 0) >> > + ? ?if (LazyStreamer && FindFunctionInStream(F, DFII)) return true; >> > >> > ? // Move the bit stream to the saved position of the deferred function >> > body. >> > ? Stream.JumpToBit(DFII->second); >> > @@ -2805,6 +2811,57 @@ >> > ? return false; >> > } >> > >> > +bool BitcodeReader::InitStream() { >> > + ?if (LazyStreamer) return InitLazyStream(); >> > + ?return InitStreamFromBuffer(); >> > +} >> > + >> > +bool BitcodeReader::InitStreamFromBuffer() { >> > + ?const unsigned char *BufPtr = (unsigned char >> > *)Buffer->getBufferStart(); >> > + ?const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); >> > + >> > + ?if (Buffer->getBufferSize() & 3) { >> > + ? ?if (!isRawBitcode(BufPtr, BufEnd) && !isBitcodeWrapper(BufPtr, >> > BufEnd)) >> > + ? ? ?return Error("Invalid bitcode signature"); >> > + ? ?else >> > + ? ? ?return Error("Bitcode stream should be a multiple of 4 bytes in >> > length"); >> > + ?} >> > + >> > + ?// If we have a wrapper header, parse it and ignore the non-bc file >> > contents. >> > + ?// The magic number is 0x0B17C0DE stored in little endian. >> > + ?if (isBitcodeWrapper(BufPtr, BufEnd)) >> > + ? ?if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) >> > + ? ? ?return Error("Invalid bitcode wrapper header"); >> > + >> > + ?StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); >> > + ?Stream.init(*StreamFile); >> > + >> > + ?return false; >> > +} >> > + >> > +bool BitcodeReader::InitLazyStream() { >> > + ?// Check and strip off the bitcode wrapper; BitstreamReader expects >> > never to >> > + ?// see it. >> > + ?StreamingMemoryObject *Bytes = new >> > StreamingMemoryObject(LazyStreamer); >> > + ?StreamFile.reset(new BitstreamReader(Bytes)); >> > + ?Stream.init(*StreamFile); >> > + >> > + ?unsigned char buf[16]; >> > + ?if (Bytes->readBytes(0, 16, buf, NULL) == -1) >> > + ? ?return Error("Bitcode stream must be at least 16 bytes in length"); >> > + >> > + ?if (!isBitcode(buf, buf + 16)) >> > + ? ?return Error("Invalid bitcode signature"); >> > + >> > + ?if (isBitcodeWrapper(buf, buf + 4)) { >> > + ? ?const unsigned char *bitcodeStart = buf; >> > + ? ?const unsigned char *bitcodeEnd = buf + 16; >> > + ? ?SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); >> > + ? ?Bytes->dropLeadingBytes(bitcodeStart - buf); >> > + ? ?Bytes->setKnownObjectSize(bitcodeEnd - bitcodeStart); >> > + ?} >> > + ?return false; >> > +} >> > >> > >> > //===----------------------------------------------------------------------===// >> > // External interface >> > @@ -2833,6 +2890,24 @@ >> > ? return M; >> > } >> > >> > + >> > +Module *llvm::getStreamedBitcodeModule(const std::string &name, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? DataStreamer *streamer, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LLVMContext &Context, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? std::string *ErrMsg) { >> > + ?Module *M = new Module(name, Context); >> > + ?BitcodeReader *R = new BitcodeReader(streamer, Context); >> > + ?M->setMaterializer(R); >> > + ?if (R->ParseBitcodeInto(M)) { >> > + ? ?if (ErrMsg) >> > + ? ? ?*ErrMsg = R->getErrorString(); >> > + ? ?delete M; ?// Also deletes R. >> > + ? ?return 0; >> > + ?} >> > + ?R->setBufferOwned(false); // no buffer to delete >> > + ?return M; >> > +} >> > + >> > /// ParseBitcodeFile - Read the specified bitcode file, returning the >> > module. >> > /// If an error occurs, return null and fill in *ErrMsg if non-null. >> > Module *llvm::ParseBitcodeFile(MemoryBuffer *Buffer, LLVMContext& >> > Context, >> > >> > Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h (original) >> > +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.h Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -126,8 +126,11 @@ >> > ? Module *TheModule; >> > ? MemoryBuffer *Buffer; >> > ? bool BufferOwned; >> > - ?BitstreamReader StreamFile; >> > + ?OwningPtr StreamFile; >> > ? BitstreamCursor Stream; >> > + ?DataStreamer *LazyStreamer; >> > + ?uint64_t NextUnreadBit; >> > + ?bool SeenValueSymbolTable; >> > >> > ? const char *ErrorString; >> > >> > @@ -161,9 +164,10 @@ >> > ? // Map the bitcode's custom MDKind ID to the Module's MDKind ID. >> > ? DenseMap MDKindMap; >> > >> > - ?// After the module header has been read, the FunctionsWithBodies >> > list is >> > - ?// reversed. ?This keeps track of whether we've done this yet. >> > - ?bool HasReversedFunctionsWithBodies; >> > + ?// Several operations happen after the module header has been read, >> > but >> > + ?// before function bodies are processed. This keeps track of whether >> > + ?// we've done this yet. >> > + ?bool SeenFirstFunctionBody; >> > >> > ? /// DeferredFunctionInfo - When function bodies are initially scanned, >> > this >> > ? /// map contains info about where to find deferred function body in >> > the >> > @@ -178,8 +182,13 @@ >> > public: >> > ? explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext &C) >> > ? ? : Context(C), TheModule(0), Buffer(buffer), BufferOwned(false), >> > - ? ? ?ErrorString(0), ValueList(C), MDValueList(C) { >> > - ? ?HasReversedFunctionsWithBodies = false; >> > + ? ? ?LazyStreamer(0), SeenValueSymbolTable(false), ErrorString(0), >> > + ? ? ?ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { >> > + ?} >> > + ?explicit BitcodeReader(DataStreamer *streamer, LLVMContext &C) >> > + ? ?: Context(C), TheModule(0), Buffer(0), BufferOwned(false), >> > + ? ? ?LazyStreamer(streamer), SeenValueSymbolTable(false), >> > ErrorString(0), >> > + ? ? ?ValueList(C), MDValueList(C), SeenFirstFunctionBody(false) { >> > ? } >> > ? ~BitcodeReader() { >> > ? ? FreeState(); >> > @@ -258,7 +267,7 @@ >> > ? } >> > >> > >> > - ?bool ParseModule(); >> > + ?bool ParseModule(bool Resume); >> > ? bool ParseAttributeBlock(); >> > ? bool ParseTypeTable(); >> > ? bool ParseTypeTableBody(); >> > @@ -267,11 +276,17 @@ >> > ? bool ParseConstants(); >> > ? bool RememberAndSkipFunctionBody(); >> > ? bool ParseFunctionBody(Function *F); >> > + ?bool GlobalCleanup(); >> > ? bool ResolveGlobalAndAliasInits(); >> > ? bool ParseMetadata(); >> > ? bool ParseMetadataAttachment(); >> > ? bool ParseModuleTriple(std::string &Triple); >> > ? bool ParseUseLists(); >> > + ?bool InitStream(); >> > + ?bool InitStreamFromBuffer(); >> > + ?bool InitLazyStream(); >> > + ?bool FindFunctionInStream(Function *F, >> > + ? ? ? ? DenseMap::iterator >> > DeferredFunctionInfoIterator); >> > }; >> > >> > } // End llvm namespace >> > >> > Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original) >> > +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -1738,11 +1738,6 @@ >> > ? // Emit metadata. >> > ? WriteModuleMetadata(M, VE, Stream); >> > >> > - ?// Emit function bodies. >> > - ?for (Module::const_iterator F = M->begin(), E = M->end(); F != E; >> > ++F) >> > - ? ?if (!F->isDeclaration()) >> > - ? ? ?WriteFunction(*F, VE, Stream); >> > - >> > ? // Emit metadata. >> > ? WriteModuleMetadataStore(M, Stream); >> > >> > @@ -1753,6 +1748,11 @@ >> > ? if (EnablePreserveUseListOrdering) >> > ? ? WriteModuleUseLists(M, VE, Stream); >> > >> > + ?// Emit function bodies. >> > + ?for (Module::const_iterator F = M->begin(), E = M->end(); F != E; >> > ++F) >> > + ? ?if (!F->isDeclaration()) >> > + ? ? ?WriteFunction(*F, VE, Stream); >> > + >> > ? Stream.ExitBlock(); >> > } >> > >> > >> > Modified: llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp (original) >> > +++ llvm/trunk/lib/MC/MCDisassembler/Disassembler.cpp Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -100,9 +100,9 @@ >> > ? ? ? ? ? ? ? ? ? ? ?Bytes(bytes), Size(size), BasePC(basePC) {} >> > >> > ? uint64_t getBase() const { return BasePC; } >> > - ?uint64_t getExtent() const { return Size; } >> > + ?uint64_t getExtent() { return Size; } >> > >> > - ?int readByte(uint64_t Addr, uint8_t *Byte) const { >> > + ?int readByte(uint64_t Addr, uint8_t *Byte) { >> > ? ? if (Addr - BasePC >= Size) >> > ? ? ? return -1; >> > ? ? *Byte = Bytes[Addr - BasePC]; >> > >> > Modified: llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp (original) >> > +++ llvm/trunk/lib/MC/MCDisassembler/EDDisassembler.cpp Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -207,8 +207,8 @@ >> > ? ? ? ? ? ? ? ? ? ?void *arg) : Callback(callback), Arg(arg) { } >> > ? ? ~EDMemoryObject() { } >> > ? ? uint64_t getBase() const { return 0x0; } >> > - ? ?uint64_t getExtent() const { return (uint64_t)-1; } >> > - ? ?int readByte(uint64_t address, uint8_t *ptr) const { >> > + ? ?uint64_t getExtent() { return (uint64_t)-1; } >> > + ? ?int readByte(uint64_t address, uint8_t *ptr) { >> > ? ? ? if (!Callback) >> > ? ? ? ? return -1; >> > >> > >> > Modified: llvm/trunk/lib/Support/CMakeLists.txt >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Support/CMakeLists.txt (original) >> > +++ llvm/trunk/lib/Support/CMakeLists.txt Mon Feb ?6 16:30:29 2012 >> > @@ -16,6 +16,7 @@ >> > ? ConstantRange.cpp >> > ? CrashRecoveryContext.cpp >> > ? DataExtractor.cpp >> > + ?DataStream.cpp >> > ? Debug.cpp >> > ? DeltaAlgorithm.cpp >> > ? DAGDeltaAlgorithm.cpp >> > @@ -42,6 +43,7 @@ >> > ? SmallVector.cpp >> > ? SourceMgr.cpp >> > ? Statistic.cpp >> > + ?StreamableMemoryObject.cpp >> > ? StringExtras.cpp >> > ? StringMap.cpp >> > ? StringPool.cpp >> > >> > Added: llvm/trunk/lib/Support/DataStream.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=149918&view=auto >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Support/DataStream.cpp (added) >> > +++ llvm/trunk/lib/Support/DataStream.cpp Mon Feb ?6 16:30:29 2012 >> > @@ -0,0 +1,96 @@ >> > +//===--- llvm/Support/DataStream.cpp - Lazy streamed Data >> > ---===// >> > +// >> > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure >> > +// >> > +// This file is distributed under the University of Illinois Open >> > Source >> > +// License. See LICENSE.TXT for details. >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > +// >> > +// This file implements DataStreamer, which fetches bytes of Data from >> > +// a stream source. It provides support for streaming (lazy reading) of >> > +// bitcode. An example implementation of streaming from a file or stdin >> > +// is included. >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > + >> > +#define DEBUG_TYPE "Data-stream" >> > +#include "llvm/ADT/Statistic.h" >> > +#include "llvm/Support/DataStream.h" >> > +#include "llvm/Support/system_error.h" >> > +#include >> > +#include >> > +#include >> > +#if !defined(_MSC_VER) && !defined(__MINGW32__) >> > +#include >> > +#else >> > +#include >> > +#endif >> > +#include >> > +using namespace llvm; >> > + >> > +// Interface goals: >> > +// * StreamableMemoryObject doesn't care about complexities like using >> > +// ? threads/async callbacks to actually overlap download+compile >> > +// * Don't want to duplicate Data in memory >> > +// * Don't need to know total Data len in advance >> > +// Non-goals: >> > +// StreamableMemoryObject already has random access so this interface >> > only does >> > +// in-order streaming (no arbitrary seeking, else we'd have to buffer >> > all the >> > +// Data here in addition to MemoryObject). ?This also means that if we >> > want >> > +// to be able to to free Data, BitstreamBytes/BitcodeReader will >> > implement it >> > + >> > +STATISTIC(NumStreamFetches, "Number of calls to Data stream fetch"); >> > + >> > +namespace llvm { >> > +DataStreamer::~DataStreamer() {} >> > +} >> > + >> > +namespace { >> > + >> > +const static error_code success; >> > + >> > +// Very simple stream backed by a file. Mostly useful for stdin and >> > debugging; >> > +// actual file access is probably still best done with mmap. >> > +class DataFileStreamer : public DataStreamer { >> > + int Fd; >> > +public: >> > + ?DataFileStreamer() : Fd(0) {} >> > + ?virtual ~DataFileStreamer() { >> > + ? ?close(Fd); >> > + ?} >> > + ?virtual size_t GetBytes(unsigned char *buf, size_t len) { >> > + ? ?NumStreamFetches++; >> > + ? ?return read(Fd, buf, len); >> > + ?} >> > + >> > + ?error_code OpenFile(const std::string &Filename) { >> > + ? ?int OpenFlags = O_RDONLY; >> > +#ifdef O_BINARY >> > + ? ?OpenFlags |= O_BINARY; ?// Open input file in binary mode on win32. >> > +#endif >> > + ? ?if (Filename == "-") >> > + ? ? ?Fd = 0; >> > + ? ?else >> > + ? ? ?Fd = ::open(Filename.c_str(), OpenFlags); >> > + ? ?if (Fd == -1) return error_code(errno, posix_category()); >> > + ? ? ?return success; >> > + ?} >> > +}; >> > + >> > +} >> > + >> > +namespace llvm { >> > +DataStreamer *getDataFileStreamer(const std::string &Filename, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?std::string *StrError) { >> > + ?DataFileStreamer *s = new DataFileStreamer(); >> > + ?error_code e = s->OpenFile(Filename); >> > + ?if (e != success) { >> > + ? ?*StrError = std::string("Could not open ") + Filename + ": " + >> > + ? ? ? ?e.message() + "\n"; >> > + ? ?return NULL; >> > + ?} >> > + ?return s; >> > +} >> > + >> > +} >> > >> > Modified: llvm/trunk/lib/Support/MemoryObject.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryObject.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Support/MemoryObject.cpp (original) >> > +++ llvm/trunk/lib/Support/MemoryObject.cpp Mon Feb ?6 16:30:29 2012 >> > @@ -16,7 +16,7 @@ >> > int MemoryObject::readBytes(uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t size, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t* buf, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied) const { >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied) { >> > ? uint64_t current = address; >> > ? uint64_t limit = getBase() + getExtent(); >> > >> > >> > Added: llvm/trunk/lib/Support/StreamableMemoryObject.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StreamableMemoryObject.cpp?rev=149918&view=auto >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Support/StreamableMemoryObject.cpp (added) >> > +++ llvm/trunk/lib/Support/StreamableMemoryObject.cpp Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -0,0 +1,137 @@ >> > +//===- StreamableMemoryObject.cpp - Streamable data interface - -*- C++ >> > -*-===// >> > +// >> > +// ? ? ? ? ? ? ? ? ? ? The LLVM Compiler Infrastructure >> > +// >> > +// This file is distributed under the University of Illinois Open >> > Source >> > +// License. See LICENSE.TXT for details. >> > +// >> > >> > +//===----------------------------------------------------------------------===// >> > + >> > +#include "llvm/Support/StreamableMemoryObject.h" >> > +#include >> > +#include >> > + >> > + >> > +using namespace llvm; >> > + >> > +namespace { >> > + >> > +class RawMemoryObject : public StreamableMemoryObject { >> > +public: >> > + ?RawMemoryObject(const unsigned char *Start, const unsigned char *End) >> > : >> > + ? ?FirstChar(Start), LastChar(End) { >> > + ? ?assert(LastChar > FirstChar && "Invalid start/end range"); >> > + ?} >> > + >> > + ?virtual uint64_t getBase() const { return 0; } >> > + ?virtual uint64_t getExtent() { return LastChar - FirstChar; } >> > + ?virtual int readByte(uint64_t address, uint8_t* ptr); >> > + ?virtual int readBytes(uint64_t address, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t size, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint8_t* buf, >> > + ? ? ? ? ? ? ? ? ? ? ? ?uint64_t* copied); >> > + ?virtual const uint8_t *getPointer(uint64_t address, uint64_t size); >> > + ?virtual bool isValidAddress(uint64_t address) {return >> > validAddress(address);} >> > + ?virtual bool isObjectEnd(uint64_t address) {return >> > objectEnd(address);} >> > + >> > +private: >> > + ?const uint8_t* const FirstChar; >> > + ?const uint8_t* const LastChar; >> > + >> > + ?// These are implemented as inline functions here to avoid multiple >> > virtual >> > + ?// calls per public function >> > + ?bool validAddress(uint64_t address) { >> > + ? ?return static_cast(address) < LastChar - FirstChar; >> > + ?} >> > + ?bool objectEnd(uint64_t address) { >> > + ? ?return static_cast(address) == LastChar - FirstChar; >> > + ?} >> > + >> > + ?RawMemoryObject(const RawMemoryObject&); ?// DO NOT IMPLEMENT >> > + ?void operator=(const RawMemoryObject&); ?// DO NOT IMPLEMENT >> > +}; >> > + >> > +int RawMemoryObject::readByte(uint64_t address, uint8_t* ptr) { >> > + ?if (!validAddress(address)) return -1; >> > + ?*ptr = *((uint8_t *)(uintptr_t)(address + FirstChar)); >> > + ?return 0; >> > +} >> > + >> > +int RawMemoryObject::readBytes(uint64_t address, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t size, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t* buf, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t* copied) { >> > + ?if (!validAddress(address) || !validAddress(address + size - 1)) >> > return -1; >> > + ?memcpy(buf, (uint8_t *)(uintptr_t)(address + FirstChar), size); >> > + ?if (copied) *copied = size; >> > + ?return size; >> > +} >> > + >> > +const uint8_t *RawMemoryObject::getPointer(uint64_t address, uint64_t >> > size) { >> > + ?return FirstChar + address; >> > +} >> > +} // anonymous namespace >> > + >> > +namespace llvm { >> > +// If the bitcode has a header, then its size is known, and we don't >> > have to >> > +// block until we actually want to read it. >> > +bool StreamingMemoryObject::isValidAddress(uint64_t address) { >> > + ?if (ObjectSize && address < ObjectSize) return true; >> > + ? ?return fetchToPos(address); >> > +} >> > + >> > +bool StreamingMemoryObject::isObjectEnd(uint64_t address) { >> > + ?if (ObjectSize) return address == ObjectSize; >> > + ?fetchToPos(address); >> > + ?return address == ObjectSize && address != 0; >> > +} >> > + >> > +uint64_t StreamingMemoryObject::getExtent() { >> > + ?if (ObjectSize) return ObjectSize; >> > + ?size_t pos = BytesRead + kChunkSize; >> > + ?// keep fetching until we run out of bytes >> > + ?while (fetchToPos(pos)) pos += kChunkSize; >> > + ?return ObjectSize; >> > +} >> > + >> > +int StreamingMemoryObject::readByte(uint64_t address, uint8_t* ptr) { >> > + ?if (!fetchToPos(address)) return -1; >> > + ?*ptr = Bytes[address + BytesSkipped]; >> > + ?return 0; >> > +} >> > + >> > +int StreamingMemoryObject::readBytes(uint64_t address, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t size, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint8_t* buf, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t* copied) { >> > + ?if (!fetchToPos(address + size - 1)) return -1; >> > + ?memcpy(buf, &Bytes[address + BytesSkipped], size); >> > + ?if (copied) *copied = size; >> > + ?return 0; >> > +} >> > + >> > +bool StreamingMemoryObject::dropLeadingBytes(size_t s) { >> > + ?if (BytesRead < s) return true; >> > + ?BytesSkipped = s; >> > + ?BytesRead -= s; >> > + ?return false; >> > +} >> > + >> > +void StreamingMemoryObject::setKnownObjectSize(size_t size) { >> > + ?ObjectSize = size; >> > + ?Bytes.reserve(size); >> > +} >> > + >> > +StreamableMemoryObject *getNonStreamedMemoryObject( >> > + ? ?const unsigned char *Start, const unsigned char *End) { >> > + ?return new RawMemoryObject(Start, End); >> > +} >> > + >> > +StreamableMemoryObject::~StreamableMemoryObject() { } >> > + >> > +StreamingMemoryObject::StreamingMemoryObject(DataStreamer *streamer) : >> > + ?Bytes(kChunkSize), Streamer(streamer), BytesRead(0), BytesSkipped(0), >> > + ?ObjectSize(0), EOFReached(false) { >> > + ?BytesRead = streamer->GetBytes(&Bytes[0], kChunkSize); >> > +} >> > +} >> > >> > Modified: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp >> > (original) >> > +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp Mon Feb >> > ?6 16:30:29 2012 >> > @@ -46,7 +46,7 @@ >> > ? /// getInstruction - See MCDisassembler. >> > ? DecodeStatus getInstruction(MCInst &instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &cStream) const; >> > @@ -71,7 +71,7 @@ >> > ? /// getInstruction - See MCDisassembler. >> > ? DecodeStatus getInstruction(MCInst &instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &cStream) const; >> > @@ -341,7 +341,7 @@ >> > } >> > >> > DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MemoryObject >> > &Region, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MemoryObject &Region, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t Address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &os, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &cs) const { >> > @@ -691,7 +691,7 @@ >> > } >> > >> > DecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t >> > &Size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MemoryObject >> > &Region, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MemoryObject &Region, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t Address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &os, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &cs) const { >> > >> > Modified: >> > llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp >> > (original) >> > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.cpp Mon >> > Feb ?6 16:30:29 2012 >> > @@ -502,7 +502,7 @@ >> > >> > MCDisassembler::DecodeStatus MBlazeDisassembler::getInstruction(MCInst >> > &instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &cStream) const { >> > >> > Modified: llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h >> > (original) >> > +++ llvm/trunk/lib/Target/MBlaze/Disassembler/MBlazeDisassembler.h Mon >> > Feb ?6 16:30:29 2012 >> > @@ -40,7 +40,7 @@ >> > ? /// getInstruction - See MCDisassembler. >> > ? MCDisassembler::DecodeStatus getInstruction(MCInst &instr, >> > ? ? ? ? ? ? ? ? ? ? ? uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ?const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ?MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? raw_ostream &cStream) const; >> > >> > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp >> > (original) >> > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.cpp Mon Feb >> > ?6 16:30:29 2012 >> > @@ -112,7 +112,7 @@ >> > MCDisassembler::DecodeStatus >> > X86GenericDisassembler::getInstruction(MCInst &instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &cStream) const { >> > >> > Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) >> > +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -114,7 +114,7 @@ >> > ? /// getInstruction - See MCDisassembler. >> > ? DecodeStatus getInstruction(MCInst &instr, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t &size, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const MemoryObject ®ion, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?MemoryObject ®ion, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uint64_t address, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &vStream, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? raw_ostream &cStream) const; >> > >> > Modified: llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp (original) >> > +++ llvm/trunk/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp Mon Feb ?6 >> > 16:30:29 2012 >> > @@ -483,13 +483,13 @@ >> > ? if (MemBuf->getBufferSize() & 3) >> > ? ? return Error("Bitcode stream should be a multiple of 4 bytes in >> > length"); >> > >> > - ?unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); >> > - ?unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); >> > + ?const unsigned char *BufPtr = (unsigned char >> > *)MemBuf->getBufferStart(); >> > + ?const unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); >> > >> > ? // If we have a wrapper header, parse it and ignore the non-bc file >> > contents. >> > ? // The magic number is 0x0B17C0DE stored in little endian. >> > ? if (isBitcodeWrapper(BufPtr, EndBufPtr)) >> > - ? ?if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) >> > + ? ?if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr, true)) >> > ? ? ? return Error("Invalid bitcode wrapper header"); >> > >> > ? BitstreamReader StreamFile(BufPtr, EndBufPtr); >> > >> > Modified: llvm/trunk/tools/llvm-dis/llvm-dis.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-dis/llvm-dis.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-dis/llvm-dis.cpp (original) >> > +++ llvm/trunk/tools/llvm-dis/llvm-dis.cpp Mon Feb ?6 16:30:29 2012 >> > @@ -24,6 +24,7 @@ >> > #include "llvm/Analysis/DebugInfo.h" >> > #include "llvm/Assembly/AssemblyAnnotationWriter.h" >> > #include "llvm/Support/CommandLine.h" >> > +#include "llvm/Support/DataStream.h" >> > #include "llvm/Support/FormattedStream.h" >> > #include "llvm/Support/ManagedStatic.h" >> > #include "llvm/Support/MemoryBuffer.h" >> > @@ -126,12 +127,19 @@ >> > ? std::string ErrorMessage; >> > ? std::auto_ptr M; >> > >> > - ?{ >> > - ? ?OwningPtr BufferPtr; >> > - ? ?if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, >> > BufferPtr)) >> > - ? ? ?ErrorMessage = ec.message(); >> > + ?// Use the bitcode streaming interface >> > + ?DataStreamer *streamer = getDataFileStreamer(InputFilename, >> > &ErrorMessage); >> > + ?if (streamer) { >> > + ? ?std::string DisplayFilename; >> > + ? ?if (InputFilename == "-") >> > + ? ? ?DisplayFilename = ""; >> > ? ? else >> > - ? ? ?M.reset(ParseBitcodeFile(BufferPtr.get(), Context, >> > &ErrorMessage)); >> > + ? ? ?DisplayFilename = InputFilename; >> > + ? ?M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, >> > Context, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? &ErrorMessage)); >> > + ? ?if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { >> > + ? ? ?M.reset(); >> > + ? ?} >> > ? } >> > >> > ? if (M.get() == 0) { >> > @@ -183,4 +191,3 @@ >> > >> > ? return 0; >> > } >> > - >> > >> > Modified: llvm/trunk/tools/llvm-mc/Disassembler.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/Disassembler.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-mc/Disassembler.cpp (original) >> > +++ llvm/trunk/tools/llvm-mc/Disassembler.cpp Mon Feb ?6 16:30:29 2012 >> > @@ -42,9 +42,9 @@ >> > ? VectorMemoryObject(const ByteArrayTy &bytes) : Bytes(bytes) {} >> > >> > ? uint64_t getBase() const { return 0; } >> > - ?uint64_t getExtent() const { return Bytes.size(); } >> > + ?uint64_t getExtent() { return Bytes.size(); } >> > >> > - ?int readByte(uint64_t Addr, uint8_t *Byte) const { >> > + ?int readByte(uint64_t Addr, uint8_t *Byte) { >> > ? ? if (Addr >= getExtent()) >> > ? ? ? return -1; >> > ? ? *Byte = Bytes[Addr].first; >> > >> > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.cpp >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.cpp?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-objdump/MCFunction.cpp (original) >> > +++ llvm/trunk/tools/llvm-objdump/MCFunction.cpp Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -28,7 +28,7 @@ >> > >> > MCFunction >> > MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler >> > *DisAsm, >> > - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const MemoryObject &Region, uint64_t >> > Start, >> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MemoryObject &Region, uint64_t Start, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?uint64_t End, const MCInstrAnalysis >> > *Ana, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?raw_ostream &DebugOut, >> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SmallVectorImpl &Calls) { >> > >> > Modified: llvm/trunk/tools/llvm-objdump/MCFunction.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/MCFunction.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-objdump/MCFunction.h (original) >> > +++ llvm/trunk/tools/llvm-objdump/MCFunction.h Mon Feb ?6 16:30:29 2012 >> > @@ -79,7 +79,7 @@ >> > ? // Create an MCFunction from a region of binary machine code. >> > ? static MCFunction >> > ? createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm, >> > - ? ? ? ? ? ? ? ? ? ? ? const MemoryObject &Region, uint64_t Start, >> > uint64_t End, >> > + ? ? ? ? ? ? ? ? ? ? ? MemoryObject &Region, uint64_t Start, uint64_t >> > End, >> > ? ? ? ? ? ? ? ? ? ? ? ?const MCInstrAnalysis *Ana, raw_ostream >> > &DebugOut, >> > ? ? ? ? ? ? ? ? ? ? ? ?SmallVectorImpl &Calls); >> > >> > >> > Modified: llvm/trunk/tools/llvm-objdump/llvm-objdump.h >> > URL: >> > http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objdump/llvm-objdump.h?rev=149918&r1=149917&r2=149918&view=diff >> > >> > ============================================================================== >> > --- llvm/trunk/tools/llvm-objdump/llvm-objdump.h (original) >> > +++ llvm/trunk/tools/llvm-objdump/llvm-objdump.h Mon Feb ?6 16:30:29 >> > 2012 >> > @@ -31,9 +31,9 @@ >> > ? StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {} >> > >> > ? uint64_t getBase() const { return 0; } >> > - ?uint64_t getExtent() const { return Bytes.size(); } >> > + ?uint64_t getExtent() { return Bytes.size(); } >> > >> > - ?int readByte(uint64_t Addr, uint8_t *Byte) const { >> > + ?int readByte(uint64_t Addr, uint8_t *Byte) { >> > ? ? if (Addr >= getExtent()) >> > ? ? ? return -1; >> > ? ? *Byte = Bytes[Addr]; >> > >> > >> > _______________________________________________ >> > llvm-commits mailing list >> > llvm-commits at cs.uiuc.edu >> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From kcc at google.com Tue Feb 7 14:40:44 2012 From: kcc at google.com (Kostya Serebryany) Date: Tue, 7 Feb 2012 12:40:44 -0800 Subject: [llvm-commits] ThreadSanitizer, first patch. Please review. In-Reply-To: References: Message-ID: On Mon, Feb 6, 2012 at 7:35 PM, Nick Lewycky wrote: > On 6 February 2012 19:10, Kostya Serebryany wrote: > >> Thanks for the review! >> Please take another look. >> > > Wrong patch attached? > > >> >> On Mon, Feb 6, 2012 at 2:35 PM, Nick Lewycky wrote: >> >>> On 30 January 2012 09:45, Kostya Serebryany wrote: >>> >>>> Any feedback? >>> >>> >>> --- test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) >>> +++ test/Instrumentation/ThreadSanitizer/tsan_basic.ll (revision 0) >>> @@ -0,0 +1,17 @@ >>> +; RUN: opt < %s -tsan -S | FileCheck %s >>> + >>> +target datalayout = >>> "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" >>> +target triple = "x86_64-unknown-linux-gnu" >>> + >>> +define i32 @read_4_bytes(i32* %a) { >>> +entry: >>> + %tmp1 = load i32* %a, align 4 >>> + ret i32 %tmp1 >>> +} >>> +; CHECK: @read_4_bytes >>> +; CHECK-NOT: ret i32 >>> +; CHECK: __tsan_func_entry >>> +; CHECK: __tsan_read4 >>> +; CHECK: __tsan_func_exit >>> +; CHECK: ret i32 >>> +; CHECK: __tsan_init >>> >>> I'm not a fan of this pile of CHECK statements. You could actually write >>> out the IR that you expect to get out and preserve the order using >>> CHECK-NEXT. Even if you don't want the matches to be too specific, it would >>> still be clearer to see "CHECK-NEXT: call {{.*}} @__tsan_func_entry". >>> >> done >> >> >>> >>> Index: lib/Transforms/Instrumentation/ThreadSanitizer.cpp >>> =================================================================== >>> --- lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) >>> +++ lib/Transforms/Instrumentation/ThreadSanitizer.cpp (revision 0) >>> @@ -0,0 +1,149 @@ >>> +//===-- ThreadSanitizer.cpp - race detector ---------------------*- C++ >>> -*-===// >>> >>> Hey hey, this ruler is 81 characters long. :) >>> >> >> Hm? My editor says 80 (81 counting the '+' in the patch). >> > > Sorry, false alarm. (Not sure how that happened; my editor said "82", but > I wasn't using my usual editor at the time.) > > >> >> >> >>> >>> +bool ThreadSanitizer::runOnModule(Module &M) { >>> + bool Res = false; >>> + CurrentModule = &M; >>> + TD = getAnalysisIfAvailable(); >>> + if (!TD) >>> + return false; >>> + >>> + for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) { >>> + if (F->isDeclaration()) continue; >>> + Res |= handleFunction(M, *F); >>> + } >>> + // We instrumented at least one function. Insert a call to >>> __tsan_init(). >>> + if (Res) { >>> + IRBuilder<> IRB(M.getContext()); >>> + Value *TsanInit = M.getOrInsertFunction("__tsan_init", >>> + IRB.getVoidTy(), NULL); >>> + appendToGlobalCtors(M, cast(TsanInit), 0); >>> + } >>> + return Res; >>> +} >>> >>> You could write this as a FunctionPass; create the __tsan_... methods in >>> doInitialization() (and store the necessary pointers in your object so that >>> you needn't look them up each time you instrument a function), then do the >>> instrumentation per-function, then in doFinalization either add the call to >>> __tsan_init or clean up declarations you created in doInitialization(). >>> >> >> Rewrote to use FunctionPass. >> However I have questions: >> - Suppose I want to count the number of transformed instructions >> in runOnFunction and store the result in the ThreadSanitizer object. Do I >> need to use locking or atomics (OMG)? >> > > Yes, you would. > > >> - You suggest to call M->getOrInsertFunction in doInitialization. Bu >> that will require 5x2+2=12 class members that will decrease the readability. >> > > Feel free to have an array or whatnot to collapse them :) > > >> Also, there is no guarantee that all these objects will ever be used, >> so this is a kind of pessimization. >> Besides, if getOrInsertFunction is slow, isn't it better to make it >> faster, than to manually optimize calls? >> We can do a lazy init for these objects, but then again what is the >> preferred way to do lazy init in the FunctionPass to avoid races? >> > > The trouble is that a FunctionPass isn't supposed to be creating or > deleting Function (or other Globals). This is part of the threading model. > See http://llvm.org/docs/WritingAnLLVMPass.html#FunctionPass . > > If you find these restrictions too hard to live with you can go back to > using a ModulePass. in reality, we have plenty FunctionPasses which do > manipulate global state against the rules, but I'm trying to make TSan > perfect. > "make TSan perfect" sounds good :) PTAL. http://codereview.appspot.com/5545054/ --kcc > > >> >>> + else if (isa(BI)) >>> + HasCalls = true; >>> >>> >> >> >>> What about invokes? >>> >>> >> Yea, sure. Done. >> >> >>> + // Instrument memory accesses. >>> + for (size_t i = 0, n = LoadsAndStores.size(); i < n; ++i) { >>> + Res |= instrumentLoadOrStore(LoadsAndStores[i]); >>> + } >>> >>> Why not just call instrumentLoadOrStore as you encounter them? It seems >>> that the vector is just overhead. >>> >> >> *in future* we will need to analyze this array and remove some of its >> elements. >> Now it just looks a bit cleaner to me. >> >> >> --kcc >> > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/cf2196df/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: issue5545054_17001.diff Type: text/x-patch Size: 9966 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/cf2196df/attachment-0001.bin From thomas.stellard at amd.com Tue Feb 7 14:53:29 2012 From: thomas.stellard at amd.com (Tom Stellard) Date: Tue, 7 Feb 2012 15:53:29 -0500 Subject: [llvm-commits] [cfe-commits] Patch: Add get_global_id builtin/intrinsic In-Reply-To: <20120207201623.GA30525@pcc.me.uk> References: <20120203211902.GC1710@L7-CNU1252LKR-172027226155.amd.com> <7DE70FDACDE4CD4887C4278C12A2E305081425@HASMSX104.ger.corp.intel.com> <20120203215531.GD1710@L7-CNU1252LKR-172027226155.amd.com> <7DE70FDACDE4CD4887C4278C12A2E3050814C5@HASMSX104.ger.corp.intel.com> <20120203222438.GB2310@L7-CNU1252LKR-172027226155.amd.com> <20120207201623.GA30525@pcc.me.uk> Message-ID: <20120207205329.GB3511@L7-CNU1252LKR-172027226155.amd.com> On Tue, Feb 07, 2012 at 08:16:23PM +0000, Peter Collingbourne wrote: > On Fri, Feb 03, 2012 at 05:24:38PM -0500, Tom Stellard wrote: > > On Fri, Feb 03, 2012 at 10:07:03PM +0000, Rotem, Nadav wrote: > > > Tom, > > > > > > Our OpenCL implementation of get_global_id is not target specific and we don't resolve it in the backend. I think that get_global_id should be implemented as a simple library call. However, this is something that needs to be discussed with Tanya Lattner, Peter Collingbourne, Anton Lokhmotov, etc. > > > > > > Nadav > > > > Nadav, > > > > Sorry, I guess I should be more clear. When I say target specific I'm > > talking about GPU targets. The get_global_id() implementation > > on the GPUs we've written a backend for (Evergreen, Northern Islands) > > requires reading values from special registers that are preloaded by the > > hardware. I'm guessing other GPUs do something similar, so I do think > > it is something that would need to be resolved in the backend. > Hi Peter, > Hi Tom, > > I disagree. There is no need to resolve these functions in the > backend, as the register reads can simply be made part of the > get_global_id implementation. The libclc OpenCL C standard library > already targets NVIDIA GPUs, and it implements get_global_id and the > other work-item functions in exactly this way: > > http://git.pcc.me.uk/?p=~peter/libclc.git;a=blob;f=ptx-nvidiacl/include/clc/workitem/get_global_id.h > I looked at this before and it seems like a good approach, but the one thing I couldn't figure out was: If I have clang embedded in my OpenCL implementation and it is using an out of tree backend, how do I get clang to recognize my target's builtins as valid and then map them to the appropriate target specific intrinsic? Thanks, Tom > Your way, we leak language-specific details into the backends, details > which can be dealt with by the frontend and standard library, so that > the backends can be kept language independent. > > Also, there is no one way of implementing functions like get_global_id > on (say) PTX. One thing that is missing from the get_global_id > implementation in libclc is global offsets. The precise details > of how those offsets are passed to the kernel have varied over > time (for example, at one point a global array was used, and now > special registers are used). If we encode these sorts of details > in the backend we reduce overall flexibility and deny optimisation > opportunities to the optimisers. For example, say the kernel computes: > > get_global_id(0) - get_global_offset(0) > > On PTX the optimisers should be able to eliminate the global offset > access altogether, but they might not be able to if get_global_id > and get_global_offset are opaque intrinsic calls. > > Thanks, > -- > Peter > From hfinkel at anl.gov Tue Feb 7 15:11:12 2012 From: hfinkel at anl.gov (Hal Finkel) Date: Tue, 07 Feb 2012 21:11:12 -0000 Subject: [llvm-commits] [llvm] r150003 - /llvm/trunk/tools/bugpoint/bugpoint.cpp Message-ID: <20120207211112.74AA82A6C12C@llvm.org> Author: hfinkel Date: Tue Feb 7 15:11:12 2012 New Revision: 150003 URL: http://llvm.org/viewvc/llvm-project?rev=150003&view=rev Log: Allow bugpoint to recognize -bb-vectorize Modified: llvm/trunk/tools/bugpoint/bugpoint.cpp Modified: llvm/trunk/tools/bugpoint/bugpoint.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/bugpoint/bugpoint.cpp?rev=150003&r1=150002&r2=150003&view=diff ============================================================================== --- llvm/trunk/tools/bugpoint/bugpoint.cpp (original) +++ llvm/trunk/tools/bugpoint/bugpoint.cpp Tue Feb 7 15:11:12 2012 @@ -120,6 +120,7 @@ PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); From rjmccall at apple.com Tue Feb 7 15:17:13 2012 From: rjmccall at apple.com (John McCall) Date: Tue, 07 Feb 2012 13:17:13 -0800 Subject: [llvm-commits] [llvm] r148553 - in /llvm/trunk: docs/LangRef.html include/llvm-c/Core.h include/llvm/Attributes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeRead In-Reply-To: References: Message-ID: <9E71123D-EB57-40B7-A5CF-EBF0C2C32C87@apple.com> On Feb 7, 2012, at 12:12 PM, Kostya Serebryany wrote: > On Tue, Feb 7, 2012 at 11:42 AM, John McCall wrote: > On Jan 20, 2012, at 9:56 AM, Kostya Serebryany wrote: > > Author: kcc > > Date: Fri Jan 20 11:56:17 2012 > > New Revision: 148553 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=148553&view=rev > > Log: > > Extend Attributes to 64 bits > > > > Problem: LLVM needs more function attributes than currently available (32 bits). > > One such proposed attribute is "address_safety", which shows that a function is being checked for address safety (by AddressSanitizer, SAFECode, etc). > > > > Solution: > > - extend the Attributes from 32 bits to 64-bits > > - wrap the object into a class so that unsigned is never erroneously used instead > > - change "unsigned" to "Attributes" throughout the code, including one place in clang. > > - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to support packing/unpacking. > > - the class has "safe operator bool()" to support the common idiom: if (Attributes attr = getAttrs()) useAttrs(attr); > > - The CTOR from uint64_t is marked explicit, so I had to add a few explicit CTOR calls > > - Add the new attribute "address_safety". Doing it in the same commit to check that attributes beyond first 32 bits actually work. > > - Some of the functions from the Attribute namespace are worth moving inside the class, but I'd prefer to have it as a separate commit. > > > > Tested: > > "make check" on Linux (32-bit and 64-bit) and Mac (10.6) > > built/run spec CPU 2006 on Linux with clang -O2. > > Using a class here is introducing global initializers into every translation unit that includes llvm/Attributes.h. Those initializers are optimized out at -O1 (by clang, at least), but it's still bad practice. > > Why? > This code looks clean and effective (with >=O1). The main problem is that it triggers warnings about global constructors. > If you remove all the constructors from the class, you can use list-initialization instead, which (in this case) is essentially guaranteed to not require a global initializer; the only other alternative (given MSVC's limitations) > > What are these limitations? I believe the underlying type of an enum on MSVC is always 'int', regardless of its enumerators. In any case, it's always 32 bits. Just for the record, no, that's not standards-compliant. > We can probably come up with something like a proxy class to initialize the Attribute constans, not sure if it's worth doing so. Oh, that should work well enough; just use a proxy, list-initializable class that implicitly converts to your class type. John. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/3d2fc855/attachment.html From dschuff at google.com Tue Feb 7 16:26:37 2012 From: dschuff at google.com (Derek Schuff) Date: Tue, 7 Feb 2012 14:26:37 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ In-Reply-To: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> References: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> Message-ID: The problem is that fetching more data can cause the underlying structure (e.g. the storage pointer in the example) to be reallocated/resized. MutableArrayRef type classes are basically just glorified pointers and designed not to own the data; but the data has to be owned by something accessible to MemoryObject, and MemoryObject::readBytes would have to call a non-const method on whatever does own it. The behavior you're describing is like a const pointer (const char* foo) but the 'const' qualifier on a method basically means 'const char* const foo' We could of course keep const on the methods and do our game-playing by making all the data members of the StreamableMemoryObject mutable, but that's worse (IMO) than just having another class that's like MemoryObject but doesn't derive directly from it. On Tue, Feb 7, 2012 at 12:30 PM, Jim Grosbach wrote: > > Why can't a const StreamableMemoryObject read in more information to > satisfy a request? As I understand it, 'const' there is saying that the > data won't be modified and not necessarily anything about what actions need > to be taken to read it. > > From an implementation detail point of view, consider the following > contrived example: > > $ cat foo.cpp > #include > > #include > > class myClass { > > unsigned *storage; > > public: > > myClass(unsigned *buffer) { storage = buffer; } > > > > void write(unsigned val) const { *storage = val; } > > unsigned read() const { return *storage; } > > void set(unsigned *buffer) { storage = buffer; } > > }; > > > > void foo(const myClass *p) { > > p->write(5); > > std::cout << p->read() << std::endl; > > p->write(4); > > std::cout << p->read() << std::endl; > > // Can't do this due to 'const' > > // error: member function 'set' not viable: 'this' argument has type > 'const myClass', but function is not marked const > //unsigned newbuf; > > //p->set(&newbuf); > > } > > > > int main(int argc, char *argv[]) { > > unsigned val; > > myClass X(&val); > > foo(&X); > > } > $ clang++ foo.cpp -o foo > $ ./foo > 5 > 4 > > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/a4a92473/attachment.html From grosbach at apple.com Tue Feb 7 16:33:41 2012 From: grosbach at apple.com (Jim Grosbach) Date: Tue, 07 Feb 2012 14:33:41 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ In-Reply-To: References: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> Message-ID: <97B3AA6F-56CB-48AD-9DB0-6395C25DD666@apple.com> On Feb 7, 2012, at 2:26 PM, Derek Schuff wrote: > The problem is that fetching more data can cause the underlying structure (e.g. the storage pointer in the example) to be reallocated/resized. That's an implementation detail. It's the exposed interface of the class and the semantics associated that I'm concerned with. As a user of the class, I should neither know nor care what's inside or how it works. In this case, the semantics we want to be able to express are whether the consumer of a MemoryObject can change the underlying data (write to the memory/file/shared object) or not. > MutableArrayRef type classes are basically just glorified pointers and designed not to own the data; but the data has to be owned by something accessible to MemoryObject, and MemoryObject::readBytes would have to call a non-const method on whatever does own it. The behavior you're describing is like a const pointer (const char* foo) but the 'const' qualifier on a method basically means 'const char* const foo' It means that the 'this' pointer is const qualified. Any additional semantics of the interface are convention up to the designer. > We could of course keep const on the methods and do our game-playing by making all the data members of the StreamableMemoryObject mutable, but that's worse (IMO) than just having another class that's like MemoryObject but doesn't derive directly from it. Why? -Jim > > On Tue, Feb 7, 2012 at 12:30 PM, Jim Grosbach wrote: > > Why can't a const StreamableMemoryObject read in more information to satisfy a request? As I understand it, 'const' there is saying that the data won't be modified and not necessarily anything about what actions need to be taken to read it. > > From an implementation detail point of view, consider the following contrived example: > > $ cat foo.cpp > #include > #include > class myClass { > unsigned *storage; > public: > myClass(unsigned *buffer) { storage = buffer; } > > void write(unsigned val) const { *storage = val; } > unsigned read() const { return *storage; } > void set(unsigned *buffer) { storage = buffer; } > }; > > void foo(const myClass *p) { > p->write(5); > std::cout << p->read() << std::endl; > p->write(4); > std::cout << p->read() << std::endl; > // Can't do this due to 'const' > // error: member function 'set' not viable: 'this' argument has type 'const myClass', but function is not marked const > //unsigned newbuf; > //p->set(&newbuf); > } > > int main(int argc, char *argv[]) { > unsigned val; > myClass X(&val); > foo(&X); > } > $ clang++ foo.cpp -o foo > $ ./foo > 5 > 4 > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/5c34e153/attachment.html From evan.cheng at apple.com Tue Feb 7 16:50:41 2012 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 07 Feb 2012 22:50:41 -0000 Subject: [llvm-commits] [llvm] r150008 - in /llvm/trunk/lib/Target/X86: X86.td X86FrameLowering.cpp X86Subtarget.cpp X86Subtarget.h Message-ID: <20120207225041.6CE032A6C12C@llvm.org> Author: evancheng Date: Tue Feb 7 16:50:41 2012 New Revision: 150008 URL: http://llvm.org/viewvc/llvm-project?rev=150008&view=rev Log: Use LEA to adjust stack ptr for Atom. Patch by Andy Zhang. Modified: llvm/trunk/lib/Target/X86/X86.td llvm/trunk/lib/Target/X86/X86FrameLowering.cpp llvm/trunk/lib/Target/X86/X86Subtarget.cpp llvm/trunk/lib/Target/X86/X86Subtarget.h Modified: llvm/trunk/lib/Target/X86/X86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=150008&r1=150007&r2=150008&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86.td (original) +++ llvm/trunk/lib/Target/X86/X86.td Tue Feb 7 16:50:41 2012 @@ -115,6 +115,8 @@ "Support BMI instructions">; def FeatureBMI2 : SubtargetFeature<"bmi2", "HasBMI2", "true", "Support BMI2 instructions">; +def FeatureLeaForSP : SubtargetFeature<"lea-sp", "UseLeaForSP", "true", + "Use LEA for adjusting the stack pointer">; //===----------------------------------------------------------------------===// // X86 processors supported. @@ -155,7 +157,7 @@ def : Proc<"penryn", [FeatureSSE41, FeatureCMPXCHG16B, FeatureSlowBTMem]>; def : AtomProc<"atom", [ProcIntelAtom, FeatureSSE3, FeatureCMPXCHG16B, - FeatureMOVBE, FeatureSlowBTMem]>; + FeatureMOVBE, FeatureSlowBTMem, FeatureLeaForSP]>; // "Arrandale" along with corei3 and corei5 def : Proc<"corei7", [FeatureSSE42, FeatureCMPXCHG16B, FeatureSlowBTMem, FeatureFastUAMem, Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=150008&r1=150007&r2=150008&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Tue Feb 7 16:50:41 2012 @@ -79,6 +79,10 @@ } } +static unsigned getLEArOpcode(unsigned is64Bit) { + return is64Bit ? X86::LEA64r : X86::LEA32r; +} + /// findDeadCallerSavedReg - Return a caller-saved register that isn't live /// when it reaches the "return" instruction. We can then pop a stack object /// to this register without worry about clobbering it. @@ -141,13 +145,18 @@ static void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, unsigned StackPtr, int64_t NumBytes, - bool Is64Bit, const TargetInstrInfo &TII, - const TargetRegisterInfo &TRI) { + bool Is64Bit, bool UseLEA, + const TargetInstrInfo &TII, const TargetRegisterInfo &TRI) { bool isSub = NumBytes < 0; uint64_t Offset = isSub ? -NumBytes : NumBytes; - unsigned Opc = isSub ? - getSUBriOpcode(Is64Bit, Offset) : - getADDriOpcode(Is64Bit, Offset); + unsigned Opc; + if (UseLEA) + Opc = getLEArOpcode(Is64Bit); + else + Opc = isSub + ? getSUBriOpcode(Is64Bit, Offset) + : getADDriOpcode(Is64Bit, Offset); + uint64_t Chunk = (1LL << 31) - 1; DebugLoc DL = MBB.findDebugLoc(MBBI); @@ -171,13 +180,21 @@ } } - MachineInstr *MI = - BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) - .addReg(StackPtr) - .addImm(ThisVal); + MachineInstr *MI = NULL; + + if (UseLEA) { + MI = addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr), + StackPtr, false, isSub ? -ThisVal : ThisVal); + } else { + MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) + .addReg(StackPtr) + .addImm(ThisVal); + MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. + } + if (isSub) MI->setFlag(MachineInstr::FrameSetup); - MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead. + Offset -= ThisVal; } } @@ -191,7 +208,8 @@ MachineBasicBlock::iterator PI = prior(MBBI); unsigned Opc = PI->getOpcode(); if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || - Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && + Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || + Opc == X86::LEA32r || Opc == X86::LEA64_32r) && PI->getOperand(0).getReg() == StackPtr) { if (NumBytes) *NumBytes += PI->getOperand(2).getImm(); @@ -237,8 +255,8 @@ } /// mergeSPUpdates - Checks the instruction before/after the passed -/// instruction. If it is an ADD/SUB instruction it is deleted argument and the -/// stack adjustment is returned as a positive value for ADD and a negative for +/// instruction. If it is an ADD/SUB/LEA instruction it is deleted argument and the +/// stack adjustment is returned as a positive value for ADD/LEA and a negative for /// SUB. static int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, @@ -254,7 +272,8 @@ int Offset = 0; if ((Opc == X86::ADD64ri32 || Opc == X86::ADD64ri8 || - Opc == X86::ADD32ri || Opc == X86::ADD32ri8) && + Opc == X86::ADD32ri || Opc == X86::ADD32ri8 || + Opc == X86::LEA32r || Opc == X86::LEA64_32r) && PI->getOperand(0).getReg() == StackPtr){ Offset += PI->getOperand(2).getImm(); MBB.erase(PI); @@ -626,6 +645,7 @@ bool HasFP = hasFP(MF); bool Is64Bit = STI.is64Bit(); bool IsWin64 = STI.isTargetWin64(); + bool UseLEA = STI.useLeaForSP(); unsigned StackAlign = getStackAlignment(); unsigned SlotSize = RegInfo->getSlotSize(); unsigned FramePtr = RegInfo->getFrameRegister(MF); @@ -879,7 +899,7 @@ // FIXME: %rax preserves the offset and should be available. if (isSPUpdateNeeded) emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, - TII, *RegInfo); + UseLEA, TII, *RegInfo); if (isEAXAlive) { // Restore EAX @@ -891,7 +911,7 @@ } } else if (NumBytes) emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, - TII, *RegInfo); + UseLEA, TII, *RegInfo); if (( (!HasFP && NumBytes) || PushedRegs) && needsFrameMoves) { // Mark end of stack pointer adjustment. @@ -935,6 +955,7 @@ unsigned RetOpcode = MBBI->getOpcode(); DebugLoc DL = MBBI->getDebugLoc(); bool Is64Bit = STI.is64Bit(); + bool UseLEA = STI.useLeaForSP(); unsigned StackAlign = getStackAlignment(); unsigned SlotSize = RegInfo->getSlotSize(); unsigned FramePtr = RegInfo->getFrameRegister(MF); @@ -1015,7 +1036,8 @@ // We cannot use LEA here, because stack pointer was realigned. We need to // deallocate local frame back. if (CSSize) { - emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); + emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, UseLEA, TII, + *RegInfo); MBBI = prior(LastCSPop); } @@ -1036,7 +1058,7 @@ } } else if (NumBytes) { // Adjust stack pointer back: ESP += numbytes. - emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII, *RegInfo); + emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, UseLEA, TII, *RegInfo); } // We're returning from function via eh_return. @@ -1071,7 +1093,7 @@ if (Offset) { // Check for possible merge with preceding ADD instruction. Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); - emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII, *RegInfo); + emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, UseLEA, TII, *RegInfo); } // Jump to label or value in register. @@ -1115,7 +1137,7 @@ // Check for possible merge with preceding ADD instruction. delta += mergeSPUpdates(MBB, MBBI, StackPtr, true); - emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, TII, *RegInfo); + emitSPUpdate(MBB, MBBI, StackPtr, delta, Is64Bit, UseLEA, TII, *RegInfo); } } Modified: llvm/trunk/lib/Target/X86/X86Subtarget.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.cpp?rev=150008&r1=150007&r2=150008&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.cpp (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.cpp Tue Feb 7 16:50:41 2012 @@ -257,6 +257,7 @@ // Set processor type. Currently only Atom is detected. if (Family == 6 && Model == 28) { X86ProcFamily = IntelAtom; + ToggleFeature(X86::FeatureLeaForSP); } unsigned MaxExtLevel; @@ -340,6 +341,7 @@ , IsUAMemFast(false) , HasVectorUAMem(false) , HasCmpxchg16b(false) + , UseLeaForSP(false) , PostRAScheduler(false) , stackAlignment(4) // FIXME: this is a known good value for Yonah. How about others? Modified: llvm/trunk/lib/Target/X86/X86Subtarget.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Subtarget.h?rev=150008&r1=150007&r2=150008&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86Subtarget.h (original) +++ llvm/trunk/lib/Target/X86/X86Subtarget.h Tue Feb 7 16:50:41 2012 @@ -132,6 +132,10 @@ /// this is true for most x86-64 chips, but not the first AMD chips. bool HasCmpxchg16b; + /// UseLeaForSP - True if the LEA instruction should be used for adjusting + /// the stack pointer. This is an optimization for Intel Atom processors. + bool UseLeaForSP; + /// PostRAScheduler - True if using post-register-allocation scheduler. bool PostRAScheduler; @@ -214,6 +218,7 @@ bool isUnalignedMemAccessFast() const { return IsUAMemFast; } bool hasVectorUAMem() const { return HasVectorUAMem; } bool hasCmpxchg16b() const { return HasCmpxchg16b; } + bool useLeaForSP() const { return UseLeaForSP; } bool isAtom() const { return X86ProcFamily == IntelAtom; } From evan.cheng at apple.com Tue Feb 7 16:54:58 2012 From: evan.cheng at apple.com (Evan Cheng) Date: Tue, 07 Feb 2012 14:54:58 -0800 Subject: [llvm-commits] [PATCH] Intel Atom optimization - use LEA to adjust stack pointer In-Reply-To: <5C9B2DB6AAFD914E864AF9803780B66A01181D@FMSMSX108.amr.corp.intel.com> References: <9A83F73AEA08BB46A2799C5D4C16BFED011A38BC09@rrsmsx509.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66A7EAC@FMSMSX108.amr.corp.intel.com> <5CED04BC-2514-4235-9364-9FFB13E415EE@2pi.dk> <5C9B2DB6AAFD914E864AF9803780B66A976F@FMSMSX108.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66AAACF@FMSMSX108.amr.corp.intel.com> <44458013-AAF2-4D59-AE66-BFCFCFBF63FE@apple.com> <5C9B2DB6AAFD914E864AF9803780B66AB1CD@FMSMSX108.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66A010CC4@FMSMSX108.amr.corp.intel.com> <5C9B2DB6AAFD914E864AF9803780B66A01181D@FMSMSX108.amr.corp.intel.com> Message-ID: I changed attribute lea_sp to lea-sp to conform to naming convention used by rest of X86 attributes. I also fixed a few 80 col violations and a couple of stylistic issues. Committed: r150008 Evan On Feb 7, 2012, at 7:11 AM, "Zhang, Andy" wrote: > Ping... > >> -----Original Message----- >> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits- >> bounces at cs.uiuc.edu] On Behalf Of Zhang, Andy >> Sent: Thursday, February 02, 2012 2:33 PM >> To: llvm-commits at cs.uiuc.edu >> Subject: Re: [llvm-commits] Intel Atom optimization - use LEA to adjust >> stack pointer >> >> On January 18, 2012 4:35 PM, Evan Cheng wrote: >>> >>> Yes, that's the right way to use subtarget features. If the number of >>> Atom specific optimizations get too large, then we can refactor it. >>> >>> Evan >>> >> >> Hi Evan, >> >> I've changed my patch to use a separate subtarget feature for this >> optimization. >> Sorry for the delay -- I was away for the past couple of weeks. >> >> If there are no more comments, could you please commit the patch. >> >> >> Thanks, >> Andy From dschuff at google.com Tue Feb 7 17:12:52 2012 From: dschuff at google.com (Derek Schuff) Date: Tue, 7 Feb 2012 15:12:52 -0800 Subject: [llvm-commits] [llvm] r149918 - in /llvm/trunk: include/llvm/Bitcode/ include/llvm/MC/ include/llvm/Support/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/MC/MCDisassembler/ lib/Support/ lib/Target/ARM/Disassembler/ lib/Target/MBlaze/Disassembler/ In-Reply-To: <97B3AA6F-56CB-48AD-9DB0-6395C25DD666@apple.com> References: <5DC1941D-90F0-40BD-954B-4284AE1D7008@apple.com> <97B3AA6F-56CB-48AD-9DB0-6395C25DD666@apple.com> Message-ID: On Tue, Feb 7, 2012 at 2:33 PM, Jim Grosbach wrote: > > On Feb 7, 2012, at 2:26 PM, Derek Schuff wrote: > > The problem is that fetching more data can cause the underlying structure > (e.g. the storage pointer in the example) to be reallocated/resized. > > > That's an implementation detail. It's the exposed interface of the class > and the semantics associated that I'm concerned with. As a user of the > class, I should neither know nor care what's inside or how it works. In > this case, the semantics we want to be able to express are whether the > consumer of a MemoryObject can change the underlying data (write to the > memory/file/shared object) or not. > > MutableArrayRef type classes are basically just glorified pointers and > designed not to own the data; but the data has to be owned by something > accessible to MemoryObject, and MemoryObject::readBytes would have to call > a non-const method on whatever does own it. The behavior you're describing > is like a const pointer (const char* foo) but the 'const' qualifier on a > method basically means 'const char* const foo' > > > It means that the 'this' pointer is const qualified. Any additional > semantics of the interface are convention up to the designer. > OK. I guess we just had different expectations of what those semantics were. > > We could of course keep const on the methods and do our game-playing by > making all the data members of the StreamableMemoryObject mutable, but > that's worse (IMO) than just having another class that's like MemoryObject > but doesn't derive directly from it. > > > Why? > > if all of the data members are mutable, then the 'const' on the methods effectively has no meaning at all. or it's a lie. More specifically to this case, I think the usage of StreamableMemoryObject is different enough from MemoryObject that it shouldn't really be derived, and these other issues are even more reason. So, I've attached a patch that fixes all the MC stuff and leaves MemoryObject as it was, and leaves StreamableMemoryObject as the base class. Please review, thanks, -Derek -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/a9cec8dd/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: MCFix.patch Type: text/x-patch Size: 13105 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/a9cec8dd/attachment.bin From dpatel at apple.com Tue Feb 7 17:33:58 2012 From: dpatel at apple.com (Devang Patel) Date: Tue, 07 Feb 2012 23:33:58 -0000 Subject: [llvm-commits] [llvm] r150012 - /llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Message-ID: <20120207233358.5239B2A6C12C@llvm.org> Author: dpatel Date: Tue Feb 7 17:33:58 2012 New Revision: 150012 URL: http://llvm.org/viewvc/llvm-project?rev=150012&view=rev Log: Remove tabs. Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp?rev=150012&r1=150011&r2=150012&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp (original) +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp Tue Feb 7 17:33:58 2012 @@ -696,7 +696,7 @@ Buffer.setTag(dwarf::DW_TAG_base_type); addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, - BTy.getEncoding()); + BTy.getEncoding()); uint64_t Size = BTy.getSizeInBits() >> 3; addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); @@ -825,17 +825,17 @@ } else if (Element.isDerivedType()) ElemDie = createMemberDIE(DIDerivedType(Element)); else if (Element.isObjCProperty()) { - DIObjCProperty Property(Element); - ElemDie = new DIE(Property.getTag()); - StringRef PropertyName = Property.getObjCPropertyName(); - addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); - StringRef GetterName = Property.getObjCPropertyGetterName(); - if (!GetterName.empty()) - addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName); - StringRef SetterName = Property.getObjCPropertySetterName(); - if (!SetterName.empty()) - addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName); - unsigned PropertyAttributes = 0; + DIObjCProperty Property(Element); + ElemDie = new DIE(Property.getTag()); + StringRef PropertyName = Property.getObjCPropertyName(); + addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName); + StringRef GetterName = Property.getObjCPropertyGetterName(); + if (!GetterName.empty()) + addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName); + StringRef SetterName = Property.getObjCPropertySetterName(); + if (!SetterName.empty()) + addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName); + unsigned PropertyAttributes = 0; if (Property.isReadOnlyObjCProperty()) PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly; if (Property.isReadWriteObjCProperty()) @@ -852,11 +852,11 @@ addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, 0, PropertyAttributes); - DIEEntry *Entry = getDIEEntry(Element); - if (!Entry) { - Entry = createDIEEntry(ElemDie); - insertDIEEntry(Element, Entry); - } + DIEEntry *Entry = getDIEEntry(Element); + if (!Entry) { + Entry = createDIEEntry(ElemDie); + insertDIEEntry(Element, Entry); + } } else continue; Buffer.addChild(ElemDie); From mcrosier at apple.com Tue Feb 7 17:56:08 2012 From: mcrosier at apple.com (Chad Rosier) Date: Tue, 07 Feb 2012 23:56:08 -0000 Subject: [llvm-commits] [llvm] r150014 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-indirectbr.ll Message-ID: <20120207235608.9749A2A6C12C@llvm.org> Author: mcrosier Date: Tue Feb 7 17:56:08 2012 New Revision: 150014 URL: http://llvm.org/viewvc/llvm-project?rev=150014&view=rev Log: [fast-isel] Add support for indirect branches. Added: llvm/trunk/test/CodeGen/ARM/fast-isel-indirectbr.ll Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=150014&r1=150013&r2=150014&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Tue Feb 7 17:56:08 2012 @@ -157,6 +157,7 @@ bool SelectLoad(const Instruction *I); bool SelectStore(const Instruction *I); bool SelectBranch(const Instruction *I); + bool SelectIndirectBr(const Instruction *I); bool SelectCmp(const Instruction *I); bool SelectFPExt(const Instruction *I); bool SelectFPTrunc(const Instruction *I); @@ -1350,6 +1351,16 @@ return true; } +bool ARMFastISel::SelectIndirectBr(const Instruction *I) { + unsigned AddrReg = getRegForValue(I->getOperand(0)); + if (AddrReg == 0) return false; + + unsigned Opc = isThumb2 ? ARM::tBRIND : ARM::BX; + AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc)) + .addReg(AddrReg)); + return true; +} + bool ARMFastISel::ARMEmitCmp(const Value *Src1Value, const Value *Src2Value, bool isZExt) { Type *Ty = Src1Value->getType(); @@ -2468,6 +2479,8 @@ return SelectStore(I); case Instruction::Br: return SelectBranch(I); + case Instruction::IndirectBr: + return SelectIndirectBr(I); case Instruction::ICmp: case Instruction::FCmp: return SelectCmp(I); Added: llvm/trunk/test/CodeGen/ARM/fast-isel-indirectbr.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-indirectbr.ll?rev=150014&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-indirectbr.ll (added) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-indirectbr.ll Tue Feb 7 17:56:08 2012 @@ -0,0 +1,17 @@ +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios | FileCheck %s --check-prefix=ARM +; RUN: llc < %s -O0 -fast-isel-abort -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios | FileCheck %s --check-prefix=THUMB + +define void @t1(i8* %x) { +entry: +; ARM: t1 +; THUMB: t1 + br label %L0 + +L0: + br label %L1 + +L1: + indirectbr i8* %x, [ label %L0, label %L1 ] +; ARM: bx r0 +; THUMB: mov pc, r0 +} From dpatel at apple.com Tue Feb 7 18:17:07 2012 From: dpatel at apple.com (Devang Patel) Date: Wed, 08 Feb 2012 00:17:07 -0000 Subject: [llvm-commits] [llvm] r150022 - in /llvm/trunk: include/llvm/Analysis/DIBuilder.h include/llvm/Analysis/DebugInfo.h lib/Analysis/DIBuilder.cpp lib/Analysis/DebugInfo.cpp Message-ID: <20120208001707.7A01A2A6C12C@llvm.org> Author: dpatel Date: Tue Feb 7 18:17:07 2012 New Revision: 150022 URL: http://llvm.org/viewvc/llvm-project?rev=150022&view=rev Log: Remove tabs. Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h llvm/trunk/include/llvm/Analysis/DebugInfo.h llvm/trunk/lib/Analysis/DIBuilder.cpp llvm/trunk/lib/Analysis/DebugInfo.cpp Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DIBuilder.h?rev=150022&r1=150021&r2=150022&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DIBuilder.h (original) +++ llvm/trunk/include/llvm/Analysis/DIBuilder.h Tue Feb 7 18:17:07 2012 @@ -215,7 +215,7 @@ /// @param SetterName Name of the Objective C property setter selector. /// @param PropertyAttributes Objective C property attributes. DIObjCProperty createObjCProperty(StringRef Name, StringRef GetterName, - StringRef SetterName, + StringRef SetterName, unsigned PropertyAttributes); /// createClassType - Create debugging information entry for a class. @@ -498,7 +498,7 @@ /// @param Scope Lexical block. /// @param File Source file. DILexicalBlockFile createLexicalBlockFile(DIDescriptor Scope, - DIFile File); + DIFile File); /// createLexicalBlock - This creates a descriptor for a lexical block /// with the specified parent context. Modified: llvm/trunk/include/llvm/Analysis/DebugInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DebugInfo.h?rev=150022&r1=150021&r2=150022&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DebugInfo.h (original) +++ llvm/trunk/include/llvm/Analysis/DebugInfo.h Tue Feb 7 18:17:07 2012 @@ -363,7 +363,7 @@ StringRef getObjCPropertyName() const { if (getVersion() > LLVMDebugVersion11) - return StringRef(); + return StringRef(); return getStringField(10); } StringRef getObjCPropertyGetterName() const { Modified: llvm/trunk/lib/Analysis/DIBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DIBuilder.cpp?rev=150022&r1=150021&r2=150022&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DIBuilder.cpp (original) +++ llvm/trunk/lib/Analysis/DIBuilder.cpp Tue Feb 7 18:17:07 2012 @@ -541,7 +541,7 @@ DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, - DIArray Elements) { + DIArray Elements) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), @@ -779,7 +779,7 @@ Elts.push_back(MDString::get(VMContext, Name)); Elts.push_back(F); Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), - (LineNo | (ArgNo << 24)))); + (LineNo | (ArgNo << 24)))); Elts.push_back(Ty); Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); Elts.push_back(llvm::Constant::getNullValue(Type::getInt32Ty(VMContext))); @@ -895,7 +895,7 @@ /// createLexicalBlockFile - This creates a new MDNode that encapsulates /// an existing scope with a new filename. DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, - DIFile File) { + DIFile File) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), Scope, Modified: llvm/trunk/lib/Analysis/DebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DebugInfo.cpp?rev=150022&r1=150021&r2=150022&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DebugInfo.cpp (original) +++ llvm/trunk/lib/Analysis/DebugInfo.cpp Tue Feb 7 18:17:07 2012 @@ -974,22 +974,22 @@ DICompileUnit CU(CU_Nodes->getOperand(i)); addCompileUnit(CU); if (CU.getVersion() > LLVMDebugVersion10) { - DIArray GVs = CU.getGlobalVariables(); - for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { - DIGlobalVariable DIG(GVs.getElement(i)); - if (addGlobalVariable(DIG)) - processType(DIG.getType()); - } - DIArray SPs = CU.getSubprograms(); - for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) - processSubprogram(DISubprogram(SPs.getElement(i))); - DIArray EnumTypes = CU.getEnumTypes(); - for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) - processType(DIType(EnumTypes.getElement(i))); - DIArray RetainedTypes = CU.getRetainedTypes(); - for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) - processType(DIType(RetainedTypes.getElement(i))); - return; + DIArray GVs = CU.getGlobalVariables(); + for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { + DIGlobalVariable DIG(GVs.getElement(i)); + if (addGlobalVariable(DIG)) + processType(DIG.getType()); + } + DIArray SPs = CU.getSubprograms(); + for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) + processSubprogram(DISubprogram(SPs.getElement(i))); + DIArray EnumTypes = CU.getEnumTypes(); + for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) + processType(DIType(EnumTypes.getElement(i))); + DIArray RetainedTypes = CU.getRetainedTypes(); + for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) + processType(DIType(RetainedTypes.getElement(i))); + return; } } } From echristo at apple.com Tue Feb 7 18:22:26 2012 From: echristo at apple.com (Eric Christopher) Date: Wed, 08 Feb 2012 00:22:26 -0000 Subject: [llvm-commits] [llvm] r150024 - in /llvm/trunk: include/llvm/Analysis/DIBuilder.h lib/Analysis/DIBuilder.cpp Message-ID: <20120208002226.8AF162A6C12C@llvm.org> Author: echristo Date: Tue Feb 7 18:22:26 2012 New Revision: 150024 URL: http://llvm.org/viewvc/llvm-project?rev=150024&view=rev Log: Add support for a temporary forward decl type. We want this so we can rauw forward declarations if we decide to emit the full type. Part of rdar://10809898 Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h llvm/trunk/lib/Analysis/DIBuilder.cpp Modified: llvm/trunk/include/llvm/Analysis/DIBuilder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/DIBuilder.h?rev=150024&r1=150023&r2=150024&view=diff ============================================================================== --- llvm/trunk/include/llvm/Analysis/DIBuilder.h (original) +++ llvm/trunk/include/llvm/Analysis/DIBuilder.h Tue Feb 7 18:22:26 2012 @@ -341,6 +341,10 @@ DIType createTemporaryType(); DIType createTemporaryType(DIFile F); + /// createForwardDecl - Create a temporary forward-declared type. + DIType createForwardDecl(unsigned Tag, StringRef Name, DIFile F, + unsigned Line); + /// retainType - Retain DIType in a module even if it is not referenced /// through debug info anchors. void retainType(DIType T); Modified: llvm/trunk/lib/Analysis/DIBuilder.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/DIBuilder.cpp?rev=150024&r1=150023&r2=150024&view=diff ============================================================================== --- llvm/trunk/lib/Analysis/DIBuilder.cpp (original) +++ llvm/trunk/lib/Analysis/DIBuilder.cpp Tue Feb 7 18:22:26 2012 @@ -669,6 +669,28 @@ return DIType(Node); } +/// createForwardDecl - Create a temporary forward-declared type that +/// can be RAUW'd if the full type is seen. +DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIFile F, + unsigned Line) { + // Create a temporary MDNode. + Value *Elts[] = { + GetTagConstant(VMContext, Tag), + NULL, // TheCU + MDString::get(VMContext, Name), + F, + ConstantInt::get(Type::getInt32Ty(VMContext), Line), + // To ease transition include sizes etc of 0. + ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), 0), + ConstantInt::get(Type::getInt32Ty(VMContext), + DIDescriptor::FlagFwdDecl) + }; + MDNode *Node = MDNode::getTemporary(VMContext, Elts); + return DIType(Node); +} + /// getOrCreateArray - Get a DIArray, create one if required. DIArray DIBuilder::getOrCreateArray(ArrayRef Elements) { if (Elements.empty()) { From ahatanaka at mips.com Tue Feb 7 18:34:33 2012 From: ahatanaka at mips.com (Hatanaka, Akira) Date: Wed, 8 Feb 2012 00:34:33 +0000 Subject: [llvm-commits] [PATCH][Review request] IEEE quad software emulation library call In-Reply-To: <95DD8BA8AA50B14BBFB86A1D541FA3809EAB5965@exchdb03.mips.com> References: <95DD8BA8AA50B14BBFB86A1D541FA3809EAB2E46@exchdb03.mips.com> <95DD8BA8AA50B14BBFB86A1D541FA3809EAB2E71@exchdb03.mips.com> <95DD8BA8AA50B14BBFB86A1D541FA3809EAB542D@exchdb03.mips.com> <95DD8BA8AA50B14BBFB86A1D541FA3809EAB5468@exchdb03.mips.com> <95DD8BA8AA50B14BBFB86A1D541FA3809EAB583D@exchdb03.mips.com>, , <95DD8BA8AA50B14BBFB86A1D541FA3809EAB5965@exchdb03.mips.com> Message-ID: <95DD8BA8AA50B14BBFB86A1D541FA380F308A30D@exchdb03.mips.com> I found the changes I made in my previous patches were not correct and some of the test programs failed to compile. So here are the revised patches and the updated test case. f128-1: Add libcall enums and set default lib call names. Add Call_F128 parameter to GetFPLibCall. f128-2: Pass NumOps to LowerCallTo so that OutputArg::IsFixed is set to true if the argument being passed is not a variable argument. f128-3: Add array PassArgsInFloatRegs to TargetLowering which is used as a flag that indicates whether an argument or return value of a certain type should be passed in floating point registers. If PassArgsInFloatRegs is true for the original type of an argument or return value, the type of InputArgs or OutputArgs is converted to a floating point type of the same size before it is passed to TargetLowering::LowerCall, LowerFormalArguments or LowerReturn. NumRegistersForVT or RegisterTypeForVT for f128 does not change once it is set in TargetLowering::computeRegisterProperties(). No bit-casting from i128 to f128 or vice versa is needed. f128-4: Changes in constructor of MipsTargetLowering. I think the first patch consists of mostly mechanical changes and the second one is harmless too. Is it okay to commit them? ________________________________________ From: Hatanaka, Akira Sent: Thursday, January 26, 2012 4:17 PM To: Anton Korobeynikov Cc: Eli Friedman; baldrick at free.fr; llvm-commits at cs.uiuc.edu Subject: RE: [llvm-commits] [PATCH][Review request] IEEE quad software emulation library call I have been thinking about this for a while but haven't been able to come up with a solution that is much better. Nodes in a DAG is legalized top-down, and f128 nodes have to be transformed to integer type nodes and then expanded into smaller type nodes to make forward progress, so it seems difficult to not legalize operands of nodes that require library calls without making drastic changes in the code. Bitcasting an i128 to f128 is silly, but I think it is a lot simpler. I have attached another patch which basically takes the same approach but is cleaner than the previous one. Properties of f128 are set by the target if it needs to have arguments passed in floating point registers: setRegisterType(MVT::f128, MVT::f64); setNumRegisters(MVT::f128, 2); setTypeToTransformTo(MVT::f128, MVT::f128); If this isn't the preferred way to legalize f128, I can do pure soft-float legalization in LegalizeFloatTypes.cpp, in the same way other floating point types are legalized, and do i128 <-> f128 conversion in MipsSelLowering.cpp, but that would require changes in LowerCall's API. ________________________________________ From: Anton Korobeynikov [anton at korobeynikov.info] Sent: Wednesday, January 25, 2012 5:46 AM To: Hatanaka, Akira Cc: Eli Friedman; baldrick at free.fr; llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [PATCH][Review request] IEEE quad software emulation library call Akira, > Okay, if that doesn't work, I think I will have to legalize f128 during type legalization. > Is the patch fine as it is now? Or does it need further changes? I'm still thinking about better approach. It seems silly to legalize f128 to i128, and try to "recover" from this afterwards. Maybe we can somehow not legalize arguments to libcalls here... ? And use the common codegenerator code to do all necessary CC stuff. Do you have any ideas here? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University -------------- next part -------------- A non-text attachment was scrubbed... Name: f128-1.patch Type: text/x-patch Size: 41627 bytes Desc: f128-1.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/bd522b88/attachment.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: f128-2.patch Type: text/x-patch Size: 959 bytes Desc: f128-2.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/bd522b88/attachment-0001.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: f128-3.patch Type: text/x-patch Size: 5456 bytes Desc: f128-3.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/bd522b88/attachment-0002.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: f128-4.patch Type: text/x-patch Size: 736 bytes Desc: f128-4.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/bd522b88/attachment-0003.bin -------------- next part -------------- A non-text attachment was scrubbed... Name: f128.ll Type: application/octet-stream Size: 8751 bytes Desc: f128.ll Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/bd522b88/attachment.obj From kcc at google.com Tue Feb 7 18:42:29 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 08 Feb 2012 00:42:29 -0000 Subject: [llvm-commits] [compiler-rt] r150027 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc tests/asan_test.cc Message-ID: <20120208004230.02FCE2A6C12C@llvm.org> Author: kcc Date: Tue Feb 7 18:42:29 2012 New Revision: 150027 URL: http://llvm.org/viewvc/llvm-project?rev=150027&view=rev Log: [asan] better warning messages for double-free bugs (provide allocation/deallocation stack traces) Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc compiler-rt/trunk/lib/asan/tests/asan_test.cc Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=150027&r1=150026&r2=150027&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.cc (original) +++ compiler-rt/trunk/lib/asan/asan_allocator.cc Tue Feb 7 18:42:29 2012 @@ -686,7 +686,7 @@ if (m->chunk_state == CHUNK_QUARANTINE) { Report("ERROR: AddressSanitizer attempting double-free on %p:\n", ptr); stack->PrintStack(); - m->DescribeAddress((uintptr_t)ptr, 1); + Describe((uintptr_t)ptr, 1); ShowStatsAndAbort(); } else if (m->chunk_state != CHUNK_ALLOCATED) { Report("ERROR: AddressSanitizer attempting free on address which was not" Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=150027&r1=150026&r2=150027&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original) +++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Tue Feb 7 18:42:29 2012 @@ -564,7 +564,11 @@ } TEST(AddressSanitizer, DoubleFreeTest) { - EXPECT_DEATH(DoubleFree(), "ERROR: AddressSanitizer attempting double-free"); + EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL + "ERROR: AddressSanitizer attempting double-free" + ".*is located 0 bytes inside of 400-byte region" + ".*freed by thread T0 here" + ".*previously allocated by thread T0 here"); } template From kcc at google.com Tue Feb 7 19:11:21 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 08 Feb 2012 01:11:21 -0000 Subject: [llvm-commits] [llvm] r150031 - /llvm/trunk/include/llvm/Attributes.h Message-ID: <20120208011121.75EB52A6C12C@llvm.org> Author: kcc Date: Tue Feb 7 19:11:21 2012 New Revision: 150031 URL: http://llvm.org/viewvc/llvm-project?rev=150031&view=rev Log: Don't use static CTORs for the Attributes constants, while still keeping the class type-safe Modified: llvm/trunk/include/llvm/Attributes.h Modified: llvm/trunk/include/llvm/Attributes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Attributes.h?rev=150031&r1=150030&r2=150031&view=diff ============================================================================== --- llvm/trunk/include/llvm/Attributes.h (original) +++ llvm/trunk/include/llvm/Attributes.h Tue Feb 7 19:11:21 2012 @@ -22,11 +22,29 @@ namespace llvm { class Type; +namespace Attribute { +/// We use this proxy POD type to allow constructing Attributes constants +/// using initializer lists. Do not use this class directly. +struct AttrConst { + uint64_t v; + AttrConst operator | (const AttrConst Attrs) const { + AttrConst Res = {v | Attrs.v}; + return Res; + } + AttrConst operator ~ () const { + AttrConst Res = {~v}; + return Res; + } +}; +} // namespace Attribute + + /// Attributes - A bitset of attributes. class Attributes { public: Attributes() : Bits(0) { } explicit Attributes(uint64_t Val) : Bits(Val) { } + /*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) { } Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { } // This is a "safe bool() operator". operator const void *() const { return Bits ? this : 0; } @@ -73,45 +91,55 @@ /// results or the function itself. /// @brief Function attributes. -const Attributes None (0); ///< No attributes have been set -const Attributes ZExt (1<<0); ///< Zero extended before/after call -const Attributes SExt (1<<1); ///< Sign extended before/after call -const Attributes NoReturn (1<<2); ///< Mark the function as not returning -const Attributes InReg (1<<3); ///< Force argument to be passed in register -const Attributes StructRet (1<<4); ///< Hidden pointer to structure to return -const Attributes NoUnwind (1<<5); ///< Function doesn't unwind stack -const Attributes NoAlias (1<<6); ///< Considered to not alias after call -const Attributes ByVal (1<<7); ///< Pass structure by value -const Attributes Nest (1<<8); ///< Nested function static chain -const Attributes ReadNone (1<<9); ///< Function does not access memory -const Attributes ReadOnly (1<<10); ///< Function only reads from memory -const Attributes NoInline (1<<11); ///< inline=never -const Attributes AlwaysInline (1<<12); ///< inline=always -const Attributes OptimizeForSize (1<<13); ///< opt_size -const Attributes StackProtect (1<<14); ///< Stack protection. -const Attributes StackProtectReq (1<<15); ///< Stack protection required. -const Attributes Alignment (31<<16); ///< Alignment of parameter (5 bits) +// We declare AttrConst objects that will be used throughout the code +// and also raw uint64_t objects with _i suffix to be used below for other +// constant declarations. This is done to avoid static CTORs and at the same +// time to keep type-safety of Attributes. +#define DECLARE_LLVM_ATTRIBUTE(name, value) \ + const uint64_t name##_i = value; \ + const AttrConst name = {value}; + +DECLARE_LLVM_ATTRIBUTE(None,0) ///< No attributes have been set +DECLARE_LLVM_ATTRIBUTE(ZExt,1<<0) ///< Zero extended before/after call +DECLARE_LLVM_ATTRIBUTE(SExt,1<<1) ///< Sign extended before/after call +DECLARE_LLVM_ATTRIBUTE(NoReturn,1<<2) ///< Mark the function as not returning +DECLARE_LLVM_ATTRIBUTE(InReg,1<<3) ///< Force argument to be passed in register +DECLARE_LLVM_ATTRIBUTE(StructRet,1<<4) ///< Hidden pointer to structure to return +DECLARE_LLVM_ATTRIBUTE(NoUnwind,1<<5) ///< Function doesn't unwind stack +DECLARE_LLVM_ATTRIBUTE(NoAlias,1<<6) ///< Considered to not alias after call +DECLARE_LLVM_ATTRIBUTE(ByVal,1<<7) ///< Pass structure by value +DECLARE_LLVM_ATTRIBUTE(Nest,1<<8) ///< Nested function static chain +DECLARE_LLVM_ATTRIBUTE(ReadNone,1<<9) ///< Function does not access memory +DECLARE_LLVM_ATTRIBUTE(ReadOnly,1<<10) ///< Function only reads from memory +DECLARE_LLVM_ATTRIBUTE(NoInline,1<<11) ///< inline=never +DECLARE_LLVM_ATTRIBUTE(AlwaysInline,1<<12) ///< inline=always +DECLARE_LLVM_ATTRIBUTE(OptimizeForSize,1<<13) ///< opt_size +DECLARE_LLVM_ATTRIBUTE(StackProtect,1<<14) ///< Stack protection. +DECLARE_LLVM_ATTRIBUTE(StackProtectReq,1<<15) ///< Stack protection required. +DECLARE_LLVM_ATTRIBUTE(Alignment,31<<16) ///< Alignment of parameter (5 bits) // stored as log2 of alignment with +1 bias // 0 means unaligned different from align 1 -const Attributes NoCapture (1<<21); ///< Function creates no aliases of pointer -const Attributes NoRedZone (1<<22); /// disable redzone -const Attributes NoImplicitFloat (1<<23); /// disable implicit floating point - /// instructions. -const Attributes Naked (1<<24); ///< Naked function -const Attributes InlineHint (1<<25); ///< source said inlining was - ///desirable -const Attributes StackAlignment (7<<26); ///< Alignment of stack for - ///function (3 bits) stored as log2 - ///of alignment with +1 bias - ///0 means unaligned (different from - ///alignstack(1)) -const Attributes ReturnsTwice (1<<29); ///< Function can return twice -const Attributes UWTable (1<<30); ///< Function must be in a unwind - ///table -const Attributes NonLazyBind (1U<<31); ///< Function is called early and/or - /// often, so lazy binding isn't - /// worthwhile. -const Attributes AddressSafety(1ULL<<32); ///< Address safety checking is on. +DECLARE_LLVM_ATTRIBUTE(NoCapture,1<<21) ///< Function creates no aliases of pointer +DECLARE_LLVM_ATTRIBUTE(NoRedZone,1<<22) /// disable redzone +DECLARE_LLVM_ATTRIBUTE(NoImplicitFloat,1<<23) /// disable implicit floating point + /// instructions. +DECLARE_LLVM_ATTRIBUTE(Naked,1<<24) ///< Naked function +DECLARE_LLVM_ATTRIBUTE(InlineHint,1<<25) ///< source said inlining was + ///desirable +DECLARE_LLVM_ATTRIBUTE(StackAlignment,7<<26) ///< Alignment of stack for + ///function (3 bits) stored as log2 + ///of alignment with +1 bias + ///0 means unaligned (different from + ///alignstack= {1)) +DECLARE_LLVM_ATTRIBUTE(ReturnsTwice,1<<29) ///< Function can return twice +DECLARE_LLVM_ATTRIBUTE(UWTable,1<<30) ///< Function must be in a unwind + ///table +DECLARE_LLVM_ATTRIBUTE(NonLazyBind,1U<<31) ///< Function is called early and/or + /// often, so lazy binding isn't + /// worthwhile. +DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is on. + +#undef DECLARE_LLVM_ATTRIBUTE /// Note that uwtable is about the ABI or the user mandating an entry in the /// unwind table. The nounwind attribute is about an exception passing by the @@ -126,24 +154,26 @@ /// uwtable + nounwind = Needs an entry because the ABI says so. /// @brief Attributes that only apply to function parameters. -const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture; +const AttrConst ParameterOnly = {ByVal_i | Nest_i | + StructRet_i | NoCapture_i}; /// @brief Attributes that may be applied to the function itself. These cannot /// be used on return values or function parameters. -const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly | - NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq | - NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment | - UWTable | NonLazyBind | ReturnsTwice | AddressSafety; +const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i | + ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i | + StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i | + Naked_i | InlineHint_i | StackAlignment_i | + UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i}; /// @brief Parameter attributes that do not apply to vararg call arguments. -const Attributes VarArgsIncompatible = StructRet; +const AttrConst VarArgsIncompatible = {StructRet_i}; /// @brief Attributes that are mutually incompatible. -const Attributes MutuallyIncompatible[4] = { - ByVal | InReg | Nest | StructRet, - ZExt | SExt, - ReadNone | ReadOnly, - NoInline | AlwaysInline +const AttrConst MutuallyIncompatible[4] = { + {ByVal_i | InReg_i | Nest_i | StructRet_i}, + {ZExt_i | SExt_i}, + {ReadNone_i | ReadOnly_i}, + {NoInline_i | AlwaysInline_i} }; /// @brief Which attributes cannot be applied to a type. From dreynaud at apple.com Tue Feb 7 19:20:24 2012 From: dreynaud at apple.com (Daniel Reynaud) Date: Tue, 07 Feb 2012 17:20:24 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers Message-ID: This is a patch for http://llvm.org/bugs/show_bug.cgi?id=11919 It seems to do the trick for me. When this particular configuration (a global initializer references a blockaddress from a function that has been sent to a different module) is not encountered, it should produce the same initializer pattern as usual (i.e., everything in the safe module). thanks, daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/97ff5485/attachment.html From dreynaud at apple.com Tue Feb 7 19:21:41 2012 From: dreynaud at apple.com (Daniel Reynaud) Date: Tue, 07 Feb 2012 17:21:41 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers In-Reply-To: References: Message-ID: Even better with the actual patch. On Feb 7, 2012, at 5:20 PM, Daniel Reynaud wrote: > This is a patch for http://llvm.org/bugs/show_bug.cgi?id=11919 > > It seems to do the trick for me. When this particular configuration (a global initializer references a blockaddress from a function that has been sent to a different module) is not encountered, it should produce the same initializer pattern as usual (i.e., everything in the safe module). > > thanks, > daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/b1a840df/attachment.html -------------- next part -------------- A non-text attachment was scrubbed... Name: bugpoint.patch Type: application/octet-stream Size: 2745 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/b1a840df/attachment.obj -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/b1a840df/attachment-0001.html From eli.friedman at gmail.com Tue Feb 7 19:44:38 2012 From: eli.friedman at gmail.com (Eli Friedman) Date: Tue, 7 Feb 2012 17:44:38 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers In-Reply-To: References: Message-ID: On Tue, Feb 7, 2012 at 5:21 PM, Daniel Reynaud wrote: > Even better with the actual patch. > > > > On Feb 7, 2012, at 5:20 PM, Daniel Reynaud wrote: > > This is a patch for?http://llvm.org/bugs/show_bug.cgi?id=11919 > > It seems to do the trick for me. When this particular configuration (a > global initializer references a blockaddress from a function that has been > sent to a different module) is not encountered, it should produce the same > initializer pattern as usual (i.e., everything in the safe module). > > thanks, > daniel + bool globalInitUsesExternalBA(GlobalVariable* GV) { + if (!GV->hasInitializer()) + return false; + + Constant *I = GV->getInitializer(); + + // walk the values used by the initializer + // (and recurse into things like ConstantExpr) + std::vector Worklist; + Worklist.push_back(I); + while(!Worklist.empty()) { + Constant* V = Worklist.back(); + Worklist.pop_back(); + + if (BlockAddress *BA = dyn_cast(V)) { + Function *F = BA->getFunction(); + if (F->isDeclaration()) + return true; + } + + for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) + if (Constant *C = dyn_cast(*i)) + Worklist.push_back(C); + } + + return false; + } You need to make sure not to recurse into GlobalValues. You also probably want a hashtable so you don't run into bad performance characteristics with ConstantExprs. Also, weird indentation. + // Try to split the global initializers evenly + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) { + GlobalVariable *GV = cast(NewVMap[I]); + if (globalInitUsesExternalBA(I)) { + assert(!globalInitUsesExternalBA(GV) && "A global initializer references" + "functions in both the safe and the test module"); I don't see what prevents this assertion from triggering... -Eli From sabre at nondot.org Tue Feb 7 19:44:00 2012 From: sabre at nondot.org (Chris Lattner) Date: Wed, 08 Feb 2012 01:44:00 -0000 Subject: [llvm-commits] [llvm] r150037 - /llvm/trunk/docs/CodingStandards.html Message-ID: <20120208014400.CDC242A6C12C@llvm.org> Author: lattner Date: Tue Feb 7 19:44:00 2012 New Revision: 150037 URL: http://llvm.org/viewvc/llvm-project?rev=150037&view=rev Log: add an explicit section on static constructors. Modified: llvm/trunk/docs/CodingStandards.html Modified: llvm/trunk/docs/CodingStandards.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CodingStandards.html?rev=150037&r1=150036&r2=150037&view=diff ============================================================================== --- llvm/trunk/docs/CodingStandards.html (original) +++ llvm/trunk/docs/CodingStandards.html Tue Feb 7 19:44:00 2012 @@ -31,6 +31,7 @@ Errors
      • Write Portable Code
      • Do not use RTTI or Exceptions
      • +
      • Do not use Static Constructors
      • Use of class/struct Keywords
      • @@ -449,6 +450,51 @@

        +Do not use Static Constructors +

        +
        + +

        Static constructors and destructors (e.g. global variables whose types have +a constructor or destructor) should not be added to the code base, and should be +removed wherever possible. Besides well known problems +where the order of initialization is undefined between globals in different +source files, the entire concept of static constructors is at odds with the +common use case of LLVM as a library linked into a larger application.

        + +

        Consider the use of LLVM as a JIT linked into another application (perhaps +for OpenGL, custom languages, +shaders in +movies, etc). Due to the design of static constructors, they must be +executed at startup time of the entire application, regardless of whether or +how LLVM is used in that larger application. There are two problems with +this:

        + +
          +
        1. The time to run the static constructors impacts startup time of + applications — a critical time for GUI apps, among others.
        2. + +
        3. The static constructors cause the app to pull many extra pages of memory + off the disk: both the code for the constructor in each .o file and + the small amount of data that gets touched. In addition, touched/dirty pages + put more pressure on the VM system on low-memory machines.
        4. +
        + +

        We would really like for there to be zero cost for linking in an additional +LLVM target or other library into an application, but static constructors +violate this goal.

        + +

        That said, LLVM unfortunately does contain static constructors. It would be +a great project for someone to purge all +static constructors from LLVM, and then enable the +-Wglobal-constructors warning flag (when building with Clang) to ensure +we do not regress in the future. +

        + +
        + + +

        Use of class and struct Keywords

        @@ -1151,22 +1197,10 @@

        The use of #include <iostream> in library files is -hereby forbidden. The primary reason for doing this is to -support clients using LLVM libraries as part of larger systems. In particular, -we statically link LLVM into some dynamic libraries. Even if LLVM isn't used, -the static constructors are run whenever an application starts up that uses the -dynamic library. There are two problems with this:

        - -
          -
        1. The time to run the static c'tors impacts startup time of applications - — a critical time for GUI apps.
        2. - -
        3. The static c'tors cause the app to pull many extra pages of memory off the - disk: both the code for the static c'tors in each .o file and the - small amount of data that gets touched. In addition, touched/dirty pages - put more pressure on the VM system on low-memory machines.
        4. -
        - +hereby forbidden, because many common implementations +transparently inject a static constructor into +every translation unit that includes it.

        +

        Note that using the other stream headers (<sstream> for example) is not problematic in this regard — just <iostream>. However, raw_ostream provides various From sabre at nondot.org Tue Feb 7 19:45:48 2012 From: sabre at nondot.org (Chris Lattner) Date: Wed, 08 Feb 2012 01:45:48 -0000 Subject: [llvm-commits] [www] r150038 - /www/trunk/OpenProjects.html Message-ID: <20120208014548.9BB062A6C12C@llvm.org> Author: lattner Date: Tue Feb 7 19:45:48 2012 New Revision: 150038 URL: http://llvm.org/viewvc/llvm-project?rev=150038&view=rev Log: another code-cleanup bug. Modified: www/trunk/OpenProjects.html Modified: www/trunk/OpenProjects.html URL: http://llvm.org/viewvc/llvm-project/www/trunk/OpenProjects.html?rev=150038&r1=150037&r2=150038&view=diff ============================================================================== --- www/trunk/OpenProjects.html (original) +++ www/trunk/OpenProjects.html Tue Feb 7 19:45:48 2012 @@ -122,6 +122,7 @@

      • Fix the design of GlobalAlias to not require dest type to match source type
      • Redesign ConstantExpr's
      • SimplifyLibCalls should be merged into instcombine
      • +
      • Static constructors should be purged from LLVM

      From atrick at apple.com Tue Feb 7 20:17:16 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 02:17:16 -0000 Subject: [llvm-commits] [llvm] r150041 - /llvm/trunk/lib/CodeGen/MachineScheduler.cpp Message-ID: <20120208021716.8D2F32A6C12C@llvm.org> Author: atrick Date: Tue Feb 7 20:17:16 2012 New Revision: 150041 URL: http://llvm.org/viewvc/llvm-project?rev=150041&view=rev Log: stale comment Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=150041&r1=150040&r2=150041&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Tue Feb 7 20:17:16 2012 @@ -242,8 +242,6 @@ Begin = MI; } - // TODO: Update live intervals. - // Release dependent instructions for scheduling. releaseSuccessors(SU); } From atrick at apple.com Tue Feb 7 20:17:19 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 02:17:19 -0000 Subject: [llvm-commits] [llvm] r150042 - /llvm/trunk/include/llvm/CodeGen/MachineInstr.h Message-ID: <20120208021719.4D4A32A6C12C@llvm.org> Author: atrick Date: Tue Feb 7 20:17:18 2012 New Revision: 150042 URL: http://llvm.org/viewvc/llvm-project?rev=150042&view=rev Log: whitespace Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=150042&r1=150041&r2=150042&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Tue Feb 7 20:17:18 2012 @@ -190,11 +190,11 @@ /// ---------------- /// | /// ---------------- - /// | MI * | + /// | MI * | /// ---------------- /// | /// ---------------- - /// | MI * | + /// | MI * | /// ---------------- /// In this case, the first MI starts a bundle but is not inside a bundle, the /// next 2 MIs are considered "inside" the bundle. @@ -209,11 +209,11 @@ /// ---------------- /// | /// ---------------- - /// | MI * | + /// | MI * | /// ---------------- /// | /// ---------------- - /// | MI * | + /// | MI * | /// ---------------- /// The first instruction has the special opcode "BUNDLE". It's not "inside" /// a bundle, but the next three MIs are. From atrick at apple.com Tue Feb 7 20:17:25 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 02:17:25 -0000 Subject: [llvm-commits] [llvm] r150044 - in /llvm/trunk: include/llvm/CodeGen/MachineInstr.h lib/CodeGen/LiveIntervalAnalysis.cpp lib/CodeGen/MachineInstr.cpp Message-ID: <20120208021725.CC5BC2A6C12E@llvm.org> Author: atrick Date: Tue Feb 7 20:17:25 2012 New Revision: 150044 URL: http://llvm.org/viewvc/llvm-project?rev=150044&view=rev Log: Added MachineInstr::isBundled() to check if an instruction is part of a bundle. Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/MachineInstr.cpp Modified: llvm/trunk/include/llvm/CodeGen/MachineInstr.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineInstr.h?rev=150044&r1=150043&r2=150044&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/MachineInstr.h (original) +++ llvm/trunk/include/llvm/CodeGen/MachineInstr.h Tue Feb 7 20:17:25 2012 @@ -230,6 +230,10 @@ clearFlag(InsideBundle); } + /// isBundled - Return true if this instruction part of a bundle. This is true + /// if either itself or its following instruction is marked "InsideBundle". + bool isBundled() const; + /// getDebugLoc - Returns the debug location id of this MachineInstr. /// DebugLoc getDebugLoc() const { return debugLoc; } Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150044&r1=150043&r2=150044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Tue Feb 7 20:17:25 2012 @@ -904,7 +904,7 @@ assert((insertPt == mbb->end() || insertPt->getParent() == mbb) && "Cannot handle moves across basic block boundaries."); assert(&*insertPt != mi && "No-op move requested?"); - assert(!mi->isInsideBundle() && "Can't handle bundled instructions yet."); + assert(!mi->isBundled() && "Can't handle bundled instructions yet."); // Grab the original instruction index. SlotIndex origIdx = indexes_->getInstructionIndex(mi); Modified: llvm/trunk/lib/CodeGen/MachineInstr.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstr.cpp?rev=150044&r1=150043&r2=150044&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstr.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstr.cpp Tue Feb 7 20:17:25 2012 @@ -890,6 +890,16 @@ return NumOperands; } +/// isBundled - Return true if this instruction part of a bundle. This is true +/// if either itself or its following instruction is marked "InsideBundle". +bool MachineInstr::isBundled() const { + if (isInsideBundle()) + return true; + MachineBasicBlock::const_instr_iterator nextMI = this; + ++nextMI; + return nextMI != Parent->instr_end() && nextMI->isInsideBundle(); +} + bool MachineInstr::isStackAligningInlineAsm() const { if (isInlineAsm()) { unsigned ExtraInfo = getOperand(InlineAsm::MIOp_ExtraInfo).getImm(); From atrick at apple.com Tue Feb 7 20:17:21 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 02:17:21 -0000 Subject: [llvm-commits] [llvm] r150043 - /llvm/trunk/lib/CodeGen/MachineScheduler.cpp Message-ID: <20120208021721.B991A2A6C12D@llvm.org> Author: atrick Date: Tue Feb 7 20:17:21 2012 New Revision: 150043 URL: http://llvm.org/viewvc/llvm-project?rev=150043&view=rev Log: misched: bug in debug output. Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=150043&r1=150042&r2=150043&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Tue Feb 7 20:17:21 2012 @@ -293,8 +293,10 @@ continue; } DEBUG(dbgs() << "MachineScheduling " << MF->getFunction()->getName() - << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: " - << *RegionEnd << " Remaining: " << RemainingCount << "\n"); + << ":BB#" << MBB->getNumber() << "\n From: " << *I << " To: "; + if (RegionEnd != MBB->end()) dbgs() << *RegionEnd; + else dbgs() << "End"; + dbgs() << " Remaining: " << RemainingCount << "\n"); // Inform ScheduleDAGInstrs of the region being scheduled. It calls back // to our Schedule() method. From mcrosier at apple.com Tue Feb 7 20:29:21 2012 From: mcrosier at apple.com (Chad Rosier) Date: Wed, 08 Feb 2012 02:29:21 -0000 Subject: [llvm-commits] [llvm] r150045 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-binary.ll Message-ID: <20120208022921.C2D582A6C12C@llvm.org> Author: mcrosier Date: Tue Feb 7 20:29:21 2012 New Revision: 150045 URL: http://llvm.org/viewvc/llvm-project?rev=150045&view=rev Log: [fast-isel] Add support for ORs with non-legal types. Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=150045&r1=150044&r2=150045&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Tue Feb 7 20:29:21 2012 @@ -1733,7 +1733,6 @@ } bool ARMFastISel::SelectBinaryIntOp(const Instruction *I, unsigned ISDOpcode) { - assert (ISDOpcode == ISD::ADD && "Expected an add."); EVT DestVT = TLI.getValueType(I->getType(), true); // We can get here in the case when we have a binary operation on a non-legal @@ -1741,6 +1740,17 @@ if (DestVT != MVT::i16 && DestVT != MVT::i8 && DestVT != MVT::i1) return false; + unsigned Opc; + switch (ISDOpcode) { + default: return false; + case ISD::ADD: + Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr; + break; + case ISD::OR: + Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr; + break; + } + unsigned SrcReg1 = getRegForValue(I->getOperand(0)); if (SrcReg1 == 0) return false; @@ -1749,7 +1759,6 @@ unsigned SrcReg2 = getRegForValue(I->getOperand(1)); if (SrcReg2 == 0) return false; - unsigned Opc = isThumb2 ? ARM::t2ADDrr : ARM::ADDrr; unsigned ResultReg = createResultReg(TLI.getRegClassFor(MVT::i32)); AddOptionalDefs(BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DL, TII.get(Opc), ResultReg) @@ -2498,6 +2507,8 @@ return SelectFPToI(I, /*isSigned*/ false); case Instruction::Add: return SelectBinaryIntOp(I, ISD::ADD); + case Instruction::Or: + return SelectBinaryIntOp(I, ISD::OR); case Instruction::FAdd: return SelectBinaryFPOp(I, ISD::FADD); case Instruction::FSub: Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll?rev=150045&r1=150044&r2=150045&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Tue Feb 7 20:29:21 2012 @@ -38,3 +38,39 @@ store i16 %0, i16* %a.addr, align 4 ret void } + +define void @or_i1(i1 %a, i1 %b) nounwind ssp { +entry: +; ARM: or_i1 +; THUMB: or_i1 + %a.addr = alloca i1, align 4 + %0 = or i1 %a, %b +; ARM: orr r0, r0, r1 +; THUMB: orrs r0, r1 + store i1 %0, i1* %a.addr, align 4 + ret void +} + +define void @or_i8(i8 %a, i8 %b) nounwind ssp { +entry: +; ARM: or_i8 +; THUMB: or_i8 + %a.addr = alloca i8, align 4 + %0 = or i8 %a, %b +; ARM: orr r0, r0, r1 +; THUMB: orrs r0, r1 + store i8 %0, i8* %a.addr, align 4 + ret void +} + +define void @or_i16(i16 %a, i16 %b) nounwind ssp { +entry: +; ARM: or_i16 +; THUMB: or_i16 + %a.addr = alloca i16, align 4 + %0 = or i16 %a, %b +; ARM: orr r0, r0, r1 +; THUMB: orrs r0, r1 + store i16 %0, i16* %a.addr, align 4 + ret void +} From mcrosier at apple.com Tue Feb 7 20:30:12 2012 From: mcrosier at apple.com (Chad Rosier) Date: Wed, 08 Feb 2012 02:30:12 -0000 Subject: [llvm-commits] [llvm] r150046 - /llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Message-ID: <20120208023012.762C72A6C12C@llvm.org> Author: mcrosier Date: Tue Feb 7 20:30:12 2012 New Revision: 150046 URL: http://llvm.org/viewvc/llvm-project?rev=150046&view=rev Log: Add comment to test case. Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll?rev=150046&r1=150045&r2=150046&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Tue Feb 7 20:30:12 2012 @@ -39,6 +39,8 @@ ret void } +; Test or with non-legal types + define void @or_i1(i1 %a, i1 %b) nounwind ssp { entry: ; ARM: or_i1 From mcrosier at apple.com Tue Feb 7 20:45:45 2012 From: mcrosier at apple.com (Chad Rosier) Date: Wed, 08 Feb 2012 02:45:45 -0000 Subject: [llvm-commits] [llvm] r150047 - in /llvm/trunk: lib/Target/ARM/ARMFastISel.cpp test/CodeGen/ARM/fast-isel-binary.ll Message-ID: <20120208024545.12B8E2A6C12C@llvm.org> Author: mcrosier Date: Tue Feb 7 20:45:44 2012 New Revision: 150047 URL: http://llvm.org/viewvc/llvm-project?rev=150047&view=rev Log: [fast-isel] Add support for SUBs with non-legal types. Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Modified: llvm/trunk/lib/Target/ARM/ARMFastISel.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMFastISel.cpp?rev=150047&r1=150046&r2=150047&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMFastISel.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMFastISel.cpp Tue Feb 7 20:45:44 2012 @@ -1749,6 +1749,9 @@ case ISD::OR: Opc = isThumb2 ? ARM::t2ORRrr : ARM::ORRrr; break; + case ISD::SUB: + Opc = isThumb2 ? ARM::t2SUBrr : ARM::SUBrr; + break; } unsigned SrcReg1 = getRegForValue(I->getOperand(0)); @@ -2509,6 +2512,8 @@ return SelectBinaryIntOp(I, ISD::ADD); case Instruction::Or: return SelectBinaryIntOp(I, ISD::OR); + case Instruction::Sub: + return SelectBinaryIntOp(I, ISD::SUB); case Instruction::FAdd: return SelectBinaryFPOp(I, ISD::FADD); case Instruction::FSub: Modified: llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll?rev=150047&r1=150046&r2=150047&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll (original) +++ llvm/trunk/test/CodeGen/ARM/fast-isel-binary.ll Tue Feb 7 20:45:44 2012 @@ -76,3 +76,41 @@ store i16 %0, i16* %a.addr, align 4 ret void } + +; Test sub with non-legal types + +define void @sub_i1(i1 %a, i1 %b) nounwind ssp { +entry: +; ARM: sub_i1 +; THUMB: sub_i1 + %a.addr = alloca i1, align 4 + %0 = sub i1 %a, %b +; ARM: sub r0, r0, r1 +; THUMB: subs r0, r0, r1 + store i1 %0, i1* %a.addr, align 4 + ret void +} + +define void @sub_i8(i8 %a, i8 %b) nounwind ssp { +entry: +; ARM: sub_i8 +; THUMB: sub_i8 + %a.addr = alloca i8, align 4 + %0 = sub i8 %a, %b +; ARM: sub r0, r0, r1 +; THUMB: subs r0, r0, r1 + store i8 %0, i8* %a.addr, align 4 + ret void +} + +define void @sub_i16(i16 %a, i16 %b) nounwind ssp { +entry: +; ARM: sub_i16 +; THUMB: sub_i16 + %a.addr = alloca i16, align 4 + %0 = sub i16 %a, %b +; ARM: sub r0, r0, r1 +; THUMB: subs r0, r0, r1 + store i16 %0, i16* %a.addr, align 4 + ret void +} From eli.bendersky at intel.com Tue Feb 7 23:59:39 2012 From: eli.bendersky at intel.com (Bendersky, Eli) Date: Wed, 8 Feb 2012 05:59:39 +0000 Subject: [llvm-commits] RuntimeDyLd new features In-Reply-To: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> References: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> Message-ID: <9BBE4537D1BAAB479E9E8F9D4234619D33ADF4@HASMSX103.ger.corp.intel.com> Hi Danil, We're currently working on getting MCJIT running on ELF (http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046671.html), and a couple of patches were already committed. There's another patch, currently pending a review (http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120130/135997.html) with further changes that make MCJIT on ELF (Linux) pass 100% of ExecutionEngine tests (all the same tests JIT passes), as well as supporting MCJIT debugging with GDB. How does your patch relate to this work? It may be a good idea to discuss all the requirements and possible solutions and come up with a design that suits everyone. Otherwise it's hard to review and reason about several large & conflicting patches to the same area of code. Eli From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Danil Malyshev Sent: Tuesday, February 07, 2012 22:24 To: llvm-commits at cs.uiuc.edu Subject: [llvm-commits] RuntimeDyLd new features Hello everyone, Please review the RuntimeDyLd-01.patch. This patch makes the following changes: 1. The main works will made in the RuntimeDyLdImpl with uses the ObjectFile class. RuntimeDyLdMachO and RuntimeDyLdELF now only parses relocations and resolve it. This is allows to make improvements of the RuntimeDyLd more easily. In addition the support for COFF can be easily added. 2. Added ARM relocations to RuntimeDyLdELF. 3. Added support for stub functions for the ARM, allowing to do a long branch. 4. Added support for external functions that are not loaded from the object files, but can be loaded from external libraries. Now MCJIT can correctly execute the code containing the printf, putc, and etc. 5. The sections emitted instead functions, thanks Jim Grosbach. MemoryManager.startFunctionBody() and MemoryManager.endFunctionBody() have been removed. 6. MCJITMemoryManager.allocateDataSection() and MCJITMemoryManager. allocateCodeSection() used JMM->allocateSpace() instead of JMM->allocateCodeSection() and JMM->allocateDataSection(), because I got an error: "Cannot allocate an allocated block!" with object file contains more than one code or data sections. 7. Fixed ELF::R_X86_64_PC32 relocation for the case when RealOffset is negative value. 8. Added new testing folder: ExecutionEngine/MCJIT because mcjit tests can be running only for x86 and arm and it's can be filtered with dg.exp. Tested in Ubuntu x86_64, Ubuntu armv7 and MacOS 64. Thank you, Danil --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/8d1ddcc9/attachment.html From eli.bendersky at intel.com Wed Feb 8 00:12:33 2012 From: eli.bendersky at intel.com (Bendersky, Eli) Date: Wed, 8 Feb 2012 06:12:33 +0000 Subject: [llvm-commits] [PATCH] JIT profiling support with Intel Parallel Amplifier XE 2011 (VTune) In-Reply-To: <9BBE4537D1BAAB479E9E8F9D4234619D334B2B@HASMSX103.ger.corp.intel.com> References: <9BBE4537D1BAAB479E9E8F9D4234619D326470@HASMSX103.ger.corp.intel.com> <9BBE4537D1BAAB479E9E8F9D4234619D334B2B@HASMSX103.ger.corp.intel.com> Message-ID: <9BBE4537D1BAAB479E9E8F9D4234619D33AE3F@HASMSX103.ger.corp.intel.com> Ping! > -----Original Message----- > From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits- > bounces at cs.uiuc.edu] On Behalf Of Bendersky, Eli > Sent: Friday, February 03, 2012 05:18 > To: llvm-commits at cs.uiuc.edu > Subject: Re: [llvm-commits] [PATCH] JIT profiling support with Intel Parallel > Amplifier XE 2011 (VTune) > > Ping! > > > -----Original Message----- > > From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits- > > bounces at cs.uiuc.edu] On Behalf Of Bendersky, Eli > > Sent: Tuesday, January 31, 2012 11:19 > > To: llvm-commits at cs.uiuc.edu > > Subject: [llvm-commits] [PATCH] JIT profiling support with Intel > > Parallel Amplifier XE 2011 (VTune) > > > > Hello, > > > > Currently the only profiling LLVM JITted code support is via OProfile. > > This patch adds profiling support for Intel Parallel Amplifier XE 2011 > > (used to be called "VTune"), does some refactoring to share code > > between the implementations, and adds unit tests both for the existing > > OProfile interface and the new Amplifier XE interface. In more detail: > > > > - Added Intel JIT Events API compatible JITEventListener, and allow > > OProfileJITEventListener to load libopagent.so at runtime > > - Removed link-time requirement on libopagent when building with > > OProfile support > > - Added Intel JIT API and OProfile support to cmake builds (Boolean > > options LLVM_USE_OPROFILE and LLVM_USE_INTEL_JITEVENTS) > > - Added IntelJITEventListener to connect to Intel JIT API (support for > > profiling with Parallel Amplifier XE 2011) > > - Added unit tests for both IntelJIT and OProfile JITEventListener > > implementations which can still be run in the absence the respective > > 3rd party libraries > > > > The change was broken into several patches. The first contains the new > > implementation and tests. The others are build system changes to > > incorporate the new code. > > > > This is essentially similar to the patch sent by Daniel Malea in the > > beginning of December, but which unfortunately hasn't received a > > reply. We updated it to cleanly apply to SVN trunk. > > > > Please review > > > > Eli > > > > > > --------------------------------------------------------------------- > > Intel Israel (74) Limited > > > > This e-mail and any attachments may contain confidential material for > > the sole use of the intended recipient(s). Any review or distribution > > by others is strictly prohibited. If you are not the intended > > recipient, please contact the sender and delete all copies. > --------------------------------------------------------------------- > Intel Israel (74) Limited > > This e-mail and any attachments may contain confidential material for the > sole use of the intended recipient(s). Any review or distribution by others is > strictly prohibited. If you are not the intended recipient, please contact the > sender and delete all copies. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From craig.topper at gmail.com Wed Feb 8 00:36:57 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 08 Feb 2012 06:36:57 -0000 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td Message-ID: <20120208063657.D34492A6C12C@llvm.org> Author: ctopper Date: Wed Feb 8 00:36:57 2012 New Revision: 150060 URL: http://llvm.org/viewvc/llvm-project?rev=150060&view=rev Log: Remove GCC builtins for vpermilp* intrinsics as clang no longer needs them. Custom lower the intrinsics to the vpermilp target specific node and remove intrinsic patterns. Modified: llvm/trunk/include/llvm/IntrinsicsX86.td llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/include/llvm/IntrinsicsX86.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff ============================================================================== --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 @@ -1092,17 +1092,17 @@ Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, + def int_x86_avx_vpermil_pd : Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, + def int_x86_avx_vpermil_ps : Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_pd_256 : GCCBuiltin<"__builtin_ia32_vpermilpd256">, + def int_x86_avx_vpermil_pd_256 : Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>; - def int_x86_avx_vpermil_ps_256 : GCCBuiltin<"__builtin_ia32_vpermilps256">, + def int_x86_avx_vpermil_ps_256 : Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>; } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 2012 @@ -9488,6 +9488,12 @@ case Intrinsic::x86_avx2_vperm2i128: return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), Op.getOperand(1), Op.getOperand(2), Op.getOperand(3)); + case Intrinsic::x86_avx_vpermil_ps: + case Intrinsic::x86_avx_vpermil_pd: + case Intrinsic::x86_avx_vpermil_ps_256: + case Intrinsic::x86_avx_vpermil_pd_256: + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), + Op.getOperand(1), Op.getOperand(2)); // ptest and testp intrinsics. The intrinsic these come from are designed to // return an integer value, not just an instruction so lower it to the ptest Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 @@ -7129,8 +7129,8 @@ // multiclass avx_permil opc_rm, bits<8> opc_rmi, string OpcodeStr, RegisterClass RC, X86MemOperand x86memop_f, - X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag, - Intrinsic IntVar, Intrinsic IntImm> { + X86MemOperand x86memop_i, PatFrag i_frag, + Intrinsic IntVar, ValueType vt> { def rr : AVX8I, VEX; + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 imm:$src2))))]>, VEX; def mi : AVXAIi8, VEX; + [(set RC:$dst, + (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, VEX; } let ExeDomain = SSEPackedSingle in { defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem, - memopv4f32, memopv2i64, - int_x86_avx_vpermilvar_ps, - int_x86_avx_vpermil_ps>; + memopv2i64, int_x86_avx_vpermilvar_ps, v4f32>; defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem, - memopv8f32, memopv4i64, - int_x86_avx_vpermilvar_ps_256, - int_x86_avx_vpermil_ps_256>; + memopv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>; } let ExeDomain = SSEPackedDouble in { defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem, - memopv2f64, memopv2i64, - int_x86_avx_vpermilvar_pd, - int_x86_avx_vpermil_pd>; + memopv2i64, int_x86_avx_vpermilvar_pd, v2f64>; defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem, - memopv4f64, memopv4i64, - int_x86_avx_vpermilvar_pd_256, - int_x86_avx_vpermil_pd_256>; + memopv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>; } let Predicates = [HasAVX] in { -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), - (VPERMILPSYri VR256:$src1, imm:$imm)>; -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), - (VPERMILPDYri VR256:$src1, imm:$imm)>; def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), (VPERMILPSYri VR256:$src1, imm:$imm)>; def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), (VPERMILPDYri VR256:$src1, imm:$imm)>; -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), - (VPERMILPSYmi addr:$src1, imm:$imm)>; -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), - (VPERMILPDYmi addr:$src1, imm:$imm)>; def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), (i8 imm:$imm))), (VPERMILPSYmi addr:$src1, imm:$imm)>; def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), (VPERMILPDYmi addr:$src1, imm:$imm)>; -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), - (VPERMILPSri VR128:$src1, imm:$imm)>; -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), - (VPERMILPDri VR128:$src1, imm:$imm)>; def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), (VPERMILPDri VR128:$src1, imm:$imm)>; -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), - (VPERMILPSmi addr:$src1, imm:$imm)>; -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), - (VPERMILPDmi addr:$src1, imm:$imm)>; def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), (VPERMILPDmi addr:$src1, imm:$imm)>; } From baldrick at free.fr Wed Feb 8 00:50:00 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 06:50:00 -0000 Subject: [llvm-commits] [zorg] r150062 - /zorg/trunk/buildbot/osuosl/master/config/builders.py Message-ID: <20120208065000.522262A6C12C@llvm.org> Author: baldrick Date: Wed Feb 8 00:50:00 2012 New Revision: 150062 URL: http://llvm.org/viewvc/llvm-project?rev=150062&view=rev Log: It looks like this machine is running out of memory when linking LLVM. Try building with optimization enabled. Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py Modified: zorg/trunk/buildbot/osuosl/master/config/builders.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/buildbot/osuosl/master/config/builders.py?rev=150062&r1=150061&r2=150062&view=diff ============================================================================== --- zorg/trunk/buildbot/osuosl/master/config/builders.py (original) +++ zorg/trunk/buildbot/osuosl/master/config/builders.py Wed Feb 8 00:50:00 2012 @@ -58,7 +58,8 @@ 'slavenames': ["gcc15"], 'builddir': "llvm-i686-debian", 'factory': LLVMBuilder.getLLVMBuildFactory("i686-pc-linux-gnu", - env = { 'CC' : "gcc -m32", 'CXX' : "g++ -m32" })}, + config_name = 'Release+Asserts', + env = { 'CC' : "gcc -m32", 'CXX' : "g++ -m32" })}, {'name': "llvm-x86_64-ubuntu", 'slavenames':["arxan_davinci"], 'builddir':"llvm-x86_64-ubuntu", From samsonov at google.com Wed Feb 8 01:11:02 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 07:11:02 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf3074b1822d678b04b86e99b9@google.com> http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h File lib/asan/asan_procmaps.h (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode30 lib/asan/asan_procmaps.h:30: // and puts it into the given buffer with a leading space On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > I know this may sound a bit confusing, but look at how easy it is to use this > function now (asan_stack.cc, which is the only place this is used) I think it's weird to write leading space here. "puts"->"writes"? http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode32 lib/asan/asan_procmaps.h:32: void DescribeAddress(uintptr_t addr, char out_buffer[], size_t buffer_size); Why not GetAddressDescription()? We've got two other different DescribeAddress functions already :) http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc File lib/asan/asan_stack.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc#newcode47 lib/asan/asan_stack.cc:47: Printf(" #%ld 0x%lx%s\n", i, pc, descr); Why not write space here? http://codereview.appspot.com/5643047/ From baldrick at free.fr Wed Feb 8 01:30:33 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 08:30:33 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <20120208063657.D34492A6C12C@llvm.org> References: <20120208063657.D34492A6C12C@llvm.org> Message-ID: <4F322499.2060706@free.fr> Hi Craig, > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs them. Custom lower the intrinsics to the vpermilp target specific node and remove intrinsic patterns. what about auto-upgrade? Ciao, Duncan. > > Modified: > llvm/trunk/include/llvm/IntrinsicsX86.td > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > llvm/trunk/lib/Target/X86/X86InstrSSE.td > > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > @@ -1092,17 +1092,17 @@ > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, > + def int_x86_avx_vpermil_pd : > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > llvm_i8_ty], [IntrNoMem]>; > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, > + def int_x86_avx_vpermil_ps : > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_pd_256 : GCCBuiltin<"__builtin_ia32_vpermilpd256">, > + def int_x86_avx_vpermil_pd_256 : > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > llvm_i8_ty], [IntrNoMem]>; > - def int_x86_avx_vpermil_ps_256 : GCCBuiltin<"__builtin_ia32_vpermilps256">, > + def int_x86_avx_vpermil_ps_256 : > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > llvm_i8_ty], [IntrNoMem]>; > } > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 2012 > @@ -9488,6 +9488,12 @@ > case Intrinsic::x86_avx2_vperm2i128: > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), > Op.getOperand(1), Op.getOperand(2), Op.getOperand(3)); > + case Intrinsic::x86_avx_vpermil_ps: > + case Intrinsic::x86_avx_vpermil_pd: > + case Intrinsic::x86_avx_vpermil_ps_256: > + case Intrinsic::x86_avx_vpermil_pd_256: > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > + Op.getOperand(1), Op.getOperand(2)); > > // ptest and testp intrinsics. The intrinsic these come from are designed to > // return an integer value, not just an instruction so lower it to the ptest > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff > ============================================================================== > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 > @@ -7129,8 +7129,8 @@ > // > multiclass avx_permil opc_rm, bits<8> opc_rmi, string OpcodeStr, > RegisterClass RC, X86MemOperand x86memop_f, > - X86MemOperand x86memop_i, PatFrag f_frag, PatFrag i_frag, > - Intrinsic IntVar, Intrinsic IntImm> { > + X86MemOperand x86memop_i, PatFrag i_frag, > + Intrinsic IntVar, ValueType vt> { > def rr : AVX8I (ins RC:$src1, RC:$src2), > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), > @@ -7144,63 +7144,40 @@ > def ri : AVXAIi8 (ins RC:$src1, i8imm:$src2), > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 imm:$src2))))]>, VEX; > def mi : AVXAIi8 (ins x86memop_f:$src1, i8imm:$src2), > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), > - [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX; > + [(set RC:$dst, > + (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, VEX; > } > > let ExeDomain = SSEPackedSingle in { > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, i128mem, > - memopv4f32, memopv2i64, > - int_x86_avx_vpermilvar_ps, > - int_x86_avx_vpermil_ps>; > + memopv2i64, int_x86_avx_vpermilvar_ps, v4f32>; > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, i256mem, > - memopv8f32, memopv4i64, > - int_x86_avx_vpermilvar_ps_256, > - int_x86_avx_vpermil_ps_256>; > + memopv4i64, int_x86_avx_vpermilvar_ps_256, v8f32>; > } > let ExeDomain = SSEPackedDouble in { > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, i128mem, > - memopv2f64, memopv2i64, > - int_x86_avx_vpermilvar_pd, > - int_x86_avx_vpermil_pd>; > + memopv2i64, int_x86_avx_vpermilvar_pd, v2f64>; > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, i256mem, > - memopv4f64, memopv4i64, > - int_x86_avx_vpermilvar_pd_256, > - int_x86_avx_vpermil_pd_256>; > + memopv4i64, int_x86_avx_vpermilvar_pd_256, v4f64>; > } > > let Predicates = [HasAVX] in { > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > (VPERMILPSYri VR256:$src1, imm:$imm)>; > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > (VPERMILPDYri VR256:$src1, imm:$imm)>; > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > (i8 imm:$imm))), > (VPERMILPSYmi addr:$src1, imm:$imm)>; > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > - (VPERMILPSri VR128:$src1, imm:$imm)>; > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > - (VPERMILPDri VR128:$src1, imm:$imm)>; > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > (VPERMILPDri VR128:$src1, imm:$imm)>; > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > - (VPERMILPSmi addr:$src1, imm:$imm)>; > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > - (VPERMILPDmi addr:$src1, imm:$imm)>; > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > (VPERMILPDmi addr:$src1, imm:$imm)>; > } > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From samsonov at google.com Wed Feb 8 01:35:54 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 07:35:54 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf3074b31e1e870304b86ef298@google.com> http://codereview.appspot.com/5642046/diff/1/interception/interception.h File interception/interception.h (right): http://codereview.appspot.com/5642046/diff/1/interception/interception.h#newcode100 interception/interception.h:100: bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); On 2012/02/07 16:42:36, glider wrote: > #define INTERCEPT_FUNCTION(func) > #ifdef __linux__ > INTERCEPT_FUNCTION_LINUX(func) > #elif __APPLE__ > ... > WDYT? > This won't dictate unnecessary interfaces to the systems that don't need them > and will hide this stuff from the user. Where will you define INTERCEPT_FUNCTION_LINUX()? Anyway, the functions that are called INTERCEPT_FUNCTION_LINUX will be inserted into user's code, and thus user should have access to their definition. We can discourage to use these functions themselves, though. http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc File interception/interception_mac.cc (right): http://codereview.appspot.com/5642046/diff/1/interception/interception_mac.cc#newcode71 interception/interception_mac.cc:71: orig_old_func, On 2012/02/07 16:42:36, glider wrote: > On 2012/02/07 14:31:32, samsonov wrote: > > On 2012/02/07 13:14:29, glider wrote: > > > mach_override_ptr_custom should have a custom prefix, too. > > > > So, you'd need different mach_override_ptr for each tool? (disregarding custom > > allocate/deallocate island) > We'll need an option to prepend a custom prefix to it. > I'll do that later in mach_override (I had asked Jonathan about that, but he > hasn't responded yet) OK, I guess we can deal with it a bit later. http://codereview.appspot.com/5642046/ From craig.topper at gmail.com Wed Feb 8 01:47:10 2012 From: craig.topper at gmail.com (Craig Topper) Date: Tue, 7 Feb 2012 23:47:10 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> Message-ID: I suppose you need the same code that autoupgrade would if I removed the intrinsics in order to fix dragonegg? On Tue, Feb 7, 2012 at 11:44 PM, Craig Topper wrote: > I only removed the builtin lines. I didn't delete the intrinsics > themselves. > > > On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands wrote: > >> Hi Craig, >> >> > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs >> them. Custom lower the intrinsics to the vpermilp target specific node and >> remove intrinsic patterns. >> >> what about auto-upgrade? >> >> Ciao, Duncan. >> >> > >> > Modified: >> > llvm/trunk/include/llvm/IntrinsicsX86.td >> > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp >> > llvm/trunk/lib/Target/X86/X86InstrSSE.td >> > >> > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td >> > URL: >> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff >> > >> ============================================================================== >> > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) >> > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 >> > @@ -1092,17 +1092,17 @@ >> > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, >> > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, >> > + def int_x86_avx_vpermil_pd : >> > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, >> > + def int_x86_avx_vpermil_ps : >> > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd_256 : >> GCCBuiltin<"__builtin_ia32_vpermilpd256">, >> > + def int_x86_avx_vpermil_pd_256 : >> > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps_256 : >> GCCBuiltin<"__builtin_ia32_vpermilps256">, >> > + def int_x86_avx_vpermil_ps_256 : >> > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > } >> > >> > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp >> > URL: >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff >> > >> ============================================================================== >> > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) >> > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 >> 2012 >> > @@ -9488,6 +9488,12 @@ >> > case Intrinsic::x86_avx2_vperm2i128: >> > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), >> > Op.getOperand(1), Op.getOperand(2), >> Op.getOperand(3)); >> > + case Intrinsic::x86_avx_vpermil_ps: >> > + case Intrinsic::x86_avx_vpermil_pd: >> > + case Intrinsic::x86_avx_vpermil_ps_256: >> > + case Intrinsic::x86_avx_vpermil_pd_256: >> > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), >> > + Op.getOperand(1), Op.getOperand(2)); >> > >> > // ptest and testp intrinsics. The intrinsic these come from are >> designed to >> > // return an integer value, not just an instruction so lower it to >> the ptest >> > >> > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td >> > URL: >> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff >> > >> ============================================================================== >> > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) >> > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 >> > @@ -7129,8 +7129,8 @@ >> > // >> > multiclass avx_permil opc_rm, bits<8> opc_rmi, string >> OpcodeStr, >> > RegisterClass RC, X86MemOperand x86memop_f, >> > - X86MemOperand x86memop_i, PatFrag f_frag, >> PatFrag i_frag, >> > - Intrinsic IntVar, Intrinsic IntImm> { >> > + X86MemOperand x86memop_i, PatFrag i_frag, >> > + Intrinsic IntVar, ValueType vt> { >> > def rr : AVX8I> > (ins RC:$src1, RC:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, $src2}"), >> > @@ -7144,63 +7144,40 @@ >> > def ri : AVXAIi8> > (ins RC:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; >> > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 >> imm:$src2))))]>, VEX; >> > def mi : AVXAIi8> > (ins x86memop_f:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm (f_frag addr:$src1), >> imm:$src2))]>, VEX; >> > + [(set RC:$dst, >> > + (vt (X86VPermilp (memop addr:$src1), (i8 >> imm:$src2))))]>, VEX; >> > } >> > >> > let ExeDomain = SSEPackedSingle in { >> > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, >> f128mem, i128mem, >> > - memopv4f32, memopv2i64, >> > - int_x86_avx_vpermilvar_ps, >> > - int_x86_avx_vpermil_ps>; >> > + memopv2i64, int_x86_avx_vpermilvar_ps, >> v4f32>; >> > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, >> f256mem, i256mem, >> > - memopv8f32, memopv4i64, >> > - int_x86_avx_vpermilvar_ps_256, >> > - int_x86_avx_vpermil_ps_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_ps_256, v8f32>; >> > } >> > let ExeDomain = SSEPackedDouble in { >> > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, >> f128mem, i128mem, >> > - memopv2f64, memopv2i64, >> > - int_x86_avx_vpermilvar_pd, >> > - int_x86_avx_vpermil_pd>; >> > + memopv2i64, int_x86_avx_vpermilvar_pd, >> v2f64>; >> > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, >> f256mem, i256mem, >> > - memopv4f64, memopv4i64, >> > - int_x86_avx_vpermilvar_pd_256, >> > - int_x86_avx_vpermil_pd_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_pd_256, v4f64>; >> > } >> > >> > let Predicates = [HasAVX] in { >> > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), >> > - (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), >> > - (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), >> > (i8 imm:$imm))), >> > (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > >> > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPSri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPDri VR128:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > (VPERMILPDri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), >> > - (VPERMILPSmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), >> > - (VPERMILPDmi addr:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDmi addr:$src1, imm:$imm)>; >> > } >> > >> > >> > _______________________________________________ >> > llvm-commits mailing list >> > llvm-commits at cs.uiuc.edu >> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits >> > > > > -- > ~Craig > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/58eb35b1/attachment.html From craig.topper at gmail.com Wed Feb 8 01:44:08 2012 From: craig.topper at gmail.com (Craig Topper) Date: Tue, 7 Feb 2012 23:44:08 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F322499.2060706@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> Message-ID: I only removed the builtin lines. I didn't delete the intrinsics themselves. On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands wrote: > Hi Craig, > > > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target specific node and > remove intrinsic patterns. > > what about auto-upgrade? > > Ciao, Duncan. > > > > > Modified: > > llvm/trunk/include/llvm/IntrinsicsX86.td > > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > llvm/trunk/lib/Target/X86/X86InstrSSE.td > > > > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff > > > ============================================================================== > > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) > > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > > @@ -1092,17 +1092,17 @@ > > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, > > + def int_x86_avx_vpermil_pd : > > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, > > + def int_x86_avx_vpermil_ps : > > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd_256 : > GCCBuiltin<"__builtin_ia32_vpermilpd256">, > > + def int_x86_avx_vpermil_pd_256 : > > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps_256 : > GCCBuiltin<"__builtin_ia32_vpermilps256">, > > + def int_x86_avx_vpermil_ps_256 : > > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > } > > > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 > 2012 > > @@ -9488,6 +9488,12 @@ > > case Intrinsic::x86_avx2_vperm2i128: > > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), > > Op.getOperand(1), Op.getOperand(2), > Op.getOperand(3)); > > + case Intrinsic::x86_avx_vpermil_ps: > > + case Intrinsic::x86_avx_vpermil_pd: > > + case Intrinsic::x86_avx_vpermil_ps_256: > > + case Intrinsic::x86_avx_vpermil_pd_256: > > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > > + Op.getOperand(1), Op.getOperand(2)); > > > > // ptest and testp intrinsics. The intrinsic these come from are > designed to > > // return an integer value, not just an instruction so lower it to > the ptest > > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 > > @@ -7129,8 +7129,8 @@ > > // > > multiclass avx_permil opc_rm, bits<8> opc_rmi, string > OpcodeStr, > > RegisterClass RC, X86MemOperand x86memop_f, > > - X86MemOperand x86memop_i, PatFrag f_frag, PatFrag > i_frag, > > - Intrinsic IntVar, Intrinsic IntImm> { > > + X86MemOperand x86memop_i, PatFrag i_frag, > > + Intrinsic IntVar, ValueType vt> { > > def rr : AVX8I > (ins RC:$src1, RC:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > @@ -7144,63 +7144,40 @@ > > def ri : AVXAIi8 > (ins RC:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 > imm:$src2))))]>, VEX; > > def mi : AVXAIi8 > (ins x86memop_f:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, > VEX; > > + [(set RC:$dst, > > + (vt (X86VPermilp (memop addr:$src1), (i8 > imm:$src2))))]>, VEX; > > } > > > > let ExeDomain = SSEPackedSingle in { > > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, > f128mem, i128mem, > > - memopv4f32, memopv2i64, > > - int_x86_avx_vpermilvar_ps, > > - int_x86_avx_vpermil_ps>; > > + memopv2i64, int_x86_avx_vpermilvar_ps, > v4f32>; > > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, > f256mem, i256mem, > > - memopv8f32, memopv4i64, > > - int_x86_avx_vpermilvar_ps_256, > > - int_x86_avx_vpermil_ps_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_ps_256, v8f32>; > > } > > let ExeDomain = SSEPackedDouble in { > > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, > f128mem, i128mem, > > - memopv2f64, memopv2i64, > > - int_x86_avx_vpermilvar_pd, > > - int_x86_avx_vpermil_pd>; > > + memopv2i64, int_x86_avx_vpermilvar_pd, > v2f64>; > > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, > f256mem, i256mem, > > - memopv4f64, memopv4i64, > > - int_x86_avx_vpermilvar_pd_256, > > - int_x86_avx_vpermil_pd_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_pd_256, v4f64>; > > } > > > > let Predicates = [HasAVX] in { > > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPSYri VR256:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPDYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > > (i8 imm:$imm))), > > (VPERMILPSYmi addr:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPSri VR128:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPDri VR128:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > (VPERMILPDri VR128:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSmi addr:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDmi addr:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDmi addr:$src1, imm:$imm)>; > > } > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120207/955c6963/attachment.html From baldrick at free.fr Wed Feb 8 01:56:02 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 08:56:02 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> Message-ID: <4F322A92.7010809@free.fr> Hi Craig, > I only removed the builtin lines. I didn't delete the intrinsics themselves. if you are not planning to delete them, can you please put the builtin lines back in again since dragonegg is using them. Or would this cause problems with clang, because that would cause it to go back to using the intrinsics? If so, or you are planning to delete the intrinsics, I can always expand them out to shuffles (or whatever) in dragonegg. Ciao, Duncan. PS: Removing the "builtin" lines also causes trouble for the C backend since it uses them to output the intrinsics as builtinXYZ IIRC. That said, no one cares about the C backend any more. > > On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > wrote: > > Hi Craig, > > > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target specific node and > remove intrinsic patterns. > > what about auto-upgrade? > > Ciao, Duncan. > > > > > Modified: > > llvm/trunk/include/llvm/IntrinsicsX86.td > > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > llvm/trunk/lib/Target/X86/X86InstrSSE.td > > > > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) > > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > > @@ -1092,17 +1092,17 @@ > > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, > > + def int_x86_avx_vpermil_pd : > > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, > > + def int_x86_avx_vpermil_ps : > > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd_256 : > GCCBuiltin<"__builtin_ia32_vpermilpd256">, > > + def int_x86_avx_vpermil_pd_256 : > > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps_256 : > GCCBuiltin<"__builtin_ia32_vpermilps256">, > > + def int_x86_avx_vpermil_ps_256 : > > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > } > > > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 2012 > > @@ -9488,6 +9488,12 @@ > > case Intrinsic::x86_avx2_vperm2i128: > > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), > > Op.getOperand(1), Op.getOperand(2), > Op.getOperand(3)); > > + case Intrinsic::x86_avx_vpermil_ps: > > + case Intrinsic::x86_avx_vpermil_pd: > > + case Intrinsic::x86_avx_vpermil_ps_256: > > + case Intrinsic::x86_avx_vpermil_pd_256: > > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > > + Op.getOperand(1), Op.getOperand(2)); > > > > // ptest and testp intrinsics. The intrinsic these come from are > designed to > > // return an integer value, not just an instruction so lower it to > the ptest > > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 > > @@ -7129,8 +7129,8 @@ > > // > > multiclass avx_permil opc_rm, bits<8> opc_rmi, string OpcodeStr, > > RegisterClass RC, X86MemOperand x86memop_f, > > - X86MemOperand x86memop_i, PatFrag f_frag, PatFrag > i_frag, > > - Intrinsic IntVar, Intrinsic IntImm> { > > + X86MemOperand x86memop_i, PatFrag i_frag, > > + Intrinsic IntVar, ValueType vt> { > > def rr : AVX8I > (ins RC:$src1, RC:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > @@ -7144,63 +7144,40 @@ > > def ri : AVXAIi8 > (ins RC:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 > imm:$src2))))]>, VEX; > > def mi : AVXAIi8 > (ins x86memop_f:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX; > > + [(set RC:$dst, > > + (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, > VEX; > > } > > > > let ExeDomain = SSEPackedSingle in { > > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, > i128mem, > > - memopv4f32, memopv2i64, > > - int_x86_avx_vpermilvar_ps, > > - int_x86_avx_vpermil_ps>; > > + memopv2i64, int_x86_avx_vpermilvar_ps, > v4f32>; > > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, > i256mem, > > - memopv8f32, memopv4i64, > > - int_x86_avx_vpermilvar_ps_256, > > - int_x86_avx_vpermil_ps_256>; > > + memopv4i64, int_x86_avx_vpermilvar_ps_256, > v8f32>; > > } > > let ExeDomain = SSEPackedDouble in { > > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, > i128mem, > > - memopv2f64, memopv2i64, > > - int_x86_avx_vpermilvar_pd, > > - int_x86_avx_vpermil_pd>; > > + memopv2i64, int_x86_avx_vpermilvar_pd, > v2f64>; > > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, > i256mem, > > - memopv4f64, memopv4i64, > > - int_x86_avx_vpermilvar_pd_256, > > - int_x86_avx_vpermil_pd_256>; > > + memopv4i64, int_x86_avx_vpermilvar_pd_256, > v4f64>; > > } > > > > let Predicates = [HasAVX] in { > > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPSYri VR256:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPDYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > > (i8 imm:$imm))), > > (VPERMILPSYmi addr:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPSri VR128:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPDri VR128:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > (VPERMILPDri VR128:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSmi addr:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDmi addr:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDmi addr:$src1, imm:$imm)>; > > } > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > > -- > ~Craig From baldrick at free.fr Wed Feb 8 01:59:39 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 08:59:39 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> Message-ID: <4F322B6B.5080909@free.fr> Hi Craig, > I suppose you need the same code that autoupgrade would if I removed the > intrinsics in order to fix dragonegg? yes, but I can also just copy clang's code. Ciao, Duncan. > > On Tue, Feb 7, 2012 at 11:44 PM, Craig Topper > wrote: > > I only removed the builtin lines. I didn't delete the intrinsics themselves. > > > On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > wrote: > > Hi Craig, > > > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target specific node > and remove intrinsic patterns. > > what about auto-upgrade? > > Ciao, Duncan. > > > > > Modified: > > llvm/trunk/include/llvm/IntrinsicsX86.td > > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > llvm/trunk/lib/Target/X86/X86InstrSSE.td > > > > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) > > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > > @@ -1092,17 +1092,17 @@ > > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, > > + def int_x86_avx_vpermil_pd : > > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, > > + def int_x86_avx_vpermil_ps : > > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd_256 : > GCCBuiltin<"__builtin_ia32_vpermilpd256">, > > + def int_x86_avx_vpermil_pd_256 : > > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps_256 : > GCCBuiltin<"__builtin_ia32_vpermilps256">, > > + def int_x86_avx_vpermil_ps_256 : > > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > } > > > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 > 2012 > > @@ -9488,6 +9488,12 @@ > > case Intrinsic::x86_avx2_vperm2i128: > > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), > > Op.getOperand(1), Op.getOperand(2), > Op.getOperand(3)); > > + case Intrinsic::x86_avx_vpermil_ps: > > + case Intrinsic::x86_avx_vpermil_pd: > > + case Intrinsic::x86_avx_vpermil_ps_256: > > + case Intrinsic::x86_avx_vpermil_pd_256: > > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > > + Op.getOperand(1), Op.getOperand(2)); > > > > // ptest and testp intrinsics. The intrinsic these come from are > designed to > > // return an integer value, not just an instruction so lower it > to the ptest > > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 > > @@ -7129,8 +7129,8 @@ > > // > > multiclass avx_permil opc_rm, bits<8> opc_rmi, string > OpcodeStr, > > RegisterClass RC, X86MemOperand x86memop_f, > > - X86MemOperand x86memop_i, PatFrag f_frag, > PatFrag i_frag, > > - Intrinsic IntVar, Intrinsic IntImm> { > > + X86MemOperand x86memop_i, PatFrag i_frag, > > + Intrinsic IntVar, ValueType vt> { > > def rr : AVX8I > (ins RC:$src1, RC:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > @@ -7144,63 +7144,40 @@ > > def ri : AVXAIi8 > (ins RC:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 > imm:$src2))))]>, VEX; > > def mi : AVXAIi8 > (ins x86memop_f:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > - [(set RC:$dst, (IntImm (f_frag addr:$src1), > imm:$src2))]>, VEX; > > + [(set RC:$dst, > > + (vt (X86VPermilp (memop addr:$src1), (i8 > imm:$src2))))]>, VEX; > > } > > > > let ExeDomain = SSEPackedSingle in { > > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, > f128mem, i128mem, > > - memopv4f32, memopv2i64, > > - int_x86_avx_vpermilvar_ps, > > - int_x86_avx_vpermil_ps>; > > + memopv2i64, > int_x86_avx_vpermilvar_ps, v4f32>; > > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, > f256mem, i256mem, > > - memopv8f32, memopv4i64, > > - int_x86_avx_vpermilvar_ps_256, > > - int_x86_avx_vpermil_ps_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_ps_256, v8f32>; > > } > > let ExeDomain = SSEPackedDouble in { > > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, > f128mem, i128mem, > > - memopv2f64, memopv2i64, > > - int_x86_avx_vpermilvar_pd, > > - int_x86_avx_vpermil_pd>; > > + memopv2i64, > int_x86_avx_vpermilvar_pd, v2f64>; > > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, > f256mem, i256mem, > > - memopv4f64, memopv4i64, > > - int_x86_avx_vpermilvar_pd_256, > > - int_x86_avx_vpermil_pd_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_pd_256, v4f64>; > > } > > > > let Predicates = [HasAVX] in { > > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPSYri VR256:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPDYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > > (i8 imm:$imm))), > > (VPERMILPSYmi addr:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPSri VR128:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPDri VR128:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > (VPERMILPDri VR128:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSmi addr:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDmi addr:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDmi addr:$src1, imm:$imm)>; > > } > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > > -- > ~Craig > > > > > -- > ~Craig From sabre at nondot.org Wed Feb 8 01:58:38 2012 From: sabre at nondot.org (Chris Lattner) Date: Wed, 08 Feb 2012 07:58:38 -0000 Subject: [llvm-commits] [llvm] r150065 - /llvm/trunk/docs/DeveloperPolicy.html Message-ID: <20120208075838.7B50C2A6C12C@llvm.org> Author: lattner Date: Wed Feb 8 01:58:38 2012 New Revision: 150065 URL: http://llvm.org/viewvc/llvm-project?rev=150065&view=rev Log: No actual functional change here, just some clarifications: Clarify that contributors are agreeing to license their code under the license corresponding to the subproject that they are contributing to, as requested by a potential contributor. Also, as a drive-by, update the llvm-gcc/GPL section to mention dragonegg and say that GPL code is all in its own repo's. Modified: llvm/trunk/docs/DeveloperPolicy.html Modified: llvm/trunk/docs/DeveloperPolicy.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/DeveloperPolicy.html?rev=150065&r1=150064&r2=150065&view=diff ============================================================================== --- llvm/trunk/docs/DeveloperPolicy.html (original) +++ llvm/trunk/docs/DeveloperPolicy.html Wed Feb 8 01:58:38 2012 @@ -43,7 +43,7 @@ the distributed nature of LLVM's development. By stating the policy in clear terms, we hope each developer can know ahead of time what to expect when making LLVM contributions. This policy covers all llvm.org subprojects, - including Clang, LLDB, etc.

      + including Clang, LLDB, libc++, etc.

      This policy is also designed to accomplish the following objectives:

        @@ -52,6 +52,9 @@
      1. Make life as simple and easy for contributors as possible.
      2. Keep the top of Subversion trees as stable as possible.
      3. + +
      4. Establish awareness of the project's copyright, + license, and patent policies with contributors to the project.

      This policy is aimed at frequent contributors to LLVM. People interested in @@ -494,19 +497,23 @@ +

      +

      NOTE: This section deals with + legal matters but does not provide legal advice. We are not lawyers — + please seek legal counsel from an attorney.

      +
      +

      This section addresses the issues of copyright, license and patents for the - LLVM project. The copyright holder for the code is held by the individual + LLVM project. The copyright for the code is held by the individual contributors of the code and the terms of its license to LLVM users and developers is the University of - Illinois/NCSA Open Source License.

      + Illinois/NCSA Open Source License (with portions dual licensed under the + MIT License, + see below). As contributor to the LLVM project, you agree to allow any + contributions to the project to licensed under these terms.

      -
      -

      NOTE: This section deals with - legal matters but does not provide legal advice. We are not lawyers, please - seek legal counsel from an attorney.

      -

      Copyright

      @@ -535,7 +542,10 @@

      License

      We intend to keep LLVM perpetually open source and to use a liberal open - source license. All of the code in LLVM is available under the + source license. As a contributor to the project, you agree that any + contributions be licensed under the terms of the corresponding + subproject. + All of the code in LLVM is available under the University of Illinois/NCSA Open Source License, which boils down to this:

      @@ -570,16 +580,17 @@ the LLVM core to libc++ without the copyright owner's permission.

      -

      Note that the LLVM Project does distribute llvm-gcc, which is GPL. +

      Note that the LLVM Project does distribute llvm-gcc and dragonegg, which + are GPL. This means that anything "linked" into llvm-gcc must itself be compatible with the GPL, and must be releasable under the terms of the GPL. This implies that any code linked into llvm-gcc and distributed to others may be subject to the viral aspects of the GPL (for example, a proprietary code generator linked into llvm-gcc must be made available under the GPL). This is not a problem for code already distributed under a more liberal - license (like the UIUC license), and does not affect code generated by - llvm-gcc. It may be a problem if you intend to base commercial development - on llvm-gcc without redistributing your source code.

      + license (like the UIUC license), and GPL-containing subprojects are kept + in separate SVN repositories whose LICENSE.txt files specifically indicate + that they contain GPL code.

      We have no plans to change the license of LLVM. If you have questions or comments about the license, please contact the @@ -596,7 +607,8 @@ arbitrary purposes (including commercial use).

      When contributing code, we expect contributors to notify us of any potential - for patent-related trouble with their changes. If you or your employer own + for patent-related trouble with their changes (including from third parties). + If you or your employer own the rights to a patent and would like to contribute code to LLVM that relies on it, we require that the copyright owner sign an agreement that allows any other user of LLVM to freely use your patent. Please contact From craig.topper at gmail.com Wed Feb 8 02:03:54 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 00:03:54 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F322B6B.5080909@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> Message-ID: I do intend to remove the intrinsics eventually. I just haven't looked at what I need to do in order to do that in the AutoUpgrade code so I didn't do it yet. The previous intrinsic removal was my first time using the IR builder functions so I'm pretty new to that side of llvm. Would you prefer me to put the builtin lines back or would you rather fix dragonegg to not use them? ~Craig On Tue, Feb 7, 2012 at 11:59 PM, Duncan Sands wrote: > Hi Craig, > > > I suppose you need the same code that autoupgrade would if I removed the >> intrinsics in order to fix dragonegg? >> > > yes, but I can also just copy clang's code. > > Ciao, Duncan. > > >> On Tue, Feb 7, 2012 at 11:44 PM, Craig Topper > > wrote: >> >> I only removed the builtin lines. I didn't delete the intrinsics >> themselves. >> >> >> On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > > wrote: >> >> Hi Craig, >> >> > Remove GCC builtins for vpermilp* intrinsics as clang no longer >> needs >> them. Custom lower the intrinsics to the vpermilp target specific >> node >> and remove intrinsic patterns. >> >> what about auto-upgrade? >> >> Ciao, Duncan. >> >> > >> > Modified: >> > llvm/trunk/include/llvm/**IntrinsicsX86.td >> > llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp >> > llvm/trunk/lib/Target/X86/**X86InstrSSE.td >> > >> > Modified: llvm/trunk/include/llvm/**IntrinsicsX86.td >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/include/** >> llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> > llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/include/llvm/**IntrinsicsX86.td (original) >> > +++ llvm/trunk/include/llvm/**IntrinsicsX86.td Wed Feb 8 >> 00:36:57 2012 >> > @@ -1092,17 +1092,17 @@ >> > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, >> > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_** >> vpermilpd">, >> > + def int_x86_avx_vpermil_pd : >> > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_** >> vpermilps">, >> > + def int_x86_avx_vpermil_ps : >> > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd_256 : >> GCCBuiltin<"__builtin_ia32_**vpermilpd256">, >> > + def int_x86_avx_vpermil_pd_256 : >> > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps_256 : >> GCCBuiltin<"__builtin_ia32_**vpermilps256">, >> > + def int_x86_avx_vpermil_ps_256 : >> > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > } >> > >> > Modified: llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/lib/Target/** >> X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> > X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp (original) >> > +++ llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp Wed Feb 8 >> 00:36:57 >> 2012 >> > @@ -9488,6 +9488,12 @@ >> > case Intrinsic::x86_avx2_**vperm2i128: >> > return DAG.getNode(X86ISD::**VPERM2X128, dl, >> Op.getValueType(), >> > Op.getOperand(1), Op.getOperand(2), >> Op.getOperand(3)); >> > + case Intrinsic::x86_avx_vpermil_ps: >> > + case Intrinsic::x86_avx_vpermil_pd: >> > + case Intrinsic::x86_avx_vpermil_ps_**256: >> > + case Intrinsic::x86_avx_vpermil_pd_**256: >> > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), >> > + Op.getOperand(1), Op.getOperand(2)); >> > >> > // ptest and testp intrinsics. The intrinsic these come >> from are >> designed to >> > // return an integer value, not just an instruction so >> lower it >> to the ptest >> > >> > Modified: llvm/trunk/lib/Target/X86/**X86InstrSSE.td >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/lib/Target/** >> X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> > X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/lib/Target/X86/**X86InstrSSE.td (original) >> > +++ llvm/trunk/lib/Target/X86/**X86InstrSSE.td Wed Feb 8 >> 00:36:57 2012 >> > @@ -7129,8 +7129,8 @@ >> > // >> > multiclass avx_permil opc_rm, bits<8> opc_rmi, >> string >> OpcodeStr, >> > RegisterClass RC, X86MemOperand >> x86memop_f, >> > - X86MemOperand x86memop_i, PatFrag f_frag, >> PatFrag i_frag, >> > - Intrinsic IntVar, Intrinsic IntImm> { >> > + X86MemOperand x86memop_i, PatFrag i_frag, >> > + Intrinsic IntVar, ValueType vt> { >> > def rr : AVX8I> > (ins RC:$src1, RC:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > @@ -7144,63 +7144,40 @@ >> > def ri : AVXAIi8> > (ins RC:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, >> VEX; >> > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 >> imm:$src2))))]>, VEX; >> > def mi : AVXAIi8> > (ins x86memop_f:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm (f_frag addr:$src1), >> imm:$src2))]>, VEX; >> > + [(set RC:$dst, >> > + (vt (X86VPermilp (memop addr:$src1), (i8 >> imm:$src2))))]>, VEX; >> > } >> > >> > let ExeDomain = SSEPackedSingle in { >> > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, >> f128mem, i128mem, >> > - memopv4f32, memopv2i64, >> > - int_x86_avx_vpermilvar_ps, >> > - int_x86_avx_vpermil_ps>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_ps, v4f32>; >> > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, >> f256mem, i256mem, >> > - memopv8f32, memopv4i64, >> > - int_x86_avx_vpermilvar_ps_256, >> > - int_x86_avx_vpermil_ps_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_ps_256, v8f32>; >> > } >> > let ExeDomain = SSEPackedDouble in { >> > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, >> f128mem, i128mem, >> > - memopv2f64, memopv2i64, >> > - int_x86_avx_vpermilvar_pd, >> > - int_x86_avx_vpermil_pd>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_pd, v2f64>; >> > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, >> f256mem, i256mem, >> > - memopv4f64, memopv4i64, >> > - int_x86_avx_vpermilvar_pd_256, >> > - int_x86_avx_vpermil_pd_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_pd_256, v4f64>; >> > } >> > >> > let Predicates = [HasAVX] in { >> > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 >> addr:$src1)), >> > (i8 imm:$imm))), >> > (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > >> > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPSri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPDri VR128:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > (VPERMILPDri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDmi addr:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDmi addr:$src1, imm:$imm)>; >> > } >> > >> > >> > ______________________________**_________________ >> > llvm-commits mailing list >> > llvm-commits at cs.uiuc.edu >> > >> >> > http://lists.cs.uiuc.edu/**mailman/listinfo/llvm-commits >> >> ______________________________**_________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> > >> >> http://lists.cs.uiuc.edu/**mailman/listinfo/llvm-commits >> >> >> >> >> -- >> ~Craig >> >> >> >> >> -- >> ~Craig >> > > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/a5a2c983/attachment.html From baldrick at free.fr Wed Feb 8 02:09:28 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 09:09:28 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> Message-ID: <4F322DB8.6020400@free.fr> Hi Craig, > I do intend to remove the intrinsics eventually. I just haven't looked at what I > need to do in order to do that in the AutoUpgrade code so I didn't do it yet. > The previous intrinsic removal was my first time using the IR builder functions > so I'm pretty new to that side of llvm. > > Would you prefer me to put the builtin lines back or would you rather fix > dragonegg to not use them? I'll fix dragonegg. Ciao, Duncan. > > ~Craig > > On Tue, Feb 7, 2012 at 11:59 PM, Duncan Sands > wrote: > > Hi Craig, > > > I suppose you need the same code that autoupgrade would if I removed the > intrinsics in order to fix dragonegg? > > > yes, but I can also just copy clang's code. > > Ciao, Duncan. > > > On Tue, Feb 7, 2012 at 11:44 PM, Craig Topper > >> wrote: > > I only removed the builtin lines. I didn't delete the intrinsics > themselves. > > > On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > >> wrote: > > Hi Craig, > > > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target > specific node > and remove intrinsic patterns. > > what about auto-upgrade? > > Ciao, Duncan. > > > > > Modified: > > llvm/trunk/include/llvm/ IntrinsicsX86.td > > llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp > > llvm/trunk/lib/Target/X86/ X86InstrSSE.td > > > > Modified: llvm/trunk/include/llvm/ IntrinsicsX86.td > > URL: > http://llvm.org/viewvc/llvm- project/llvm/trunk/include/ > llvm/IntrinsicsX86.td?rev= 150060&r1=150059&r2=150060& view=diff > > llvm/IntrinsicsX86.td?rev= 150060&r1=150059&r2=150060& view=diff > > > > > ============================== ============================== > ================== > > --- llvm/trunk/include/llvm/ IntrinsicsX86.td (original) > > +++ llvm/trunk/include/llvm/ IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > > @@ -1092,17 +1092,17 @@ > > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_ vpermilpd">, > > + def int_x86_avx_vpermil_pd : > > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_ vpermilps">, > > + def int_x86_avx_vpermil_ps : > > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd_256 : > GCCBuiltin<"__builtin_ia32_ vpermilpd256">, > > + def int_x86_avx_vpermil_pd_256 : > > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps_256 : > GCCBuiltin<"__builtin_ia32_ vpermilps256">, > > + def int_x86_avx_vpermil_ps_256 : > > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > } > > > > Modified: llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp > > URL: > http://llvm.org/viewvc/llvm- project/llvm/trunk/lib/Target/ > X86/X86ISelLowering.cpp?rev= 150060&r1=150059&r2=150060& view=diff > > X86/X86ISelLowering.cpp?rev= 150060&r1=150059&r2=150060& view=diff > > > > > ============================== ============================== > ================== > > --- llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp (original) > > +++ llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp Wed Feb 8 00:36:57 > 2012 > > @@ -9488,6 +9488,12 @@ > > case Intrinsic::x86_avx2_ vperm2i128: > > return DAG.getNode(X86ISD:: VPERM2X128, dl, Op.getValueType(), > > Op.getOperand(1), Op.getOperand(2), > Op.getOperand(3)); > > + case Intrinsic::x86_avx_vpermil_ps: > > + case Intrinsic::x86_avx_vpermil_pd: > > + case Intrinsic::x86_avx_vpermil_ps_ 256: > > + case Intrinsic::x86_avx_vpermil_pd_ 256: > > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > > + Op.getOperand(1), Op.getOperand(2)); > > > > // ptest and testp intrinsics. The intrinsic these come from are > designed to > > // return an integer value, not just an instruction so lower it > to the ptest > > > > Modified: llvm/trunk/lib/Target/X86/ X86InstrSSE.td > > URL: > http://llvm.org/viewvc/llvm- project/llvm/trunk/lib/Target/ > X86/X86InstrSSE.td?rev=150060& r1=150059&r2=150060&view=diff > > X86/X86InstrSSE.td?rev=150060& r1=150059&r2=150060&view=diff > > > > > ============================== ============================== > ================== > > --- llvm/trunk/lib/Target/X86/ X86InstrSSE.td (original) > > +++ llvm/trunk/lib/Target/X86/ X86InstrSSE.td Wed Feb 8 00:36:57 2012 > > @@ -7129,8 +7129,8 @@ > > // > > multiclass avx_permil opc_rm, bits<8> opc_rmi, string > OpcodeStr, > > RegisterClass RC, X86MemOperand x86memop_f, > > - X86MemOperand x86memop_i, PatFrag f_frag, > PatFrag i_frag, > > - Intrinsic IntVar, Intrinsic IntImm> { > > + X86MemOperand x86memop_i, PatFrag i_frag, > > + Intrinsic IntVar, ValueType vt> { > > def rr : AVX8I > (ins RC:$src1, RC:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > @@ -7144,63 +7144,40 @@ > > def ri : AVXAIi8 > (ins RC:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 > imm:$src2))))]>, VEX; > > def mi : AVXAIi8 > (ins x86memop_f:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, > $src1, $src2}"), > > - [(set RC:$dst, (IntImm (f_frag addr:$src1), > imm:$src2))]>, VEX; > > + [(set RC:$dst, > > + (vt (X86VPermilp (memop addr:$src1), (i8 > imm:$src2))))]>, VEX; > > } > > > > let ExeDomain = SSEPackedSingle in { > > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, > f128mem, i128mem, > > - memopv4f32, memopv2i64, > > - int_x86_avx_vpermilvar_ps, > > - int_x86_avx_vpermil_ps>; > > + memopv2i64, > int_x86_avx_vpermilvar_ps, v4f32>; > > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, > f256mem, i256mem, > > - memopv8f32, memopv4i64, > > - int_x86_avx_vpermilvar_ps_256, > > - int_x86_avx_vpermil_ps_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_ps_256, v8f32>; > > } > > let ExeDomain = SSEPackedDouble in { > > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, > f128mem, i128mem, > > - memopv2f64, memopv2i64, > > - int_x86_avx_vpermilvar_pd, > > - int_x86_avx_vpermil_pd>; > > + memopv2i64, > int_x86_avx_vpermilvar_pd, v2f64>; > > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, > f256mem, i256mem, > > - memopv4f64, memopv4i64, > > - int_x86_avx_vpermilvar_pd_256, > > - int_x86_avx_vpermil_pd_256>; > > + memopv4i64, > int_x86_avx_vpermilvar_pd_256, v4f64>; > > } > > > > let Predicates = [HasAVX] in { > > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPSYri VR256:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPDYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > > (i8 imm:$imm))), > > (VPERMILPSYmi addr:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPSri VR128:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPDri VR128:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > (VPERMILPDri VR128:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSmi addr:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDmi addr:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDmi addr:$src1, imm:$imm)>; > > } > > > > > > ______________________________ _________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > > > > http://lists.cs.uiuc.edu/ mailman/listinfo/llvm-commits > > > ______________________________ _________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > > > > http://lists.cs.uiuc.edu/ mailman/listinfo/llvm-commits > > > > > > -- > ~Craig > > > > > -- > ~Craig > > > > > > -- > ~Craig From craig.topper at gmail.com Wed Feb 8 02:12:53 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 00:12:53 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F322DB8.6020400@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <4F322DB8.6020400@free.fr> Message-ID: You should fix vperm2f128 and vperm2i128 that I also just replaced in clang. Haven't committed the llvm side yet. On Wed, Feb 8, 2012 at 12:09 AM, Duncan Sands wrote: > Hi Craig, > > > I do intend to remove the intrinsics eventually. I just haven't looked at >> what I >> need to do in order to do that in the AutoUpgrade code so I didn't do it >> yet. >> The previous intrinsic removal was my first time using the IR builder >> functions >> so I'm pretty new to that side of llvm. >> >> Would you prefer me to put the builtin lines back or would you rather fix >> dragonegg to not use them? >> > > I'll fix dragonegg. > > Ciao, Duncan. > > >> ~Craig >> >> On Tue, Feb 7, 2012 at 11:59 PM, Duncan Sands > > wrote: >> >> Hi Craig, >> >> >> I suppose you need the same code that autoupgrade would if I >> removed the >> intrinsics in order to fix dragonegg? >> >> >> yes, but I can also just copy clang's code. >> >> Ciao, Duncan. >> >> >> On Tue, Feb 7, 2012 at 11:44 PM, Craig Topper < >> craig.topper at gmail.com >> >> >> >> wrote: >> >> I only removed the builtin lines. I didn't delete the >> intrinsics >> themselves. >> >> >> On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands < >> baldrick at free.fr >> >> >> wrote: >> >> Hi Craig, >> >> > Remove GCC builtins for vpermilp* intrinsics as clang no longer >> needs >> them. Custom lower the intrinsics to the vpermilp target >> specific node >> and remove intrinsic patterns. >> >> what about auto-upgrade? >> >> Ciao, Duncan. >> >> > >> > Modified: >> > llvm/trunk/include/llvm/ IntrinsicsX86.td >> > llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp >> > llvm/trunk/lib/Target/X86/ X86InstrSSE.td >> > >> > Modified: llvm/trunk/include/llvm/ IntrinsicsX86.td >> > URL: >> http://llvm.org/viewvc/llvm- project/llvm/trunk/include/ >> llvm/IntrinsicsX86.td?rev= 150060&r1=150059&r2=150060& view=diff >> > llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > llvm/IntrinsicsX86.td?rev= 150060&r1=150059&r2=150060& view=diff >> > llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> >> >> > >> ============================== >> ============================== >> ================== >> > --- llvm/trunk/include/llvm/ IntrinsicsX86.td (original) >> > +++ llvm/trunk/include/llvm/ IntrinsicsX86.td Wed Feb 8 >> 00:36:57 2012 >> >> > @@ -1092,17 +1092,17 @@ >> > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, >> > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_ >> vpermilpd">, >> >> > + def int_x86_avx_vpermil_pd : >> > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_ >> vpermilps">, >> >> > + def int_x86_avx_vpermil_ps : >> > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd_256 : >> GCCBuiltin<"__builtin_ia32_ vpermilpd256">, >> >> > + def int_x86_avx_vpermil_pd_256 : >> > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps_256 : >> GCCBuiltin<"__builtin_ia32_ vpermilps256">, >> >> > + def int_x86_avx_vpermil_ps_256 : >> > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > } >> > >> > Modified: llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp >> > URL: >> http://llvm.org/viewvc/llvm- project/llvm/trunk/lib/Target/ >> X86/X86ISelLowering.cpp?rev= 150060&r1=150059&r2=150060& view=diff >> > X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > X86/X86ISelLowering.cpp?rev= 150060&r1=150059&r2=150060& view=diff >> > X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> >> >> > >> ============================== >> ============================== >> ================== >> > --- llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp (original) >> > +++ llvm/trunk/lib/Target/X86/ X86ISelLowering.cpp Wed Feb 8 >> 00:36:57 >> >> 2012 >> > @@ -9488,6 +9488,12 @@ >> > case Intrinsic::x86_avx2_ vperm2i128: >> > return DAG.getNode(X86ISD:: VPERM2X128, dl, >> Op.getValueType(), >> > Op.getOperand(1), Op.getOperand(2), >> Op.getOperand(3)); >> > + case Intrinsic::x86_avx_vpermil_ps: >> > + case Intrinsic::x86_avx_vpermil_pd: >> > + case Intrinsic::x86_avx_vpermil_ps_ 256: >> > + case Intrinsic::x86_avx_vpermil_pd_ 256: >> > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), >> > + Op.getOperand(1), Op.getOperand(2)); >> > >> > // ptest and testp intrinsics. The intrinsic these come >> from are >> designed to >> > // return an integer value, not just an instruction so >> lower it >> to the ptest >> > >> > Modified: llvm/trunk/lib/Target/X86/ X86InstrSSE.td >> > URL: >> http://llvm.org/viewvc/llvm- project/llvm/trunk/lib/Target/ >> X86/X86InstrSSE.td?rev=150060& r1=150059&r2=150060&view=diff >> > X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> > >> > X86/X86InstrSSE.td?rev=150060& r1=150059&r2=150060&view=diff >> > X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> >**> >> > >> ============================== >> ============================== >> ================== >> > --- llvm/trunk/lib/Target/X86/ X86InstrSSE.td (original) >> > +++ llvm/trunk/lib/Target/X86/ X86InstrSSE.td Wed Feb 8 >> 00:36:57 2012 >> >> > @@ -7129,8 +7129,8 @@ >> > // >> > multiclass avx_permil opc_rm, bits<8> opc_rmi, >> string >> OpcodeStr, >> > RegisterClass RC, X86MemOperand >> x86memop_f, >> > - X86MemOperand x86memop_i, PatFrag f_frag, >> PatFrag i_frag, >> > - Intrinsic IntVar, Intrinsic IntImm> { >> > + X86MemOperand x86memop_i, PatFrag i_frag, >> > + Intrinsic IntVar, ValueType vt> { >> > def rr : AVX8I> > (ins RC:$src1, RC:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > @@ -7144,63 +7144,40 @@ >> > def ri : AVXAIi8> > (ins RC:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, >> VEX; >> > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 >> imm:$src2))))]>, VEX; >> > def mi : AVXAIi8> > (ins x86memop_f:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, >> $dst|$dst, >> $src1, $src2}"), >> > - [(set RC:$dst, (IntImm (f_frag addr:$src1), >> imm:$src2))]>, VEX; >> > + [(set RC:$dst, >> > + (vt (X86VPermilp (memop addr:$src1), (i8 >> imm:$src2))))]>, VEX; >> > } >> > >> > let ExeDomain = SSEPackedSingle in { >> > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, >> f128mem, i128mem, >> > - memopv4f32, memopv2i64, >> > - int_x86_avx_vpermilvar_ps, >> > - int_x86_avx_vpermil_ps>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_ps, v4f32>; >> > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, >> f256mem, i256mem, >> > - memopv8f32, memopv4i64, >> > - int_x86_avx_vpermilvar_ps_256, >> > - int_x86_avx_vpermil_ps_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_ps_256, v8f32>; >> > } >> > let ExeDomain = SSEPackedDouble in { >> > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, >> f128mem, i128mem, >> > - memopv2f64, memopv2i64, >> > - int_x86_avx_vpermilvar_pd, >> > - int_x86_avx_vpermil_pd>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_pd, v2f64>; >> > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, >> f256mem, i256mem, >> > - memopv4f64, memopv4i64, >> > - int_x86_avx_vpermilvar_pd_256, >> > - int_x86_avx_vpermil_pd_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_pd_256, v4f64>; >> > } >> > >> > let Predicates = [HasAVX] in { >> > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 >> addr:$src1)), >> > (i8 imm:$imm))), >> > (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > >> > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPSri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPDri VR128:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > (VPERMILPDri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDmi addr:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDmi addr:$src1, imm:$imm)>; >> > } >> > >> > >> > ______________________________ _________________ >> > llvm-commits mailing list >> > llvm-commits at cs.uiuc.edu >> > >> > edu >> >> >> > http://lists.cs.uiuc.edu/ mailman/listinfo/llvm-commits >> >> > >> >> ______________________________ _________________ >> >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> > >> > edu >> >> >> http://lists.cs.uiuc.edu/ mailman/listinfo/llvm-commits >> >> >> > >> >> >> >> >> -- >> ~Craig >> >> >> >> >> -- >> ~Craig >> >> >> >> >> >> -- >> ~Craig >> > > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/a12a606b/attachment.html From glider at google.com Wed Feb 8 02:19:17 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 08:19:17 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf306f77fe44df9604b86f8d9d@google.com> LGTM with nit. http://codereview.appspot.com/5642046/diff/1012/asan_interceptors.h File asan_interceptors.h (right): http://codereview.appspot.com/5642046/diff/1012/asan_interceptors.h#newcode34 asan_interceptors.h:34: size_t internal_strlen(const char *s); BTW aren't these functions already declared in asan_internal.h? http://codereview.appspot.com/5642046/ From craig.topper at gmail.com Wed Feb 8 02:29:30 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 08 Feb 2012 08:29:30 -0000 Subject: [llvm-commits] [llvm] r150067 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td Message-ID: <20120208082930.E4E0B2A6C12C@llvm.org> Author: ctopper Date: Wed Feb 8 02:29:30 2012 New Revision: 150067 URL: http://llvm.org/viewvc/llvm-project?rev=150067&view=rev Log: Remove a couple unneeded intrinsic patterns Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150067&r1=150066&r2=150067&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 02:29:30 2012 @@ -7199,12 +7199,6 @@ } let Predicates = [HasAVX] in { -def : Pat<(int_x86_avx_vperm2f128_si_256 VR256:$src1, VR256:$src2, imm:$src3), - (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$src3)>; -def : Pat<(int_x86_avx_vperm2f128_si_256 - VR256:$src1, (bc_v8i32 (memopv4i64 addr:$src2)), imm:$src3), - (VPERM2F128rm VR256:$src1, addr:$src2, imm:$src3)>; - def : Pat<(v8i32 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))), (VPERM2F128rr VR256:$src1, VR256:$src2, imm:$imm)>; def : Pat<(v4i64 (X86VPerm2x128 VR256:$src1, VR256:$src2, (i8 imm:$imm))), From james.molloy at arm.com Wed Feb 8 02:34:44 2012 From: james.molloy at arm.com (James Molloy) Date: Wed, 8 Feb 2012 08:34:44 -0000 Subject: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE In-Reply-To: References: <000c01cce4bc$173fe630$45bfb290$%molloy@arm.com>, <9F39D766-682D-4279-8D04-814291A11FBA@mac.com> Message-ID: <000001cce63c$8289ffd0$879dff70$@molloy@arm.com> Hi Owen, Do you have any other comments about this patch or is it OK to commit? Cheers, James -----Original Message----- From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of James Molloy Sent: 06 February 2012 19:15 To: Owen Anderson Cc: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE Hi Owen, For the generated disassembler it only adds two lines of code and only on instructions that require it. The difference in size before and after this patch is +2 lines, because it is only hooked up to tBX. There is no noticeable build time difference. Cheers, James ________________________________________ From: Owen Anderson [resistor at mac.com] Sent: 06 February 2012 18:19 To: James Molloy Cc: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE James, I like the concept of this feature, and it'd be nice if it could help use eliminate more of the hand-written decoding hooks. However, I'm concerned about the impact it will have on LLVM's build time. Have you looked at how much bigger this makes the generated disassembler file? It already takes a very long time to compile, and I'm wage to avoid making it any worse. --Owen On Feb 6, 2012, at 2:42 AM, James Molloy wrote: Hi, ARM has the concept of an "unpredictable" instruction - one which is valid (and will be executed) but whose results are not defined. An example of an unpredictable instruction is a load with address increment and writeback where the writeback register is the same as the load destination. The MC disassembler has the concept of a "soft failure" which maps well to unpredictability (coincidentally because it was added for that purpose). However this soft failure can currently only be triggered by manual C++ code such as that in ARMDisassembler.cpp - it cannot be triggered from tablegen-generated code. The attached patch adds this functionality. It adds the ability for the FixedLenDecoderEmitter to take into account a bitfield in a tablegen record called "SoftFail" that mirrors the "Inst" field. If a bitpattern BP matches the Inst field of an instruction record but differs from Inst in any bits which are set to '1' in the SoftFail field, then that instruction is matched by the disassembler but the status SoftFail is returned instead of Success. For example, this is a modified Thumb BX instruction with unpredictability modelled as per the ARMARM: def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>, T1Special<{1,1,0,?}> { // A6.2.3 & A8.6.25 bits<4> Rm; let Inst{6-3} = Rm; let Inst{2-0} = 0b000; // Any of the bottom 3 bits set is unpredictable. let SoftFail{2-0} = 0b111; } And this is the generated disassembler code (new code bolded): if ((Bits & ARM::ModeThumb)) { if (insn & 0x7) S = MCDisassembler::SoftFail; MI.setOpcode(2662); tmp = fieldFromInstruction16(insn, 3, 4); if (!Check(S, DecodeGPRRegisterClass(MI, tmp, Address, Decoder))) return MCDisassembler::Fail; return S; // tBXT } This results in the MC now correctly identifying such an instruction: $ echo '0x01 0x47' | ./bin/llvm-mc -triple thumbv7 -disassemble :1:1: warning: potentially undefined instruction encoding 0x01 0x47 ^ bx r0 The patch works by removing any bits that could SoftFail from the set of possible disassembly island values, and emitting an extra test if required in the generated disassembler. If no SoftFail bits are set, no extra code will be emitted. In the ARM tablegen files, this patch aliases SoftFail to "Unpredictable" so it is more recognisable what it is doing in the ARM world. Please review! It wires the new functionality up to "tBX" as a proof of concept and testing codepath, and adds a regression test. Cheers, James _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you. _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From elena.demikhovsky at intel.com Wed Feb 8 02:37:27 2012 From: elena.demikhovsky at intel.com (Elena Demikhovsky) Date: Wed, 08 Feb 2012 08:37:27 -0000 Subject: [llvm-commits] [llvm] r150068 - in /llvm/trunk: lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp lib/Target/X86/X86AsmPrinter.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/avx-intrinsics-x86.ll Message-ID: <20120208083727.58F752A6C12D@llvm.org> Author: delena Date: Wed Feb 8 02:37:26 2012 New Revision: 150068 URL: http://llvm.org/viewvc/llvm-project?rev=150068&view=rev Log: Fixed a bug in printing "cmp" pseudo ops. > This IR code > %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 14) > fails with assertion: > > llc: X86ATTInstPrinter.cpp:62: void llvm::X86ATTInstPrinter::printSSECC(const llvm::MCInst*, unsigned int, llvm::raw_ostream&): Assertion `0 && "Invalid ssecc argument!"' failed. > 0 llc 0x0000000001355803 > 1 llc 0x0000000001355dc9 > 2 libpthread.so.0 0x00007f79a30575d0 > 3 libc.so.6 0x00007f79a23a1945 gsignal + 53 > 4 libc.so.6 0x00007f79a23a2f21 abort + 385 > 5 libc.so.6 0x00007f79a239a810 __assert_fail + 240 > 6 llc 0x00000000011858d5 llvm::X86ATTInstPrinter::printSSECC(llvm::MCInst const*, unsigned int, llvm::raw_ostream&) + 119 I added the full testing for all possible pseudo-ops of cmp. I extended X86AsmPrinter.cpp and X86IntelInstPrinter.cpp. You'l also see lines alignments (unrelated to this fix) in X86IselLowering.cpp from my previous check-in. Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp llvm/trunk/lib/Target/X86/X86ISelLowering.cpp llvm/trunk/test/CodeGen/X86/avx-intrinsics-x86.ll Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp?rev=150068&r1=150067&r2=150068&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp Wed Feb 8 02:37:26 2012 @@ -60,14 +60,38 @@ raw_ostream &O) { switch (MI->getOperand(Op).getImm()) { default: llvm_unreachable("Invalid ssecc argument!"); - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; + case 0: O << "eq"; break; + case 1: O << "lt"; break; + case 2: O << "le"; break; + case 3: O << "unord"; break; + case 4: O << "neq"; break; + case 5: O << "nlt"; break; + case 6: O << "nle"; break; + case 7: O << "ord"; break; + case 8: O << "eq_uq"; break; + case 9: O << "nge"; break; + case 0xa: O << "ngt"; break; + case 0xb: O << "false"; break; + case 0xc: O << "neq_oq"; break; + case 0xd: O << "ge"; break; + case 0xe: O << "gt"; break; + case 0xf: O << "true"; break; + case 0x10: O << "eq_os"; break; + case 0x11: O << "lt_oq"; break; + case 0x12: O << "le_oq"; break; + case 0x13: O << "unord_s"; break; + case 0x14: O << "neq_us"; break; + case 0x15: O << "nlt_uq"; break; + case 0x16: O << "nle_uq"; break; + case 0x17: O << "ord_s"; break; + case 0x18: O << "eq_us"; break; + case 0x19: O << "nge_uq"; break; + case 0x1a: O << "ngt_uq"; break; + case 0x1b: O << "false_os"; break; + case 0x1c: O << "neq_os"; break; + case 0x1d: O << "ge_oq"; break; + case 0x1e: O << "gt_oq"; break; + case 0x1f: O << "true_us"; break; } } Modified: llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp?rev=150068&r1=150067&r2=150068&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp Wed Feb 8 02:37:26 2012 @@ -50,14 +50,39 @@ raw_ostream &O) { switch (MI->getOperand(Op).getImm()) { default: llvm_unreachable("Invalid ssecc argument!"); - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; + case 0: O << "eq"; break; + case 1: O << "lt"; break; + case 2: O << "le"; break; + case 3: O << "unord"; break; + case 4: O << "neq"; break; + case 5: O << "nlt"; break; + case 6: O << "nle"; break; + case 7: O << "ord"; break; + case 8: O << "eq_uq"; break; + case 9: O << "nge"; break; + case 0xa: O << "ngt"; break; + case 0xb: O << "false"; break; + case 0xc: O << "neq_oq"; break; + case 0xd: O << "ge"; break; + case 0xe: O << "gt"; break; + case 0xf: O << "true"; break; + case 0x10: O << "eq_os"; break; + case 0x11: O << "lt_oq"; break; + case 0x12: O << "le_oq"; break; + case 0x13: O << "unord_s"; break; + case 0x14: O << "neq_us"; break; + case 0x15: O << "nlt_uq"; break; + case 0x16: O << "nle_uq"; break; + case 0x17: O << "ord_s"; break; + case 0x18: O << "eq_us"; break; + case 0x19: O << "nge_uq"; break; + case 0x1a: O << "ngt_uq"; break; + case 0x1b: O << "false_os"; break; + case 0x1c: O << "neq_os"; break; + case 0x1d: O << "ge_oq"; break; + case 0x1e: O << "gt_oq"; break; + case 0x1f: O << "true_us"; break; + } } Modified: llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp?rev=150068&r1=150067&r2=150068&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp (original) +++ llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp Wed Feb 8 02:37:26 2012 @@ -266,14 +266,38 @@ unsigned char value = MI->getOperand(Op).getImm(); assert(value <= 7 && "Invalid ssecc argument!"); switch (value) { - case 0: O << "eq"; break; - case 1: O << "lt"; break; - case 2: O << "le"; break; - case 3: O << "unord"; break; - case 4: O << "neq"; break; - case 5: O << "nlt"; break; - case 6: O << "nle"; break; - case 7: O << "ord"; break; + case 0: O << "eq"; break; + case 1: O << "lt"; break; + case 2: O << "le"; break; + case 3: O << "unord"; break; + case 4: O << "neq"; break; + case 5: O << "nlt"; break; + case 6: O << "nle"; break; + case 7: O << "ord"; break; + case 8: O << "eq_uq"; break; + case 9: O << "nge"; break; + case 0xa: O << "ngt"; break; + case 0xb: O << "false"; break; + case 0xc: O << "neq_oq"; break; + case 0xd: O << "ge"; break; + case 0xe: O << "gt"; break; + case 0xf: O << "true"; break; + case 0x10: O << "eq_os"; break; + case 0x11: O << "lt_oq"; break; + case 0x12: O << "le_oq"; break; + case 0x13: O << "unord_s"; break; + case 0x14: O << "neq_us"; break; + case 0x15: O << "nlt_uq"; break; + case 0x16: O << "nle_uq"; break; + case 0x17: O << "ord_s"; break; + case 0x18: O << "eq_us"; break; + case 0x19: O << "nge_uq"; break; + case 0x1a: O << "ngt_uq"; break; + case 0x1b: O << "false_os"; break; + case 0x1c: O << "neq_os"; break; + case 0x1d: O << "ge_oq"; break; + case 0x1e: O << "gt_oq"; break; + case 0x1f: O << "true_us"; break; } } Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150068&r1=150067&r2=150068&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 02:37:26 2012 @@ -14597,41 +14597,42 @@ if (!DCI.isBeforeLegalizeOps()) return SDValue(); - if (!Subtarget->hasAVX()) return SDValue(); + if (!Subtarget->hasAVX()) + return SDValue(); - // Optimize vectors in AVX mode - // Sign extend v8i16 to v8i32 and - // v4i32 to v4i64 - // - // Divide input vector into two parts - // for v4i32 the shuffle mask will be { 0, 1, -1, -1} {2, 3, -1, -1} - // use vpmovsx instruction to extend v4i32 -> v2i64; v8i16 -> v4i32 - // concat the vectors to original VT + // Optimize vectors in AVX mode + // Sign extend v8i16 to v8i32 and + // v4i32 to v4i64 + // + // Divide input vector into two parts + // for v4i32 the shuffle mask will be { 0, 1, -1, -1} {2, 3, -1, -1} + // use vpmovsx instruction to extend v4i32 -> v2i64; v8i16 -> v4i32 + // concat the vectors to original VT EVT VT = N->getValueType(0); SDValue Op = N->getOperand(0); EVT OpVT = Op.getValueType(); DebugLoc dl = N->getDebugLoc(); - if (((VT == MVT::v4i64) && (OpVT == MVT::v4i32)) || - ((VT == MVT::v8i32) && (OpVT == MVT::v8i16))) { + if ((VT == MVT::v4i64 && OpVT == MVT::v4i32) || + (VT == MVT::v8i32 && OpVT == MVT::v8i16)) { unsigned NumElems = OpVT.getVectorNumElements(); SmallVector ShufMask1(NumElems, -1); - for (unsigned i=0; i< NumElems/2; i++) ShufMask1[i] = i; + for (unsigned i = 0; i < NumElems/2; i++) ShufMask1[i] = i; SDValue OpLo = DAG.getVectorShuffle(OpVT, dl, Op, DAG.getUNDEF(OpVT), - ShufMask1.data()); + ShufMask1.data()); SmallVector ShufMask2(NumElems, -1); - for (unsigned i=0; i< NumElems/2; i++) ShufMask2[i] = i+NumElems/2; + for (unsigned i = 0; i < NumElems/2; i++) ShufMask2[i] = i + NumElems/2; SDValue OpHi = DAG.getVectorShuffle(OpVT, dl, Op, DAG.getUNDEF(OpVT), - ShufMask2.data()); + ShufMask2.data()); EVT HalfVT = EVT::getVectorVT(*DAG.getContext(), VT.getScalarType(), - VT.getVectorNumElements()/2); - + VT.getVectorNumElements()/2); + OpLo = DAG.getNode(X86ISD::VSEXT_MOVL, dl, HalfVT, OpLo); OpHi = DAG.getNode(X86ISD::VSEXT_MOVL, dl, HalfVT, OpHi); Modified: llvm/trunk/test/CodeGen/X86/avx-intrinsics-x86.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/avx-intrinsics-x86.ll?rev=150068&r1=150067&r2=150068&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/avx-intrinsics-x86.ll (original) +++ llvm/trunk/test/CodeGen/X86/avx-intrinsics-x86.ll Wed Feb 8 02:37:26 2012 @@ -1766,6 +1766,74 @@ %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 7) ; <<8 x float>> [#uses=1] ret <8 x float> %res } + +define <8 x float> @test_x86_avx_cmp_ps_256_pseudo_op(<8 x float> %a0, <8 x float> %a1) { + ; CHECK: vcmpeqps + %a2 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a1, i8 0) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpltps + %a3 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a2, i8 1) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpleps + %a4 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a3, i8 2) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpunordps + %a5 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a4, i8 3) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneqps + %a6 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a5, i8 4) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnltps + %a7 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a6, i8 5) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnleps + %a8 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a7, i8 6) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpordps + %a9 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a8, i8 7) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_uqps + %a10 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a9, i8 8) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngeps + %a11 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a10, i8 9) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngtps + %a12 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a11, i8 10) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpfalseps + %a13 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a12, i8 11) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_oqps + %a14 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a13, i8 12) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgeps + %a15 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a14, i8 13) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgtps + %a16 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a15, i8 14) ; <<8 x float>> [#uses=1] + ; CHECK: vcmptrueps + %a17 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a16, i8 15) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_osps + %a18 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a17, i8 16) ; <<8 x float>> [#uses=1] + ; CHECK: vcmplt_oqps + %a19 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a18, i8 17) ; <<8 x float>> [#uses=1] + ; CHECK: vcmple_oqps + %a20 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a19, i8 18) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpunord_sps + %a21 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a20, i8 19) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_usps + %a22 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a21, i8 20) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnlt_uqps + %a23 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a22, i8 21) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnle_uqps + %a24 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a23, i8 22) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpord_sps + %a25 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a24, i8 23) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpeq_usps + %a26 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a25, i8 24) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpnge_uqps + %a27 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a26, i8 25) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpngt_uqps + %a28 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a27, i8 26) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpfalse_osps + %a29 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a28, i8 27) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpneq_osps + %a30 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a29, i8 28) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpge_oqps + %a31 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a30, i8 29) ; <<8 x float>> [#uses=1] + ; CHECK: vcmpgt_oqps + %a32 = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a31, i8 30) ; <<8 x float>> [#uses=1] + ; CHECK: vcmptrue_usps + %res = call <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float> %a0, <8 x float> %a32, i8 31) ; <<8 x float>> [#uses=1] + ret <8 x float> %res +} declare <8 x float> @llvm.x86.avx.cmp.ps.256(<8 x float>, <8 x float>, i8) nounwind readnone From baldrick at free.fr Wed Feb 8 02:45:44 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 09:45:44 +0100 Subject: [llvm-commits] [llvm] r150068 - in /llvm/trunk: lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp lib/Target/X86/X86AsmPrinter.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/avx-intrinsics-x86.ll In-Reply-To: <20120208083727.58F752A6C12D@llvm.org> References: <20120208083727.58F752A6C12D@llvm.org> Message-ID: <4F323638.9040602@free.fr> Hi Elena, there seems to be a lot of repetition: what seems like the same big switch for ssecc printing in three files. Can they be unified somehow? Ciao, Duncan. From timurrrr at google.com Wed Feb 8 03:43:32 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 09:43:32 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf306f77fe94124c04b870ba01@google.com> Alexander, Can you please take a look about the refactoring idea? http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h File lib/asan/asan_procmaps.h (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode30 lib/asan/asan_procmaps.h:30: // and puts it into the given buffer with a leading space On 2012/02/08 07:11:02, samsonov wrote: > On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > > I know this may sound a bit confusing, but look at how easy it is to use this > > function now (asan_stack.cc, which is the only place this is used) > I think it's weird to write leading space here. See the other comment; otherwise you'll need "if" or "?:" every time you use a function > "puts"->"writes"? Will do http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode32 lib/asan/asan_procmaps.h:32: void DescribeAddress(uintptr_t addr, char out_buffer[], size_t buffer_size); On 2012/02/08 07:11:02, samsonov wrote: > Why not GetAddressDescription()? Shorter names are better if they mean the same thing, right? > We've got two other different DescribeAddress > functions already :) That's good, no? One has to remember less names. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc File lib/asan/asan_stack.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc#newcode47 lib/asan/asan_stack.cc:47: Printf(" #%ld 0x%lx%s\n", i, pc, descr); Extra trailing space if descr is empty On 2012/02/08 07:11:02, samsonov wrote: > Why not write space here? http://codereview.appspot.com/5643047/ From elena.demikhovsky at intel.com Wed Feb 8 03:45:25 2012 From: elena.demikhovsky at intel.com (Demikhovsky, Elena) Date: Wed, 8 Feb 2012 09:45:25 +0000 Subject: [llvm-commits] [llvm] r150068 - in /llvm/trunk: lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp lib/Target/X86/X86AsmPrinter.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/avx-intrinsics-... In-Reply-To: <4F323638.9040602@free.fr> References: <20120208083727.58F752A6C12D@llvm.org> <4F323638.9040602@free.fr> Message-ID: I can initialize a global array somewhere const char * CmpPseoudoOps [] = { /* 0 */ "eq", /* 1 */ "lt", .. /*0x1f*/ "true_us" } #define LEGAL_CMP_OP_FIRST 0 #define LEGAL_CMP_OP_LAST 0x1f then all three printSETCC() will look like: Imm = MI->getOperand(Op).getImm(); if (Imm < LEGAL_CMP_OP_FIRST ) || (Imm > LEGAL_CMP_OP_LAST) - unreachable O << CmpPseoudoOps[Imm]; If it looks good, where the best place for the array initialization? - Elena -----Original Message----- From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Duncan Sands Sent: Wednesday, February 08, 2012 10:46 To: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [llvm] r150068 - in /llvm/trunk: lib/Target/X86/InstPrinter/X86ATTInstPrinter.cpp lib/Target/X86/InstPrinter/X86IntelInstPrinter.cpp lib/Target/X86/X86AsmPrinter.cpp lib/Target/X86/X86ISelLowering.cpp test/CodeGen/X86/avx-intrinsics-... Hi Elena, there seems to be a lot of repetition: what seems like the same big switch for ssecc printing in three files. Can they be unified somehow? Ciao, Duncan. _______________________________________________ llvm-commits mailing list llvm-commits at cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. From glider at google.com Wed Feb 8 04:12:40 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 10:12:40 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf300fb1efbd69aa04b87122ac@google.com> http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_internal.h File lib/asan/asan_internal.h (left): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_internal.h#oldcode145 lib/asan/asan_internal.h:145: int SNPrint(char *buffer, size_t length, const char *format, ...); On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > This was wrong in the first place I think it's generally better to send separate CLs for cleanup. I'm ok with this particular change however. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc File lib/asan/asan_linux.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode216 lib/asan/asan_linux.cc:216: uintptr_t offset; On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > this code is identical to that on Mac, see comment below You'd better put the default implementation into asan_procmaps.h instead of IterateForObjectNameAndOffset. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode221 lib/asan/asan_linux.cc:221: out_buffer[0] = '\0'; Please check that out_buffer!=NULL http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode265 lib/asan/asan_linux.cc:265: if (dl_iterate_phdr(dl_iterate_phdr_callback, &data)) { On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > Alternative suggestion: > I can extract this code to IterateForObjectNameAndOffset > and move the common AsanProcMaps::DescribeAddress code to asan_posix.cc > (we have the same symbolization capabilities on Linux and Mac, right?) > WDYT? We do not have dl_iterate_phdr on Mac. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode266 lib/asan/asan_linux.cc:266: SNPrintf(out_buffer, buffer_size, Please mind the return value of snprintf. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h File lib/asan/asan_procmaps.h (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode30 lib/asan/asan_procmaps.h:30: // and puts it into the given buffer with a leading space On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > I know this may sound a bit confusing, but look at how easy it is to use this > function now (asan_stack.cc, which is the only place this is used) Please no leading spaces. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc File lib/asan/asan_stack.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_stack.cc#newcode47 lib/asan/asan_stack.cc:47: Printf(" #%ld 0x%lx%s\n", i, pc, descr); Please keep in mind this should be %p (not %lx) on Windows See also http://mail.python.org/pipermail/patches/2000-June/000871.html http://codereview.appspot.com/5643047/ From samsonov at google.com Wed Feb 8 04:39:50 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 10:39:50 +0000 Subject: [llvm-commits] PATCH: AddressSanitizer: replace all "real_X" calls with "REAL(X)". (issue 5645054) Message-ID: <20cf3005ddc4e4b55604b87183ab@google.com> Reviewers: ramosian.glider, kcc, Description: AddressSanitizer: replace all "real_X" calls with "REAL(X)". Please review this at http://codereview.appspot.com/5645054/ Affected files: M asan_allocator.cc M asan_allocator.h M asan_interceptors.cc M asan_linux.cc M asan_mac.cc M asan_malloc_linux.cc M asan_malloc_mac.cc M asan_poisoning.cc M asan_posix.cc M asan_rtl.cc M asan_stack.cc M asan_stats.cc -------------- next part -------------- Index: asan_stats.cc =================================================================== --- asan_stats.cc (revision 150068) +++ asan_stats.cc (working copy) @@ -21,8 +21,8 @@ namespace __asan { AsanStats::AsanStats() { - CHECK(real_memset != NULL); - real_memset(this, 0, sizeof(AsanStats)); + CHECK(REAL(memset) != NULL); + REAL(memset)(this, 0, sizeof(AsanStats)); } static void PrintMallocStatsArray(const char *prefix, Index: asan_rtl.cc =================================================================== --- asan_rtl.cc (revision 150068) +++ asan_rtl.cc (working copy) @@ -148,7 +148,7 @@ // where alloc_i looks like "offset size len ObjectName ". CHECK(frame_descr); // Report the function name and the offset. - const char *name_end = real_strchr(frame_descr, ' '); + const char *name_end = REAL(strchr)(frame_descr, ' '); CHECK(name_end); buf[0] = 0; internal_strncat(buf, frame_descr, Index: asan_posix.cc =================================================================== --- asan_posix.cc (revision 150068) +++ asan_posix.cc (working copy) @@ -35,10 +35,10 @@ if (!AsanInterceptsSignal(signum)) return; struct sigaction sigact; - real_memset(&sigact, 0, sizeof(sigact)); + REAL(memset)(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = handler; sigact.sa_flags = SA_SIGINFO; - CHECK(0 == real_sigaction(signum, &sigact, 0)); + CHECK(0 == REAL(sigaction)(signum, &sigact, 0)); } static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { Index: asan_poisoning.cc =================================================================== --- asan_poisoning.cc (revision 150068) +++ asan_poisoning.cc (working copy) @@ -24,8 +24,8 @@ CHECK(AddrIsAlignedByGranularity(addr + size)); uintptr_t shadow_beg = MemToShadow(addr); uintptr_t shadow_end = MemToShadow(addr + size); - CHECK(real_memset != NULL); - real_memset((void*)shadow_beg, value, shadow_end - shadow_beg); + CHECK(REAL(memset) != NULL); + REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg); } void PoisonShadowPartialRightRedzone(uintptr_t addr, @@ -108,7 +108,7 @@ } beg.chunk++; } - real_memset(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk); + REAL(memset)(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk); // Poison if byte in end.offset is unaddressable. if (end.value > 0 && end.value <= end.offset) { *end.chunk = kAsanUserPoisonedMemoryMagic; @@ -140,7 +140,7 @@ *beg.chunk = 0; beg.chunk++; } - real_memset(beg.chunk, 0, end.chunk - beg.chunk); + REAL(memset)(beg.chunk, 0, end.chunk - beg.chunk); if (end.offset > 0 && end.value != 0) { *end.chunk = Max(end.value, end.offset); } Index: asan_interceptors.cc =================================================================== --- asan_interceptors.cc (revision 150068) +++ asan_interceptors.cc (working copy) @@ -159,8 +159,8 @@ size_t internal_strnlen(const char *s, size_t maxlen) { #ifndef __APPLE__ - if (real_strnlen != NULL) { - return real_strnlen(s, maxlen); + if (REAL(strnlen) != NULL) { + return REAL(strnlen)(s, maxlen); } #endif size_t i = 0; @@ -264,12 +264,12 @@ int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); asanThreadRegistry().RegisterThread(t); - return real_pthread_create(thread, attr, asan_thread_start, t); + return REAL(pthread_create)(thread, attr, asan_thread_start, t); } INTERCEPTOR(void*, signal, int signum, void *handler) { if (!AsanInterceptsSignal(signum)) { - return real_signal(signum, handler); + return REAL(signal)(signum, handler); } return NULL; } @@ -277,7 +277,7 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, struct sigaction *oldact) { if (!AsanInterceptsSignal(signum)) { - return real_sigaction(signum, act, oldact); + return REAL(sigaction)(signum, act, oldact); } return 0; } @@ -295,17 +295,17 @@ INTERCEPTOR(void, longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real_longjmp(env, val); + REAL(longjmp)(env, val); } INTERCEPTOR(void, _longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real__longjmp(env, val); + REAL(_longjmp)(env, val); } INTERCEPTOR(void, siglongjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real_siglongjmp(env, val); + REAL(siglongjmp)(env, val); } #if ASAN_HAS_EXCEPTIONS == 1 @@ -314,9 +314,9 @@ #endif // __APPLE__ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { - CHECK(&real___cxa_throw); + CHECK(REAL(__cxa_throw)); UnpoisonStackFromHereToTop(); - real___cxa_throw(a, b, c); + REAL(__cxa_throw)(a, b, c); } #endif @@ -386,7 +386,7 @@ // memcpy is called during __asan_init() from the internals // of printf(...). if (asan_init_is_running) { - return real_memcpy(to, from, size); + return REAL(memcpy)(to, from, size); } ENSURE_ASAN_INITED(); if (FLAG_replace_intrin) { @@ -398,7 +398,7 @@ ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } - return real_memcpy(to, from, size); + return REAL(memcpy)(to, from, size); } INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) { @@ -407,26 +407,26 @@ ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } - return real_memmove(to, from, size); + return REAL(memmove)(to, from, size); } INTERCEPTOR(void*, memset, void *block, int c, size_t size) { // memset is called inside INTERCEPT_FUNCTION on Mac. if (asan_init_is_running) { - return real_memset(block, c, size); + return REAL(memset)(block, c, size); } ENSURE_ASAN_INITED(); if (FLAG_replace_intrin) { ASAN_WRITE_RANGE(block, size); } - return real_memset(block, c, size); + return REAL(memset)(block, c, size); } INTERCEPTOR(char*, strchr, const char *str, int c) { ENSURE_ASAN_INITED(); - char *result = real_strchr(str, c); + char *result = REAL(strchr)(str, c); if (FLAG_replace_str) { - size_t bytes_read = (result ? result - str : real_strlen(str)) + 1; + size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; ASAN_READ_RANGE(str, bytes_read); } return result; @@ -456,16 +456,16 @@ INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t from_length = real_strlen(from); + size_t from_length = REAL(strlen)(from); ASAN_READ_RANGE(from, from_length + 1); if (from_length > 0) { - size_t to_length = real_strlen(to); + size_t to_length = REAL(strlen)(to); ASAN_READ_RANGE(to, to_length); ASAN_WRITE_RANGE(to + to_length, from_length + 1); CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1); } } - return real_strcat(to, from); + return REAL(strcat)(to, from); // NOLINT } INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { @@ -488,35 +488,35 @@ // strcpy is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strcpy(to, from); + return REAL(strcpy)(to, from); // NOLINT } ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t from_size = real_strlen(from) + 1; + size_t from_size = REAL(strlen)(from) + 1; CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); ASAN_READ_RANGE(from, from_size); ASAN_WRITE_RANGE(to, from_size); } - return real_strcpy(to, from); + return REAL(strcpy)(to, from); // NOLINT } INTERCEPTOR(char*, strdup, const char *s) { ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t length = real_strlen(s); + size_t length = REAL(strlen)(s); ASAN_READ_RANGE(s, length + 1); } - return real_strdup(s); + return REAL(strdup)(s); } INTERCEPTOR(size_t, strlen, const char *s) { // strlen is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strlen(s); + return REAL(strlen)(s); } ENSURE_ASAN_INITED(); - size_t length = real_strlen(s); + size_t length = REAL(strlen)(s); if (FLAG_replace_str) { ASAN_READ_RANGE(s, length + 1); } @@ -541,7 +541,7 @@ // strncmp is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strncmp(s1, s2, size); + return REAL(strncmp)(s1, s2, size); } unsigned char c1 = 0, c2 = 0; size_t i; @@ -563,13 +563,13 @@ ASAN_READ_RANGE(from, from_size); ASAN_WRITE_RANGE(to, size); } - return real_strncpy(to, from, size); + return REAL(strncpy)(to, from, size); } #ifndef __APPLE__ INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { ENSURE_ASAN_INITED(); - size_t length = real_strnlen(s, maxlen); + size_t length = REAL(strnlen)(s, maxlen); if (FLAG_replace_str) { ASAN_READ_RANGE(s, Min(length + 1, maxlen)); } @@ -596,7 +596,7 @@ if (GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD) { INTERCEPT_FUNCTION(memcpy); } else { - real_memcpy = real_memmove; + REAL(memcpy) = REAL(memmove); } #else // Always wrap memcpy() on non-Darwin platforms. Index: asan_allocator.h =================================================================== --- asan_allocator.h (revision 150068) +++ asan_allocator.h (working copy) @@ -45,8 +45,8 @@ explicit AsanThreadLocalMallocStorage(LinkerInitialized x) : quarantine_(x) { } AsanThreadLocalMallocStorage() { - CHECK(real_memset); - real_memset(this, 0, sizeof(AsanThreadLocalMallocStorage)); + CHECK(REAL(memset)); + REAL(memset)(this, 0, sizeof(AsanThreadLocalMallocStorage)); } AsanChunkFifoList quarantine_; Index: asan_linux.cc =================================================================== --- asan_linux.cc (revision 150068) +++ asan_linux.cc (working copy) @@ -241,7 +241,7 @@ data->filename[path_len] = 0; } else { CHECK(info->dlpi_name); - real_strncpy(data->filename, info->dlpi_name, data->filename_size); + REAL(strncpy)(data->filename, info->dlpi_name, data->filename_size); } data->offset = data->addr - info->dlpi_addr; return 1; Index: asan_mac.cc =================================================================== --- asan_mac.cc (revision 150068) +++ asan_mac.cc (working copy) @@ -209,8 +209,8 @@ if (end) *end = sc->vmaddr + sc->vmsize + dlloff; if (offset) *offset = sc->fileoff; if (filename) { - real_strncpy(filename, _dyld_get_image_name(current_image_), - filename_size); + REAL(strncpy)(filename, _dyld_get_image_name(current_image_), + filename_size); } if (FLAG_v >= 4) Report("LC_SEGMENT: %p--%p %s+%p\n", *start, *end, filename, *offset); @@ -432,8 +432,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - return real_dispatch_async_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_async_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, void *ctxt, @@ -445,8 +445,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - return real_dispatch_sync_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_sync_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, @@ -458,8 +458,8 @@ Report("dispatch_after_f: %p\n", asan_ctxt); PRINT_CURRENT_STACK(); } - return real_dispatch_after_f(when, dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_barrier_async_f, dispatch_queue_t dq, void *ctxt, @@ -471,8 +471,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - real_dispatch_barrier_async_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + REAL(dispatch_barrier_async_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, @@ -485,8 +485,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - real_dispatch_group_async_f(group, dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } // The following stuff has been extremely helpful while looking for the @@ -521,8 +521,9 @@ Report("pthread_workqueue_additem_np: %p\n", asan_ctxt); PRINT_CURRENT_STACK(); } - return real_pthread_workqueue_additem_np(workq, wrap_workitem_func, asan_ctxt, - itemhandlep, gencountp); + return REAL(pthread_workqueue_additem_np)(workq, wrap_workitem_func, + asan_ctxt, itemhandlep, + gencountp); } // CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal @@ -562,7 +563,7 @@ if (__CFStrIsConstant(str)) { return str; } else { - return real_CFStringCreateCopy(alloc, str); + return REAL(CFStringCreateCopy)(alloc, str); } } Index: asan_stack.cc =================================================================== --- asan_stack.cc (revision 150068) +++ asan_stack.cc (working copy) @@ -140,8 +140,8 @@ // |res| may be greater than check_stack.size, because // UncompressStack(CompressStack(stack)) eliminates the 0x0 frames. CHECK(res >= check_stack.size); - CHECK(0 == real_memcmp(check_stack.trace, stack->trace, - check_stack.size * sizeof(uintptr_t))); + CHECK(0 == REAL(memcmp)(check_stack.trace, stack->trace, + check_stack.size * sizeof(uintptr_t))); #endif return res; Index: asan_allocator.cc =================================================================== --- asan_allocator.cc (revision 150068) +++ asan_allocator.cc (working copy) @@ -668,7 +668,7 @@ size & (REDZONE - 1)); } if (size <= FLAG_max_malloc_fill_size) { - real_memset((void*)addr, 0, rounded_size); + REAL(memset)((void*)addr, 0, rounded_size); } return (uint8_t*)addr; } @@ -740,8 +740,8 @@ size_t memcpy_size = Min(new_size, old_size); uint8_t *new_ptr = Allocate(0, new_size, stack); if (new_ptr) { - CHECK(real_memcpy != NULL); - real_memcpy(new_ptr, old_ptr, memcpy_size); + CHECK(REAL(memcpy) != NULL); + REAL(memcpy)(new_ptr, old_ptr, memcpy_size); Deallocate(old_ptr, stack); } return new_ptr; @@ -791,7 +791,7 @@ void *asan_calloc(size_t nmemb, size_t size, AsanStackTrace *stack) { void *ptr = (void*)Allocate(0, nmemb * size, stack); if (ptr) - real_memset(ptr, 0, nmemb * size); + REAL(memset)(ptr, 0, nmemb * size); ASAN_NEW_HOOK(ptr, nmemb * size); return ptr; } @@ -867,8 +867,8 @@ // ---------------------- Fake stack-------------------- {{{1 FakeStack::FakeStack() { - CHECK(real_memset != NULL); - real_memset(this, 0, sizeof(*this)); + CHECK(REAL(memset) != NULL); + REAL(memset)(this, 0, sizeof(*this)); } bool FakeStack::AddrIsInSizeClass(uintptr_t addr, size_t size_class) { Index: asan_malloc_linux.cc =================================================================== --- asan_malloc_linux.cc (revision 150068) +++ asan_malloc_linux.cc (working copy) @@ -71,7 +71,7 @@ INTERCEPTOR(void*, calloc, size_t nmemb, size_t size) { if (!asan_inited) { - // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. const size_t kCallocPoolSize = 1024; static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize]; static size_t allocated; @@ -105,7 +105,7 @@ INTERCEPTOR(struct mallinfo, mallinfo) { struct mallinfo res; - real_memset(&res, 0, sizeof(res)); + REAL(memset)(&res, 0, sizeof(res)); return res; } Index: asan_malloc_mac.cc =================================================================== --- asan_malloc_mac.cc (revision 150068) +++ asan_malloc_mac.cc (working copy) @@ -92,7 +92,7 @@ void *mz_calloc(malloc_zone_t *zone, size_t nmemb, size_t size) { if (!asan_inited) { - // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. const size_t kCallocPoolSize = 1024; static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize]; static size_t allocated; @@ -310,7 +310,7 @@ namespace __asan { void ReplaceSystemMalloc() { static malloc_introspection_t asan_introspection; - __asan::real_memset(&asan_introspection, 0, sizeof(asan_introspection)); + __asan::REAL(memset)(&asan_introspection, 0, sizeof(asan_introspection)); asan_introspection.enumerator = &mi_enumerator; asan_introspection.good_size = &mi_good_size; @@ -321,7 +321,7 @@ asan_introspection.force_unlock = &mi_force_unlock; static malloc_zone_t asan_zone; - __asan::real_memset(&asan_zone, 0, sizeof(malloc_zone_t)); + __asan::REAL(memset)(&asan_zone, 0, sizeof(malloc_zone_t)); // Start with a version 4 zone which is used for OS X 10.4 and 10.5. asan_zone.version = 4; From samsonov at google.com Wed Feb 8 04:51:36 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 10:51:36 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf3074b31effc39304b871ad14@google.com> http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h File lib/asan/asan_procmaps.h (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_procmaps.h#newcode32 lib/asan/asan_procmaps.h:32: void DescribeAddress(uintptr_t addr, char out_buffer[], size_t buffer_size); On 2012/02/08 09:43:33, timurrrr_at_google_com wrote: > On 2012/02/08 07:11:02, samsonov wrote: > > Why not GetAddressDescription()? > Shorter names are better if they mean the same thing, right? > > We've got two other different DescribeAddress > > functions already :) > That's good, no? Not if they do different things. DescribeAddress we already have acts like a procedure and prints the description to the output. What you have here is function that returns the buffer with description. Leaving this up to you, though. > One has to remember less names. http://codereview.appspot.com/5643047/ From dmalyshev at accesssoftek.com Wed Feb 8 05:47:47 2012 From: dmalyshev at accesssoftek.com (Danil Malyshev) Date: Wed, 8 Feb 2012 03:47:47 -0800 Subject: [llvm-commits] RuntimeDyLd new features In-Reply-To: <9BBE4537D1BAAB479E9E8F9D4234619D33ADF4@HASMSX103.ger.corp.intel.com> References: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> <9BBE4537D1BAAB479E9E8F9D4234619D33ADF4@HASMSX103.ger.corp.intel.com> Message-ID: <6AE1604EE3EC5F4296C096518C6B77EE1AA523908D@mail.accesssoftek.com> Hello Eli, Oh, I did not see this patch as was very busy with my patch and did not follow the mailing. I apologize. Now I will study it. > How does your patch relate to this work? It may be a good idea to discuss all the requirements and possible solutions and come up with a design that suits everyone. Otherwise it's hard to review and reason about several large & conflicting patches to the same area of code. I can offer a few thoughts for discussion about the design: The code should be emitted by sectors, rather than by functions. If we allocate space for each function separately, there is no guarantee that their position relative to each other will be the same as it was in the object file. However, if two functions are in one sector and one calls the other, then this call will at once direct brunch in the code without any relocation. And if these two functions will be emitted separately, probably a runtime error will occurred. RuntimeDyLdImpl Simplistically, RuntimeDyLd doing the following: 1. Load an object file: 1.1. Parse an object file, finds the functions, data, relocations, etc. 1.2. Emit functions and data. 1.3. Parse relocations, associate it with the emitted data. 2. Resolve relocations after loading all the object files. If we will parsing the object file with the ObjectFile class then the object file formats different will appear only at stages 1.3 and 2. In this case, it makes sense to most of the work doing in RuntimeDyLdImpl, and only stages 1.3 and 2 doing in RuntimeDyLdMachO and RuntimeDyLdELF. ARM Some branch instructions have a limited range. For address outside this range are used special instructions. Accordingly, we need add a stub function with these instructions when we see short range branch relocation, because we can not be sure this brunch is out of range or not. Perhaps another architectures need stub-functions also, so it is desirable to make this mechanism more general. Regress tests. The RuntimeDyLd has only x86 and ARM relocation resolvers now (in ToT ARM ELF not yet supported, but in any case, I'll add support for ARM ELF). So it make sense to use an separate folder for MCJIT ExecutionEngine tests and add to dg.exp a special filter. Regards, Danil ________________________________ From: Bendersky, Eli [mailto:eli.bendersky at intel.com] Sent: Wednesday, February 08, 2012 10:00 AM To: Danil Malyshev; llvm-commits at cs.uiuc.edu Subject: RE: RuntimeDyLd new features Hi Danil, We're currently working on getting MCJIT running on ELF (http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-January/046671.html), and a couple of patches were already committed. There's another patch, currently pending a review (http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120130/135997.html) with further changes that make MCJIT on ELF (Linux) pass 100% of ExecutionEngine tests (all the same tests JIT passes), as well as supporting MCJIT debugging with GDB. How does your patch relate to this work? It may be a good idea to discuss all the requirements and possible solutions and come up with a design that suits everyone. Otherwise it's hard to review and reason about several large & conflicting patches to the same area of code. Eli -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/c3f6f99d/attachment.html From glider at google.com Wed Feb 8 05:45:09 2012 From: glider at google.com (Alexander Potapenko) Date: Wed, 08 Feb 2012 11:45:09 -0000 Subject: [llvm-commits] [compiler-rt] r150069 - /compiler-rt/trunk/lib/asan/asan_internal.h Message-ID: <20120208114510.034162A6C12C@llvm.org> Author: glider Date: Wed Feb 8 05:45:09 2012 New Revision: 150069 URL: http://llvm.org/viewvc/llvm-project?rev=150069&view=rev Log: Typo fix: s/SNPrint/SNPrintf Modified: compiler-rt/trunk/lib/asan/asan_internal.h Modified: compiler-rt/trunk/lib/asan/asan_internal.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=150069&r1=150068&r2=150069&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_internal.h (original) +++ compiler-rt/trunk/lib/asan/asan_internal.h Wed Feb 8 05:45:09 2012 @@ -142,7 +142,7 @@ // asan_printf.cc void RawWrite(const char *buffer); -int SNPrint(char *buffer, size_t length, const char *format, ...); +int SNPrintf(char *buffer, size_t length, const char *format, ...); void Printf(const char *format, ...); int SScanf(const char *str, const char *format, ...); void Report(const char *format, ...); From eli.bendersky at intel.com Wed Feb 8 06:42:16 2012 From: eli.bendersky at intel.com (Bendersky, Eli) Date: Wed, 8 Feb 2012 12:42:16 +0000 Subject: [llvm-commits] [PATCH] LIT cleanup phase #1 - replacing dg.exp with lit.local.cfg Message-ID: <9BBE4537D1BAAB479E9E8F9D4234619D33B0DC@HASMSX103.ger.corp.intel.com> Hello, I've started working on cleaning up LIT a bit. The overall cleanup plan was approved by Daniel Dunbar. The first patch (attached) is ready for review. The LIT global configuration currently relies on "dg.exp" files to find out which file extensions have tests, and which targets are supported for these tests. This is a relic from old times and is no longer required for LIT runs. LIT already has good infrastructure for specifying these things via lit.local.cfg - in fact it's already being used in Clang tests instead of dg.exp. The attached patch translates all existing dg.exp files into respective lit.local.cfg files. Also, the configuration-specific information was moved from site.exp to lit.site.cfg, as appropriate. To keep the first patch minimal (it's rather large even now, because a lot of files were modified), some things are left for next patches: * I've made lit.cfg just ignore the fact that it can't find dg.exp, meaning that dg.exp is in theory still supported. This code in lit.cfg will be cleaned up, as well as removing the generation, reading and parsing of site.exp - which is also no longer needed. * There's a bit of duplication in some of the lit.local.cfg files for reaching the root configuration. This duplication is "borrowed" from the Clang lit.local.cfg files, where it also exists. In a future patch I plan to clean it up (including the Clang lit files), probably by adding a new configuration attribute exposed from the LIT library itself that will allow local configs to easily access the root. Eli --------------------------------------------------------------------- Intel Israel (74) Limited This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). Any review or distribution by others is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies. -------------- next part -------------- A non-text attachment was scrubbed... Name: lit_dg_cleanup.2.patch Type: application/octet-stream Size: 89198 bytes Desc: lit_dg_cleanup.2.patch Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/17660ba0/attachment-0001.obj From glider at google.com Wed Feb 8 06:53:32 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 12:53:32 +0000 Subject: [llvm-commits] AddressSanitizer: replace all "real_X" calls with "REAL(X)". (issue 5645054) Message-ID: <20cf3074b31e0a816e04b8736219@google.com> LGTM http://codereview.appspot.com/5645054/ From benny.kra at googlemail.com Wed Feb 8 07:13:47 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 08 Feb 2012 13:13:47 -0000 Subject: [llvm-commits] [llvm] r150071 - /llvm/trunk/lib/Support/PathV2.cpp Message-ID: <20120208131347.BE0F62A6C12C@llvm.org> Author: d0k Date: Wed Feb 8 07:13:47 2012 New Revision: 150071 URL: http://llvm.org/viewvc/llvm-project?rev=150071&view=rev Log: PathV2: Remove static StringRef ctors. Modified: llvm/trunk/lib/Support/PathV2.cpp Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=150071&r1=150070&r2=150071&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Wed Feb 8 07:13:47 2012 @@ -24,11 +24,11 @@ using llvm::sys::path::is_separator; #ifdef LLVM_ON_WIN32 - const StringRef separators = "\\/"; - const char prefered_separator = '\\'; + const char *separators = "\\/"; + const char prefered_separator = '\\'; #else - const StringRef separators = "/"; - const char prefered_separator = '/'; + const char separators = '/'; + const char prefered_separator = '/'; #endif const llvm::error_code success; From samsonov at google.com Wed Feb 8 07:45:32 2012 From: samsonov at google.com (Alexey Samsonov) Date: Wed, 08 Feb 2012 13:45:32 -0000 Subject: [llvm-commits] [compiler-rt] r150073 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc asan_allocator.h asan_interceptors.cc asan_linux.cc asan_mac.cc asan_malloc_linux.cc asan_malloc_mac.cc asan_poisoning.cc asan_posix.cc asan_rtl.cc asan_stack.cc asan_stats.cc Message-ID: <20120208134532.5C65C2A6C12C@llvm.org> Author: samsonov Date: Wed Feb 8 07:45:31 2012 New Revision: 150073 URL: http://llvm.org/viewvc/llvm-project?rev=150073&view=rev Log: AddressSanitizer: replace all "real_X" calls with "REAL(X)" Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc compiler-rt/trunk/lib/asan/asan_allocator.h compiler-rt/trunk/lib/asan/asan_interceptors.cc compiler-rt/trunk/lib/asan/asan_linux.cc compiler-rt/trunk/lib/asan/asan_mac.cc compiler-rt/trunk/lib/asan/asan_malloc_linux.cc compiler-rt/trunk/lib/asan/asan_malloc_mac.cc compiler-rt/trunk/lib/asan/asan_poisoning.cc compiler-rt/trunk/lib/asan/asan_posix.cc compiler-rt/trunk/lib/asan/asan_rtl.cc compiler-rt/trunk/lib/asan/asan_stack.cc compiler-rt/trunk/lib/asan/asan_stats.cc Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.cc (original) +++ compiler-rt/trunk/lib/asan/asan_allocator.cc Wed Feb 8 07:45:31 2012 @@ -668,7 +668,7 @@ size & (REDZONE - 1)); } if (size <= FLAG_max_malloc_fill_size) { - real_memset((void*)addr, 0, rounded_size); + REAL(memset)((void*)addr, 0, rounded_size); } return (uint8_t*)addr; } @@ -740,8 +740,8 @@ size_t memcpy_size = Min(new_size, old_size); uint8_t *new_ptr = Allocate(0, new_size, stack); if (new_ptr) { - CHECK(real_memcpy != NULL); - real_memcpy(new_ptr, old_ptr, memcpy_size); + CHECK(REAL(memcpy) != NULL); + REAL(memcpy)(new_ptr, old_ptr, memcpy_size); Deallocate(old_ptr, stack); } return new_ptr; @@ -791,7 +791,7 @@ void *asan_calloc(size_t nmemb, size_t size, AsanStackTrace *stack) { void *ptr = (void*)Allocate(0, nmemb * size, stack); if (ptr) - real_memset(ptr, 0, nmemb * size); + REAL(memset)(ptr, 0, nmemb * size); ASAN_NEW_HOOK(ptr, nmemb * size); return ptr; } @@ -867,8 +867,8 @@ // ---------------------- Fake stack-------------------- {{{1 FakeStack::FakeStack() { - CHECK(real_memset != NULL); - real_memset(this, 0, sizeof(*this)); + CHECK(REAL(memset) != NULL); + REAL(memset)(this, 0, sizeof(*this)); } bool FakeStack::AddrIsInSizeClass(uintptr_t addr, size_t size_class) { Modified: compiler-rt/trunk/lib/asan/asan_allocator.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.h?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.h (original) +++ compiler-rt/trunk/lib/asan/asan_allocator.h Wed Feb 8 07:45:31 2012 @@ -45,8 +45,8 @@ explicit AsanThreadLocalMallocStorage(LinkerInitialized x) : quarantine_(x) { } AsanThreadLocalMallocStorage() { - CHECK(real_memset); - real_memset(this, 0, sizeof(AsanThreadLocalMallocStorage)); + CHECK(REAL(memset)); + REAL(memset)(this, 0, sizeof(AsanThreadLocalMallocStorage)); } AsanChunkFifoList quarantine_; Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original) +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Feb 8 07:45:31 2012 @@ -159,8 +159,8 @@ size_t internal_strnlen(const char *s, size_t maxlen) { #ifndef __APPLE__ - if (real_strnlen != NULL) { - return real_strnlen(s, maxlen); + if (REAL(strnlen) != NULL) { + return REAL(strnlen)(s, maxlen); } #endif size_t i = 0; @@ -264,12 +264,12 @@ int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); asanThreadRegistry().RegisterThread(t); - return real_pthread_create(thread, attr, asan_thread_start, t); + return REAL(pthread_create)(thread, attr, asan_thread_start, t); } INTERCEPTOR(void*, signal, int signum, void *handler) { if (!AsanInterceptsSignal(signum)) { - return real_signal(signum, handler); + return REAL(signal)(signum, handler); } return NULL; } @@ -277,7 +277,7 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, struct sigaction *oldact) { if (!AsanInterceptsSignal(signum)) { - return real_sigaction(signum, act, oldact); + return REAL(sigaction)(signum, act, oldact); } return 0; } @@ -295,17 +295,17 @@ INTERCEPTOR(void, longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real_longjmp(env, val); + REAL(longjmp)(env, val); } INTERCEPTOR(void, _longjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real__longjmp(env, val); + REAL(_longjmp)(env, val); } INTERCEPTOR(void, siglongjmp, void *env, int val) { UnpoisonStackFromHereToTop(); - real_siglongjmp(env, val); + REAL(siglongjmp)(env, val); } #if ASAN_HAS_EXCEPTIONS == 1 @@ -314,9 +314,9 @@ #endif // __APPLE__ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { - CHECK(&real___cxa_throw); + CHECK(REAL(__cxa_throw)); UnpoisonStackFromHereToTop(); - real___cxa_throw(a, b, c); + REAL(__cxa_throw)(a, b, c); } #endif @@ -386,7 +386,7 @@ // memcpy is called during __asan_init() from the internals // of printf(...). if (asan_init_is_running) { - return real_memcpy(to, from, size); + return REAL(memcpy)(to, from, size); } ENSURE_ASAN_INITED(); if (FLAG_replace_intrin) { @@ -398,7 +398,7 @@ ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } - return real_memcpy(to, from, size); + return REAL(memcpy)(to, from, size); } INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) { @@ -407,26 +407,26 @@ ASAN_WRITE_RANGE(from, size); ASAN_READ_RANGE(to, size); } - return real_memmove(to, from, size); + return REAL(memmove)(to, from, size); } INTERCEPTOR(void*, memset, void *block, int c, size_t size) { // memset is called inside INTERCEPT_FUNCTION on Mac. if (asan_init_is_running) { - return real_memset(block, c, size); + return REAL(memset)(block, c, size); } ENSURE_ASAN_INITED(); if (FLAG_replace_intrin) { ASAN_WRITE_RANGE(block, size); } - return real_memset(block, c, size); + return REAL(memset)(block, c, size); } INTERCEPTOR(char*, strchr, const char *str, int c) { ENSURE_ASAN_INITED(); - char *result = real_strchr(str, c); + char *result = REAL(strchr)(str, c); if (FLAG_replace_str) { - size_t bytes_read = (result ? result - str : real_strlen(str)) + 1; + size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; ASAN_READ_RANGE(str, bytes_read); } return result; @@ -456,16 +456,16 @@ INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t from_length = real_strlen(from); + size_t from_length = REAL(strlen)(from); ASAN_READ_RANGE(from, from_length + 1); if (from_length > 0) { - size_t to_length = real_strlen(to); + size_t to_length = REAL(strlen)(to); ASAN_READ_RANGE(to, to_length); ASAN_WRITE_RANGE(to + to_length, from_length + 1); CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1); } } - return real_strcat(to, from); + return REAL(strcat)(to, from); // NOLINT } INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { @@ -488,35 +488,35 @@ // strcpy is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strcpy(to, from); + return REAL(strcpy)(to, from); // NOLINT } ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t from_size = real_strlen(from) + 1; + size_t from_size = REAL(strlen)(from) + 1; CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); ASAN_READ_RANGE(from, from_size); ASAN_WRITE_RANGE(to, from_size); } - return real_strcpy(to, from); + return REAL(strcpy)(to, from); // NOLINT } INTERCEPTOR(char*, strdup, const char *s) { ENSURE_ASAN_INITED(); if (FLAG_replace_str) { - size_t length = real_strlen(s); + size_t length = REAL(strlen)(s); ASAN_READ_RANGE(s, length + 1); } - return real_strdup(s); + return REAL(strdup)(s); } INTERCEPTOR(size_t, strlen, const char *s) { // strlen is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strlen(s); + return REAL(strlen)(s); } ENSURE_ASAN_INITED(); - size_t length = real_strlen(s); + size_t length = REAL(strlen)(s); if (FLAG_replace_str) { ASAN_READ_RANGE(s, length + 1); } @@ -541,7 +541,7 @@ // strncmp is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return real_strncmp(s1, s2, size); + return REAL(strncmp)(s1, s2, size); } unsigned char c1 = 0, c2 = 0; size_t i; @@ -563,13 +563,13 @@ ASAN_READ_RANGE(from, from_size); ASAN_WRITE_RANGE(to, size); } - return real_strncpy(to, from, size); + return REAL(strncpy)(to, from, size); } #ifndef __APPLE__ INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { ENSURE_ASAN_INITED(); - size_t length = real_strnlen(s, maxlen); + size_t length = REAL(strnlen)(s, maxlen); if (FLAG_replace_str) { ASAN_READ_RANGE(s, Min(length + 1, maxlen)); } @@ -596,7 +596,7 @@ if (GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD) { INTERCEPT_FUNCTION(memcpy); } else { - real_memcpy = real_memmove; + REAL(memcpy) = REAL(memmove); } #else // Always wrap memcpy() on non-Darwin platforms. Modified: compiler-rt/trunk/lib/asan/asan_linux.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_linux.cc (original) +++ compiler-rt/trunk/lib/asan/asan_linux.cc Wed Feb 8 07:45:31 2012 @@ -241,7 +241,7 @@ data->filename[path_len] = 0; } else { CHECK(info->dlpi_name); - real_strncpy(data->filename, info->dlpi_name, data->filename_size); + REAL(strncpy)(data->filename, info->dlpi_name, data->filename_size); } data->offset = data->addr - info->dlpi_addr; return 1; Modified: compiler-rt/trunk/lib/asan/asan_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_mac.cc (original) +++ compiler-rt/trunk/lib/asan/asan_mac.cc Wed Feb 8 07:45:31 2012 @@ -209,8 +209,8 @@ if (end) *end = sc->vmaddr + sc->vmsize + dlloff; if (offset) *offset = sc->fileoff; if (filename) { - real_strncpy(filename, _dyld_get_image_name(current_image_), - filename_size); + REAL(strncpy)(filename, _dyld_get_image_name(current_image_), + filename_size); } if (FLAG_v >= 4) Report("LC_SEGMENT: %p--%p %s+%p\n", *start, *end, filename, *offset); @@ -432,8 +432,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - return real_dispatch_async_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_async_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_sync_f, dispatch_queue_t dq, void *ctxt, @@ -445,8 +445,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - return real_dispatch_sync_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_sync_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, @@ -458,8 +458,8 @@ Report("dispatch_after_f: %p\n", asan_ctxt); PRINT_CURRENT_STACK(); } - return real_dispatch_after_f(when, dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_barrier_async_f, dispatch_queue_t dq, void *ctxt, @@ -471,8 +471,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - real_dispatch_barrier_async_f(dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + REAL(dispatch_barrier_async_f)(dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, @@ -485,8 +485,8 @@ asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); } - real_dispatch_group_async_f(group, dq, (void*)asan_ctxt, - asan_dispatch_call_block_and_release); + REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt, + asan_dispatch_call_block_and_release); } // The following stuff has been extremely helpful while looking for the @@ -521,8 +521,9 @@ Report("pthread_workqueue_additem_np: %p\n", asan_ctxt); PRINT_CURRENT_STACK(); } - return real_pthread_workqueue_additem_np(workq, wrap_workitem_func, asan_ctxt, - itemhandlep, gencountp); + return REAL(pthread_workqueue_additem_np)(workq, wrap_workitem_func, + asan_ctxt, itemhandlep, + gencountp); } // CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal @@ -562,7 +563,7 @@ if (__CFStrIsConstant(str)) { return str; } else { - return real_CFStringCreateCopy(alloc, str); + return REAL(CFStringCreateCopy)(alloc, str); } } Modified: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_linux.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc (original) +++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc Wed Feb 8 07:45:31 2012 @@ -71,7 +71,7 @@ INTERCEPTOR(void*, calloc, size_t nmemb, size_t size) { if (!asan_inited) { - // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. const size_t kCallocPoolSize = 1024; static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize]; static size_t allocated; @@ -105,7 +105,7 @@ INTERCEPTOR(struct mallinfo, mallinfo) { struct mallinfo res; - real_memset(&res, 0, sizeof(res)); + REAL(memset)(&res, 0, sizeof(res)); return res; } Modified: compiler-rt/trunk/lib/asan/asan_malloc_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_mac.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_mac.cc (original) +++ compiler-rt/trunk/lib/asan/asan_malloc_mac.cc Wed Feb 8 07:45:31 2012 @@ -92,7 +92,7 @@ void *mz_calloc(malloc_zone_t *zone, size_t nmemb, size_t size) { if (!asan_inited) { - // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym. + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. const size_t kCallocPoolSize = 1024; static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize]; static size_t allocated; @@ -310,7 +310,7 @@ namespace __asan { void ReplaceSystemMalloc() { static malloc_introspection_t asan_introspection; - __asan::real_memset(&asan_introspection, 0, sizeof(asan_introspection)); + __asan::REAL(memset)(&asan_introspection, 0, sizeof(asan_introspection)); asan_introspection.enumerator = &mi_enumerator; asan_introspection.good_size = &mi_good_size; @@ -321,7 +321,7 @@ asan_introspection.force_unlock = &mi_force_unlock; static malloc_zone_t asan_zone; - __asan::real_memset(&asan_zone, 0, sizeof(malloc_zone_t)); + __asan::REAL(memset)(&asan_zone, 0, sizeof(malloc_zone_t)); // Start with a version 4 zone which is used for OS X 10.4 and 10.5. asan_zone.version = 4; Modified: compiler-rt/trunk/lib/asan/asan_poisoning.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_poisoning.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original) +++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Wed Feb 8 07:45:31 2012 @@ -24,8 +24,8 @@ CHECK(AddrIsAlignedByGranularity(addr + size)); uintptr_t shadow_beg = MemToShadow(addr); uintptr_t shadow_end = MemToShadow(addr + size); - CHECK(real_memset != NULL); - real_memset((void*)shadow_beg, value, shadow_end - shadow_beg); + CHECK(REAL(memset) != NULL); + REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg); } void PoisonShadowPartialRightRedzone(uintptr_t addr, @@ -108,7 +108,7 @@ } beg.chunk++; } - real_memset(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk); + REAL(memset)(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk); // Poison if byte in end.offset is unaddressable. if (end.value > 0 && end.value <= end.offset) { *end.chunk = kAsanUserPoisonedMemoryMagic; @@ -140,7 +140,7 @@ *beg.chunk = 0; beg.chunk++; } - real_memset(beg.chunk, 0, end.chunk - beg.chunk); + REAL(memset)(beg.chunk, 0, end.chunk - beg.chunk); if (end.offset > 0 && end.value != 0) { *end.chunk = Max(end.value, end.offset); } Modified: compiler-rt/trunk/lib/asan/asan_posix.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_posix.cc (original) +++ compiler-rt/trunk/lib/asan/asan_posix.cc Wed Feb 8 07:45:31 2012 @@ -35,10 +35,10 @@ if (!AsanInterceptsSignal(signum)) return; struct sigaction sigact; - real_memset(&sigact, 0, sizeof(sigact)); + REAL(memset)(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = handler; sigact.sa_flags = SA_SIGINFO; - CHECK(0 == real_sigaction(signum, &sigact, 0)); + CHECK(0 == REAL(sigaction)(signum, &sigact, 0)); } static void ASAN_OnSIGSEGV(int, siginfo_t *siginfo, void *context) { Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_rtl.cc (original) +++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Feb 8 07:45:31 2012 @@ -148,7 +148,7 @@ // where alloc_i looks like "offset size len ObjectName ". CHECK(frame_descr); // Report the function name and the offset. - const char *name_end = real_strchr(frame_descr, ' '); + const char *name_end = REAL(strchr)(frame_descr, ' '); CHECK(name_end); buf[0] = 0; internal_strncat(buf, frame_descr, Modified: compiler-rt/trunk/lib/asan/asan_stack.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_stack.cc (original) +++ compiler-rt/trunk/lib/asan/asan_stack.cc Wed Feb 8 07:45:31 2012 @@ -140,8 +140,8 @@ // |res| may be greater than check_stack.size, because // UncompressStack(CompressStack(stack)) eliminates the 0x0 frames. CHECK(res >= check_stack.size); - CHECK(0 == real_memcmp(check_stack.trace, stack->trace, - check_stack.size * sizeof(uintptr_t))); + CHECK(0 == REAL(memcmp)(check_stack.trace, stack->trace, + check_stack.size * sizeof(uintptr_t))); #endif return res; Modified: compiler-rt/trunk/lib/asan/asan_stats.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stats.cc?rev=150073&r1=150072&r2=150073&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_stats.cc (original) +++ compiler-rt/trunk/lib/asan/asan_stats.cc Wed Feb 8 07:45:31 2012 @@ -21,8 +21,8 @@ namespace __asan { AsanStats::AsanStats() { - CHECK(real_memset != NULL); - real_memset(this, 0, sizeof(AsanStats)); + CHECK(REAL(memset) != NULL); + REAL(memset)(this, 0, sizeof(AsanStats)); } static void PrintMallocStatsArray(const char *prefix, From samsonov at google.com Wed Feb 8 07:50:01 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 13:50:01 +0000 Subject: [llvm-commits] AddressSanitizer: replace all "real_X" calls with "REAL(X)". (issue 5645054) Message-ID: <20cf3074b4400aeb4a04b8742cac@google.com> On 2012/02/08 12:53:31, glider wrote: > LGTM r150073 http://codereview.appspot.com/5645054/ From timurrrr at google.com Wed Feb 8 08:11:57 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 14:11:57 +0000 Subject: [llvm-commits] [ASan] Move the _ReturnAddress definition out of the __asan:: namespace (issue 5643056) Message-ID: <20cf306f77fe792f5d04b8747a64@google.com> Reviewers: glider, Message: Hi Alexander, Can you please review this small patch? Thanks, Timur Please review this at http://codereview.appspot.com/5643056/ Affected files: M lib/asan/asan_internal.h Index: lib/asan/asan_internal.h diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index fa503795347b1a1250d4ddbe3f01b159ca7bb753..54556a29ad887d1b955d307076d1e2957e8c6df6 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -31,6 +31,9 @@ typedef __int16 int16_t; typedef __int32 int32_t; typedef __int64 int64_t; +extern "C" void* _ReturnAddress(void); +# pragma intrinsic(_ReturnAddress) + # define ALIAS(x) // TODO(timurrrr): do we need this on Windows? # define ALIGNED(x) __declspec(align(x)) # define NOINLINE __declspec(noinline) @@ -215,8 +218,6 @@ const size_t kPageSize = 1UL << kPageSizeBits; # define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) # define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) #else -extern "C" void* _ReturnAddress(void); -# pragma intrinsic(_ReturnAddress) # define GET_CALLER_PC() (uintptr_t)_ReturnAddress() // CaptureStackBackTrace doesn't need to know BP on Windows. // FIXME: This macro is still used when printing error reports though it's not From baldrick at free.fr Wed Feb 8 08:10:53 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 14:10:53 -0000 Subject: [llvm-commits] [llvm] r150074 - /llvm/trunk/lib/Transforms/Scalar/GVN.cpp Message-ID: <20120208141053.E00252A6C12C@llvm.org> Author: baldrick Date: Wed Feb 8 08:10:53 2012 New Revision: 150074 URL: http://llvm.org/viewvc/llvm-project?rev=150074&view=rev Log: Use Use::set rather than finding the operand number of the use and setting that. Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp Modified: llvm/trunk/lib/Transforms/Scalar/GVN.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/GVN.cpp?rev=150074&r1=150073&r2=150074&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/GVN.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/GVN.cpp Wed Feb 8 08:10:53 2012 @@ -1900,12 +1900,9 @@ unsigned Count = 0; for (Value::use_iterator UI = From->use_begin(), UE = From->use_end(); UI != UE; ) { - Instruction *User = cast(*UI); - unsigned OpNum = UI.getOperandNo(); - ++UI; - - if (DT->dominates(Root, User->getParent())) { - User->setOperand(OpNum, To); + Use &U = (UI++).getUse(); + if (DT->dominates(Root, cast(U.getUser())->getParent())) { + U.set(To); ++Count; } } From glider at google.com Wed Feb 8 08:15:53 2012 From: glider at google.com (Alexander Potapenko) Date: Wed, 8 Feb 2012 18:15:53 +0400 Subject: [llvm-commits] [ASan] Move the _ReturnAddress definition out of the __asan:: namespace (issue 5643056) In-Reply-To: <20cf306f77fe792f5d04b8747a64@google.com> References: <20cf306f77fe792f5d04b8747a64@google.com> Message-ID: LGTM From glider at google.com Wed Feb 8 08:14:18 2012 From: glider at google.com (Alexander Potapenko) Date: Wed, 08 Feb 2012 14:14:18 -0000 Subject: [llvm-commits] [compiler-rt] r150075 - /compiler-rt/trunk/lib/asan/asan_internal.h Message-ID: <20120208141418.822FA2A6C12C@llvm.org> Author: glider Date: Wed Feb 8 08:14:18 2012 New Revision: 150075 URL: http://llvm.org/viewvc/llvm-project?rev=150075&view=rev Log: Move the _ReturnAddress definition out of the __asan:: namespace Patch by Timur Iskhodzhanov (timurrrr at google.com) Modified: compiler-rt/trunk/lib/asan/asan_internal.h Modified: compiler-rt/trunk/lib/asan/asan_internal.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=150075&r1=150074&r2=150075&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_internal.h (original) +++ compiler-rt/trunk/lib/asan/asan_internal.h Wed Feb 8 08:14:18 2012 @@ -31,6 +31,9 @@ typedef __int32 int32_t; typedef __int64 int64_t; +extern "C" void* _ReturnAddress(void); +# pragma intrinsic(_ReturnAddress) + # define ALIAS(x) // TODO(timurrrr): do we need this on Windows? # define ALIGNED(x) __declspec(align(x)) # define NOINLINE __declspec(noinline) @@ -215,8 +218,6 @@ # define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) # define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) #else -extern "C" void* _ReturnAddress(void); -# pragma intrinsic(_ReturnAddress) # define GET_CALLER_PC() (uintptr_t)_ReturnAddress() // CaptureStackBackTrace doesn't need to know BP on Windows. // FIXME: This macro is still used when printing error reports though it's not From glider at google.com Wed Feb 8 08:18:46 2012 From: glider at google.com (Alexander Potapenko) Date: Wed, 8 Feb 2012 18:18:46 +0400 Subject: [llvm-commits] [ASan] Move the _ReturnAddress definition out of the __asan:: namespace (issue 5643056) In-Reply-To: References: <20cf306f77fe792f5d04b8747a64@google.com> Message-ID: r150075. From benny.kra at googlemail.com Wed Feb 8 08:43:53 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 08 Feb 2012 14:43:53 -0000 Subject: [llvm-commits] [llvm] r150076 - in /llvm/trunk: include/llvm/MC/MCRegisterInfo.h utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20120208144353.B56F82A6C12C@llvm.org> Author: d0k Date: Wed Feb 8 08:43:53 2012 New Revision: 150076 URL: http://llvm.org/viewvc/llvm-project?rev=150076&view=rev Log: Value initialize MCRegisterClasses. Not sure how could miss this during the MCTargetDesc refactor. Modified: llvm/trunk/include/llvm/MC/MCRegisterInfo.h llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/MC/MCRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCRegisterInfo.h?rev=150076&r1=150075&r2=150076&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCRegisterInfo.h (original) +++ llvm/trunk/include/llvm/MC/MCRegisterInfo.h Wed Feb 8 08:43:53 2012 @@ -27,7 +27,7 @@ public: typedef const unsigned* iterator; typedef const unsigned* const_iterator; -private: + unsigned ID; const char *Name; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes @@ -36,17 +36,6 @@ const iterator RegsBegin, RegsEnd; const unsigned char *const RegSet; const unsigned RegSetSize; -public: - MCRegisterClass(unsigned id, const char *name, - unsigned RS, unsigned Al, int CC, bool Allocable, - iterator RB, iterator RE, const unsigned char *Bits, - unsigned NumBytes) - : ID(id), Name(name), RegSize(RS), Alignment(Al), CopyCost(CC), - Allocatable(Allocable), RegsBegin(RB), RegsEnd(RE), RegSet(Bits), - RegSetSize(NumBytes) { - for (iterator i = RegsBegin; i != RegsEnd; ++i) - assert(contains(*i) && "Bit field corrupted."); - } /// getID() - Return the register class ID number. /// Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=150076&r1=150075&r2=150076&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed Feb 8 08:43:53 2012 @@ -367,7 +367,7 @@ for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = *RegisterClasses[rc]; - OS << " MCRegisterClass(" << RC.getQualifiedName() + "RegClassID" << ", " + OS << " { " << RC.getQualifiedName() + "RegClassID" << ", " << '\"' << RC.getName() << "\", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " @@ -376,7 +376,7 @@ << RC.getName() << ", " << RC.getName() << " + " << RC.getOrder().size() << ", " << RC.getName() << "Bits, sizeof(" << RC.getName() << "Bits)" - << "),\n"; + << " },\n"; } OS << "};\n\n"; From timurrrr at google.com Wed Feb 8 08:49:13 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 14:49:13 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf3074b31ebe2d6204b874ff54@google.com> Reviewers: kcc1, glider, Message: Hi Alexander, Kostya, Can you please review this patch? It makes some simple C tests pass when the tests are compiled with Clang and linked with the runtime built using MSVS cl. It has a lot of FIXMEs but I'd like to have this code under source control and available to someone besides me. This patch should be a no-op change for Linux and Mac. Thanks, Timur. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h#newcode230 lib/asan/asan_internal.h:230: # define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize Alternative suggestions are welcome if you believe this is too hacky. Description: [ASan] The first version of the RTL for Windows Please review this at http://codereview.appspot.com/5647052/ Affected files: M lib/asan/asan_allocator.cc M lib/asan/asan_interceptors.cc M lib/asan/asan_internal.h M lib/asan/asan_rtl.cc A lib/asan/asan_win.cc From timurrrr at google.com Wed Feb 8 08:50:44 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 14:50:44 +0000 Subject: [llvm-commits] [ASan] Replace AsanProcMaps::GetObjectNameAndOffset with a simpler AsanProcMaps::DescribeAddress (issue 5643047) Message-ID: <20cf30334a452a590a04b875051c@google.com> After thinking for a while and studying the code better I've decided to leave the AsanProcMaps as-is. See http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h instead. http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc File lib/asan/asan_linux.cc (right): http://codereview.appspot.com/5643047/diff/1/lib/asan/asan_linux.cc#newcode265 lib/asan/asan_linux.cc:265: if (dl_iterate_phdr(dl_iterate_phdr_callback, &data)) { I meant Mac and Android. On 2012/02/08 10:12:40, glider wrote: > On 2012/02/07 17:41:15, timurrrr_at_google_com wrote: > > Alternative suggestion: > > I can extract this code to IterateForObjectNameAndOffset > > and move the common AsanProcMaps::DescribeAddress code to asan_posix.cc > > (we have the same symbolization capabilities on Linux and Mac, right?) > > > > WDYT? > We do not have dl_iterate_phdr on Mac. http://codereview.appspot.com/5643047/ From glider at google.com Wed Feb 8 09:30:09 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 15:30:09 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf300fb1ef20d8b104b8759294@google.com> http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h#newcode230 lib/asan/asan_internal.h:230: # define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize On 2012/02/08 14:49:13, timurrrr_at_google_com wrote: > Alternative suggestions are welcome if you believe this is too hacky. LG http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode59 lib/asan/asan_win.cc:59: CHECK(fd == 2); // Looks like we only use stderr for AsanWrite? I think we may want to use other fds someday (I'm considering output redirection as one of the possible ways to integrate with Breakpad) http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode62 lib/asan/asan_win.cc:62: return fwrite(buf, 1, count, stderr); The point of AsanWrite is to avoid memory allocations during writes, that's why we're using syscalls on Linux and Mac. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode142 lib/asan/asan_win.cc:142: IMAGEHLP_LINE64 info; Shouldn't this be arch-dependent? http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode155 lib/asan/asan_win.cc:155: " %s+0x%lx", symbol->Name, offset); Again, http://mail.python.org/pipermail/patches/2000-June/000871.html http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode201 lib/asan/asan_win.cc:201: // FIXME: is __declspec enough? You may want to take a look at the TLS implementation in Chrome (I've no idea :)) http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode231 lib/asan/asan_win.cc:231: return getenv(name); Does getenv() allocate memory? If so, you may run into a trouble. http://codereview.appspot.com/5647052/ From aaron at aaronballman.com Wed Feb 8 09:30:58 2012 From: aaron at aaronballman.com (Aaron Ballman) Date: Wed, 8 Feb 2012 09:30:58 -0600 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) In-Reply-To: <20cf3074b31ebe2d6204b874ff54@google.com> References: <20cf3074b31ebe2d6204b874ff54@google.com> Message-ID: On Wed, Feb 8, 2012 at 8:49 AM, wrote: > Reviewers: kcc1, glider, > > Message: > Hi Alexander, Kostya, > > Can you please review this patch? > > It makes some simple C tests pass when the tests are compiled with Clang > and linked with the runtime built using MSVS cl. > > It has a lot of FIXMEs but I'd like to have this code under source > control and available to someone besides me. > > This patch should be a no-op change for Linux and Mac. > > Thanks, > Timur. > > > http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h > File lib/asan/asan_internal.h (right): > > http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_internal.h#newcode230 > lib/asan/asan_internal.h:230: # ?define ASAN_USE_EXTERNAL_SYMBOLIZER > __asan::WinSymbolize > Alternative suggestions are welcome if you believe this is too hacky. > > Description: > [ASan] The first version of the RTL for Windows > > Please review this at http://codereview.appspot.com/5647052/ > > Affected files: > ? M lib/asan/asan_allocator.cc > ? M lib/asan/asan_interceptors.cc > ? M lib/asan/asan_internal.h > ? M lib/asan/asan_rtl.cc > ? A lib/asan/asan_win.cc > +++ b/lib/asan/asan_win.cc > +// Disable "getenv and strcpy are unsafe" warnings. > +#pragma warning(disable: 4996) Instead of the pragma to disable warnings, why not just fix getenv and strcpy? > +void *AsanMprotect(uintptr_t fixed_addr, size_t size) { > + return VirtualAlloc((LPVOID)fixed_addr, size, > + MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); > +} Shouldn't this be doing a VirtualProtect instead of allocating? > +void AsanThread::SetThreadStackTopAndBottom() { > + MEMORY_BASIC_INFORMATION mbi; > + CHECK(VirtualQuery(&mbi /* on stack */, > + &mbi, sizeof(mbi)) != 0); > + // FIXME: is it possible for the stack to not be a single allocation? > + stack_top_ = (uintptr_t)mbi.BaseAddress + mbi.RegionSize; > + stack_bottom_ = (uintptr_t)mbi.AllocationBase; > +} The stack will always be a single block, but I think what you're getting there is including the stack's guard page. Are you sure you want that? Also, I think that's only getting you the reserved size and not the committed size. > + size_t cs_ret = CaptureStackBackTrace(1, max_size, tmp, NULL), > + offset = 0; Since you're already using DbgHelp APIs, would StackWalk64 make a bit more sense? IIRC, it's a bit more accurate than CaptureStackBackTrace. Certainly it gives you more control. You may want to look at LLVMUnhandledExceptionFilter in Signals.inc because a lot of the stack walking fun is already done there. Perhaps we could refactor it to use common code? ~Aaron From greened at obbligato.org Wed Feb 8 09:34:38 2012 From: greened at obbligato.org (David A. Greene) Date: Wed, 08 Feb 2012 09:34:38 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <20120208063657.D34492A6C12C@llvm.org> (Craig Topper's message of "Wed, 08 Feb 2012 06:36:57 -0000") References: <20120208063657.D34492A6C12C@llvm.org> Message-ID: <877gzxpcdt.fsf@smith.obbligato.org> Craig Topper writes: > Author: ctopper > Date: Wed Feb 8 00:36:57 2012 > New Revision: 150060 > > URL: http://llvm.org/viewvc/llvm-project?rev=150060&view=rev > Log: > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target specific node > and remove intrinsic patterns. Please don't do this gratuitously. Lots of users use the Intel intrinsics to write "asm" in their high-level code. We generally try to leave that code alone and respect what the user has done. Without intrinsics this is harder to do. -Dave From samsonov at google.com Wed Feb 8 09:38:11 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 15:38:11 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf306f77fedd845c04b875ae3b@google.com> kcc@: 1) Moved auxiliary functions under __interception namespace. 2) Why can't we for simplicity declare real_f inside __interception namespace as well? This may break if two different libraries using interception are linked together, but it's a mess anyway, as they'll have interceptors for the same functions. 3) This CL is large already, so I'd prefer to resolve some FIXMEs after this CL is submitted, if you don't mind. glider@ suggested we should remove all OS-specific details from the header "interception.h", so I moved them to OS-specific headers. In this way the user code will not include or mach_override.h http://codereview.appspot.com/5642046/diff/1012/asan_interceptors.h File asan_interceptors.h (right): http://codereview.appspot.com/5642046/diff/1012/asan_interceptors.h#newcode34 asan_interceptors.h:34: size_t internal_strlen(const char *s); On 2012/02/08 08:19:17, glider wrote: > BTW aren't these functions already declared in asan_internal.h? Not yet. http://codereview.appspot.com/5642046/ From greened at obbligato.org Wed Feb 8 09:36:04 2012 From: greened at obbligato.org (David A. Greene) Date: Wed, 08 Feb 2012 09:36:04 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Craig Topper's message of "Wed, 8 Feb 2012 00:03:54 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> Message-ID: <8739alpcbf.fsf@smith.obbligato.org> Craig Topper writes: > I do intend to remove the intrinsics eventually. I just haven't looked > at what I need to do in order to do that in the AutoUpgrade code so I > didn't do it yet. The previous intrinsic removal was my first time > using the IR builder functions so I'm pretty new to that side of llvm. > > Would you prefer me to put the builtin lines back or would you rather > fix dragonegg to not use them? Please put back the builtin lines and do not delete the intrinsics. Intrinsics are used by users and we want to respect that. The builtins are useful for running the C backend to get something compilable by gcc. This is very helpful for debugging. -Dave From greened at obbligato.org Wed Feb 8 09:37:04 2012 From: greened at obbligato.org (David A. Greene) Date: Wed, 08 Feb 2012 09:37:04 -0600 Subject: [llvm-commits] [llvm] r150067 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td In-Reply-To: <20120208082930.E4E0B2A6C12C@llvm.org> (Craig Topper's message of "Wed, 08 Feb 2012 08:29:30 -0000") References: <20120208082930.E4E0B2A6C12C@llvm.org> Message-ID: <87y5sdnxpb.fsf@smith.obbligato.org> Craig Topper writes: > Author: ctopper > Date: Wed Feb 8 02:29:30 2012 > New Revision: 150067 > > URL: http://llvm.org/viewvc/llvm-project?rev=150067&view=rev > Log: > Remove a couple unneeded intrinsic patterns Don't! They aren't uneeded. I've explained why in a couple of e-mails. -Dave From glider at google.com Wed Feb 8 09:40:33 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 15:40:33 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf3074b4405283b904b875b7a4@google.com> http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_interceptors.cc#newcode32 lib/asan/asan_interceptors.cc:32: # include // FIXME: remove when we start intercepting on Windows. Do you still need it after you've declared _ReturnAddress? http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode231 lib/asan/asan_win.cc:231: return getenv(name); Hint: http://code.google.com/p/gperftools/source/browse/trunk/src/base/sysinfo.cc http://codereview.appspot.com/5647052/ From baldrick at free.fr Wed Feb 8 09:41:32 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 16:41:32 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <8739alpcbf.fsf@smith.obbligato.org> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> Message-ID: <4F3297AC.6010409@free.fr> Hi David, >> I do intend to remove the intrinsics eventually. I just haven't looked >> at what I need to do in order to do that in the AutoUpgrade code so I >> didn't do it yet. The previous intrinsic removal was my first time >> using the IR builder functions so I'm pretty new to that side of llvm. >> >> Would you prefer me to put the builtin lines back or would you rather >> fix dragonegg to not use them? > > Please put back the builtin lines and do not delete the intrinsics. > > Intrinsics are used by users and we want to respect that. > > The builtins are useful for running the C backend to get something > compilable by gcc. This is very helpful for debugging. once auto-upgrade support for these intrinsics goes in, won't everything be fine? Old bitcode using the intrinsics will be turned into generic LLVM IR (shuffles). The C backend should turn this into valid C, though indeed not into the GCC builtins anymore. Frontends can pretty easily just generate the generic IR rather than the intrinsics (at least I hope it's easy, since I'm going to have to do this in my front-end). Ciao, Duncan. From glider at google.com Wed Feb 8 09:43:11 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 15:43:11 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf3074b31ec4753404b875c06a@google.com> LGTM http://codereview.appspot.com/5642046/ From craig.topper at gmail.com Wed Feb 8 09:57:19 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 07:57:19 -0800 Subject: [llvm-commits] [llvm] r150067 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td In-Reply-To: <87y5sdnxpb.fsf@smith.obbligato.org> References: <20120208082930.E4E0B2A6C12C@llvm.org> <87y5sdnxpb.fsf@smith.obbligato.org> Message-ID: They are unneeded because LowerINTRINSIC_WO_CHAIN already converted it to a target specific node before instruction selection. ~Craig On Wed, Feb 8, 2012 at 7:37 AM, David A. Greene wrote: > Craig Topper writes: > > > Author: ctopper > > Date: Wed Feb 8 02:29:30 2012 > > New Revision: 150067 > > > > URL: http://llvm.org/viewvc/llvm-project?rev=150067&view=rev > > Log: > > Remove a couple unneeded intrinsic patterns > > Don't! They aren't uneeded. > > I've explained why in a couple of e-mails. > > -Dave > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/fa15dc45/attachment-0001.html From craig.topper at gmail.com Wed Feb 8 10:03:40 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 08:03:40 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F3297AC.6010409@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: On Wed, Feb 8, 2012 at 7:41 AM, Duncan Sands wrote: > Hi David, > > > I do intend to remove the intrinsics eventually. I just haven't looked >>> at what I need to do in order to do that in the AutoUpgrade code so I >>> didn't do it yet. The previous intrinsic removal was my first time >>> using the IR builder functions so I'm pretty new to that side of llvm. >>> >>> Would you prefer me to put the builtin lines back or would you rather >>> fix dragonegg to not use them? >>> >> >> Please put back the builtin lines and do not delete the intrinsics. >> >> Intrinsics are used by users and we want to respect that. >> >> The builtins are useful for running the C backend to get something >> compilable by gcc. This is very helpful for debugging. >> > > once auto-upgrade support for these intrinsics goes in, won't everything be > fine? Old bitcode using the intrinsics will be turned into generic LLVM IR > (shuffles). The C backend should turn this into valid C, though indeed not > into the GCC builtins anymore. Frontends can pretty easily just generate > the generic IR rather than the intrinsics (at least I hope it's easy, > since I'm > going to have to do this in my front-end). > > Ciao, Duncan. > LLVM doesn't match gcc on a lot of builtins. Chris also stated to me in e-mail that matching gcc on vector builtins isn't a goal. Most of the x86 shuffle instructions don't have llvm intrinsics and instead use the generic _builtin_shufflevector in the *mmintrin.h header files in clang. My goal here was only to make a few more shuffles match the behavior of the other shuffles in this respect. -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/05de4b0e/attachment.html From dag at cray.com Wed Feb 8 10:08:03 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 10:08:03 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F3297AC.6010409@free.fr> (Duncan Sands's message of "Wed, 08 Feb 2012 16:41:32 +0100") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: Duncan Sands writes: >> Intrinsics are used by users and we want to respect that. >> >> The builtins are useful for running the C backend to get something >> compilable by gcc. This is very helpful for debugging. > > once auto-upgrade support for these intrinsics goes in, won't everything be > fine? Old bitcode using the intrinsics will be turned into generic LLVM IR > (shuffles). The C backend should turn this into valid C, though indeed not > into the GCC builtins anymore. My experience with the C backend says otherwise. I've run across lots of cases where shuffles could not be handled. Remember, gcc is not the only vectorizer out there. That's part of the reason I started to write a new C backend. Though that's stalled at the moment, it's still on my TODO list. > Frontends can pretty easily just generate the generic IR rather than > the intrinsics (at least I hope it's easy, since I'm going to have to > do this in my front-end). I don't know of any way to generate generic IR and guarantee that the instruction the user selected through an intrinsic will be the instruction selected by LLVM's isel. There are too many transformation steps in-between. -Dave From dag at cray.com Wed Feb 8 10:12:46 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 10:12:46 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Craig Topper's message of "Wed, 8 Feb 2012 08:03:40 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: Craig Topper writes: > LLVM doesn't match gcc on a lot of builtins. Chris also stated to me > in e-mail that matching gcc on vector builtins isn't a goal. Most of > the x86 shuffle instructions don't have llvm intrinsics and instead > use the generic _builtin_shufflevector in the *mmintrin.h header files > in clang.? My goal here was only to make a few more shuffles match the > behavior of? the other shuffles in this respect. Not everthing is Clang. Lots of people use GCC builtins and expect that code to be honored. We can't do that without intrinsics. If anything, I would like to see *more* x86 intrinsics. In fact we have a bunch here that I was planning to send up. -Dave From baldrick at free.fr Wed Feb 8 10:13:13 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 17:13:13 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: <4F329F19.2040709@free.fr> Hi Dave, >>> Intrinsics are used by users and we want to respect that. >>> >>> The builtins are useful for running the C backend to get something >>> compilable by gcc. This is very helpful for debugging. >> >> once auto-upgrade support for these intrinsics goes in, won't everything be >> fine? Old bitcode using the intrinsics will be turned into generic LLVM IR >> (shuffles). The C backend should turn this into valid C, though indeed not >> into the GCC builtins anymore. > > My experience with the C backend says otherwise. I've run across lots > of cases where shuffles could not be handled. then fix the C backend? I mean, it is clear that any shuffle can be written in C (not necessarily efficiently). Or maybe you mean that the C backend outputs something but that it is too horrible and inefficient for your needs? Remember, gcc is not the > only vectorizer out there. > > That's part of the reason I started to write a new C backend. Though > that's stalled at the moment, it's still on my TODO list. Ah, OK! > >> Frontends can pretty easily just generate the generic IR rather than >> the intrinsics (at least I hope it's easy, since I'm going to have to >> do this in my front-end). > > I don't know of any way to generate generic IR and guarantee that the > instruction the user selected through an intrinsic will be the > instruction selected by LLVM's isel. There are too many transformation > steps in-between. Of course there is no such guarantee. The question is whether doing things using generic IR is mostly a win or not. Maybe today it's often not a win, but since that's fixable it seems to me that the "use generic IR if not too crazy" path is on the whole the right way to go. Ciao, Duncan. From timurrrr at google.com Wed Feb 8 10:16:01 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 16:16:01 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf300fb1ef3181a104b876361e@google.com> PTAL On Wed, Feb 8, 2012 at 7:30 PM, Aaron Ballman wrote: Aaron, can you please make the comments in the web interface of rietveld? (by double-clicking the source line you'd like to comment on) It's a bit more convenient to see all the comments in the web diff than having a half there and another half in the email. Thanks! >> +// Disable "getenv and strcpy are unsafe" warnings. >> +#pragma warning(disable: 4996) > Instead of the pragma to disable warnings, why not just fix getenv and strcpy? Turns out I've forgotten to remove "strcpy" from this comment; and now I've got rid of getenv() too. >> +void *AsanMprotect(uintptr_t fixed_addr, size_t size) { >> + ?return VirtualAlloc((LPVOID)fixed_addr, size, >> + ? ? ? ? ? ? ? ? ? ? ?MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); >> +} > Shouldn't this be doing a VirtualProtect instead of allocating? It turns out AsanMprotect must allocate + protect, so VirtualProtect is not enough. I don't like the definition of AsanMprotect too :) > The stack will always be a single block, but I think what you're > getting there is including the stack's guard page. ?Are you sure you > want that? ?Also, I think that's only getting you the reserved size > and not the committed size. That's a good question. I'm not sure. I've added a comment so I'll definitely come back to this question once I start writing tests for stack OOBs. > Since you're already using DbgHelp APIs, would StackWalk64 make a bit > more sense? ?IIRC, it's a bit more accurate than > CaptureStackBackTrace. ?Certainly it gives you more control. > You may want to look at LLVMUnhandledExceptionFilter in Signals.inc > because a lot of the stack walking fun is already done there. ?Perhaps > we could refactor it to use common code? I'll decide later. First we need to be sure that CaptureStackBackTrace is not what we want. -- Thanks, Timur http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_interceptors.cc#newcode32 lib/asan/asan_interceptors.cc:32: # include // FIXME: remove when we start intercepting on Windows. On 2012/02/08 15:40:33, glider wrote: > Do you still need it after you've declared _ReturnAddress? Yes, intrinsic versions of memcpy/memset are defined there. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode59 lib/asan/asan_win.cc:59: CHECK(fd == 2); // Looks like we only use stderr for AsanWrite? On 2012/02/08 15:30:09, glider wrote: > I think we may want to use other fds someday (I'm considering output redirection > as one of the possible ways to integrate with Breakpad) Replaced CHECK with "if()" http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode62 lib/asan/asan_win.cc:62: return fwrite(buf, 1, count, stderr); On 2012/02/08 15:30:09, glider wrote: > The point of AsanWrite is to avoid memory allocations during writes, that's why > we're using syscalls on Linux and Mac. I know, that's why I've added a FIXME. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode142 lib/asan/asan_win.cc:142: IMAGEHLP_LINE64 info; On 2012/02/08 15:30:09, glider wrote: > Shouldn't this be arch-dependent? No, see the link in the code above + http://msdn.microsoft.com/en-us/library/ms681330(v=vs.85).aspx http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode155 lib/asan/asan_win.cc:155: " %s+0x%lx", symbol->Name, offset); On 2012/02/08 15:30:09, glider wrote: > Again, http://mail.python.org/pipermail/patches/2000-June/000871.html Done. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode201 lib/asan/asan_win.cc:201: // FIXME: is __declspec enough? On 2012/02/08 15:30:09, glider wrote: > You may want to take a look at the TLS implementation in Chrome (I've no idea > :)) That's what FIXME is about. I'd like to decide later. http://codereview.appspot.com/5647052/diff/4001/lib/asan/asan_win.cc#newcode231 lib/asan/asan_win.cc:231: return getenv(name); On 2012/02/08 15:30:09, glider wrote: > Does getenv() allocate memory? If so, you may run into a trouble. Hm, in fact we can just return NULL for now as it's only used for ASAN_OPTIONS. http://codereview.appspot.com/5647052/ From baldrick at free.fr Wed Feb 8 10:21:28 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 17:21:28 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: <4F32A108.2030408@free.fr> Hi Dave, >> LLVM doesn't match gcc on a lot of builtins. Chris also stated to me >> in e-mail that matching gcc on vector builtins isn't a goal. Most of >> the x86 shuffle instructions don't have llvm intrinsics and instead >> use the generic _builtin_shufflevector in the *mmintrin.h header files >> in clang. My goal here was only to make a few more shuffles match the >> behavior of the other shuffles in this respect. > > Not everthing is Clang. Lots of people use GCC builtins and expect that > code to be honored. We can't do that without intrinsics. I think you are swimming against the tide here. Remember when C programmers used to complain because the compiler didn't just directly translate their C into the obvious assembly code any more? People have mostly gotten over that now since most of the time all those compiler transformations resulted in better code. C isn't portable assembler any more... Remember the days when C programmers could rely on builtins being directly translated into the obvious assembly code? People have mostly gotten over that now since ... oops - we aren't there yet, wait a few years! Here's another one that might be coming: remember when C programmers could rely on their inline assembly being squirted directly out into the assembler, without the compiler understanding and "improving" it? Well, who knows where we will end up, but I suspect the general trend is that compilers will more and more fiddle with anything they can get their hands on, even things that used to be sacrosanct and mostly just ignored. > If anything, I would like to see *more* x86 intrinsics. In fact we have > a bunch here that I was planning to send up. If they can't be expressed simply as generic IR, then an intrinsic is appropriate so sure go ahead! Ciao, Duncan. From glider at google.com Wed Feb 8 10:41:55 2012 From: glider at google.com (glider at google.com) Date: Wed, 08 Feb 2012 16:41:55 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf3074b440ccd4aa04b87692a1@google.com> I see no problems with this code, awaiting for others. http://codereview.appspot.com/5647052/ From dag at cray.com Wed Feb 8 10:43:22 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 10:43:22 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F329F19.2040709@free.fr> (Duncan Sands's message of "Wed, 8 Feb 2012 10:13:13 -0600") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: Duncan Sands writes: >> My experience with the C backend says otherwise. I've run across lots >> of cases where shuffles could not be handled. > > then fix the C backend? Not possible with the current C backend. It uses illegal types, for one. >> I don't know of any way to generate generic IR and guarantee that the >> instruction the user selected through an intrinsic will be the >> instruction selected by LLVM's isel. There are too many transformation >> steps in-between. > > Of course there is no such guarantee. The question is whether doing things > using generic IR is mostly a win or not. Maybe today it's often not a win, > but since that's fixable it seems to me that the "use generic IR if not too > crazy" path is on the whole the right way to go. Whether generic IR is a "win" isn't the primary issue here. The issue is that the user wrote code using intrinsics and expects that exact code to be in the asm. Whether or not that is the best performing code possible doesn't matter. It's what they want and we have to respect it. Our customers demand it. -Dave From baldrick at free.fr Wed Feb 8 10:44:14 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 17:44:14 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: <4F32A65E.802@free.fr> Hi Dave, > Whether generic IR is a "win" isn't the primary issue here. The issue > is that the user wrote code using intrinsics and expects that exact code > to be in the asm. Whether or not that is the best performing code > possible doesn't matter. It's what they want and we have to respect it. > Our customers demand it. then I guess you will have to use inline asm. Ciao, Duncan. From dag at cray.com Wed Feb 8 10:57:14 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 10:57:14 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F32A108.2030408@free.fr> (Duncan Sands's message of "Wed, 8 Feb 2012 10:21:28 -0600") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F32A108.2030408@free.fr> Message-ID: Duncan Sands writes: >> Not everthing is Clang. Lots of people use GCC builtins and expect that >> code to be honored. We can't do that without intrinsics. > > I think you are swimming against the tide here. It's not my desire. It's a customer requirement. Really, what's wrong with keeping intrinsics around if people find them necessary and useful? It doesn't mean clang has to use them. We need this ability. I'm telling you, we do. > Remember when C programmers used to complain because the compiler > didn't just directly translate their C into the obvious assembly code > any more... None of this historical essay matters. We have customers who demand that intrinsics (intrinsics, not general C code), remain, well, intrinsics. >> If anything, I would like to see *more* x86 intrinsics. In fact we have >> a bunch here that I was planning to send up. > > If they can't be expressed simply as generic IR, then an intrinsic is > appropriate so sure go ahead! I'm talking about cases where it CAN be expressed with generic IR. Apple may not have these needs, but others do. -Dave From dag at cray.com Wed Feb 8 11:02:27 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 11:02:27 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F32A65E.802@free.fr> (Duncan Sands's message of "Wed, 08 Feb 2012 17:44:14 +0100") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> Message-ID: Duncan Sands writes: > Hi Dave, > >> Whether generic IR is a "win" isn't the primary issue here. The issue >> is that the user wrote code using intrinsics and expects that exact code >> to be in the asm. Whether or not that is the best performing code >> possible doesn't matter. It's what they want and we have to respect it. >> Our customers demand it. > > then I guess you will have to use inline asm. We can't use inline asm. Our compiler does not support it. -Dave From dag at cray.com Wed Feb 8 11:03:12 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 11:03:12 -0600 Subject: [llvm-commits] [llvm] r150067 - /llvm/trunk/lib/Target/X86/X86InstrSSE.td In-Reply-To: (Craig Topper's message of "Wed, 8 Feb 2012 07:57:19 -0800") References: <20120208082930.E4E0B2A6C12C@llvm.org> <87y5sdnxpb.fsf@smith.obbligato.org> Message-ID: Craig Topper writes: > They are unneeded because LowerINTRINSIC_WO_CHAIN already converted it > to a target specific node before instruction selection. Ok, that should be fine. Thanks for the explanation. -Dave From baldrick at free.fr Wed Feb 8 11:03:44 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 18:03:44 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> Message-ID: <4F32AAF0.6090601@free.fr> Hi Dave, >>> Whether generic IR is a "win" isn't the primary issue here. The issue >>> is that the user wrote code using intrinsics and expects that exact code >>> to be in the asm. Whether or not that is the best performing code >>> possible doesn't matter. It's what they want and we have to respect it. >>> Our customers demand it. >> >> then I guess you will have to use inline asm. > > We can't use inline asm. Our compiler does not support it. your front-end can expand the builtin into the corresponding LLVM inline asm expression when generating the IR. Ciao, Duncan. From baldrick at free.fr Wed Feb 8 11:11:04 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 18:11:04 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> Message-ID: <4F32ACA8.9080805@free.fr> Hi Craig, On 08/02/12 08:44, Craig Topper wrote: > I only removed the builtin lines. I didn't delete the intrinsics themselves. I see that you removed all clang support for these builtins, rather than having clang turn the builtin into a shufflevector instruction (which is what I thought you did). Is that wise? You just reduced GCC compatibility, when you could have kept it by expanding the builtins into generic IR. Ciao, Duncan. > > On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > wrote: > > Hi Craig, > > > Remove GCC builtins for vpermilp* intrinsics as clang no longer needs > them. Custom lower the intrinsics to the vpermilp target specific node and > remove intrinsic patterns. > > what about auto-upgrade? > > Ciao, Duncan. > > > > > Modified: > > llvm/trunk/include/llvm/IntrinsicsX86.td > > llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > llvm/trunk/lib/Target/X86/X86InstrSSE.td > > > > Modified: llvm/trunk/include/llvm/IntrinsicsX86.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IntrinsicsX86.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/include/llvm/IntrinsicsX86.td (original) > > +++ llvm/trunk/include/llvm/IntrinsicsX86.td Wed Feb 8 00:36:57 2012 > > @@ -1092,17 +1092,17 @@ > > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, > > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_vpermilpd">, > > + def int_x86_avx_vpermil_pd : > > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_vpermilps">, > > + def int_x86_avx_vpermil_ps : > > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > > > - def int_x86_avx_vpermil_pd_256 : > GCCBuiltin<"__builtin_ia32_vpermilpd256">, > > + def int_x86_avx_vpermil_pd_256 : > > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, > > llvm_i8_ty], [IntrNoMem]>; > > - def int_x86_avx_vpermil_ps_256 : > GCCBuiltin<"__builtin_ia32_vpermilps256">, > > + def int_x86_avx_vpermil_ps_256 : > > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, > > llvm_i8_ty], [IntrNoMem]>; > > } > > > > Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original) > > +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Feb 8 00:36:57 2012 > > @@ -9488,6 +9488,12 @@ > > case Intrinsic::x86_avx2_vperm2i128: > > return DAG.getNode(X86ISD::VPERM2X128, dl, Op.getValueType(), > > Op.getOperand(1), Op.getOperand(2), > Op.getOperand(3)); > > + case Intrinsic::x86_avx_vpermil_ps: > > + case Intrinsic::x86_avx_vpermil_pd: > > + case Intrinsic::x86_avx_vpermil_ps_256: > > + case Intrinsic::x86_avx_vpermil_pd_256: > > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), > > + Op.getOperand(1), Op.getOperand(2)); > > > > // ptest and testp intrinsics. The intrinsic these come from are > designed to > > // return an integer value, not just an instruction so lower it to > the ptest > > > > Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td > > URL: > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=150060&r1=150059&r2=150060&view=diff > > > > ============================================================================== > > --- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original) > > +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Wed Feb 8 00:36:57 2012 > > @@ -7129,8 +7129,8 @@ > > // > > multiclass avx_permil opc_rm, bits<8> opc_rmi, string OpcodeStr, > > RegisterClass RC, X86MemOperand x86memop_f, > > - X86MemOperand x86memop_i, PatFrag f_frag, PatFrag > i_frag, > > - Intrinsic IntVar, Intrinsic IntImm> { > > + X86MemOperand x86memop_i, PatFrag i_frag, > > + Intrinsic IntVar, ValueType vt> { > > def rr : AVX8I > (ins RC:$src1, RC:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > @@ -7144,63 +7144,40 @@ > > def ri : AVXAIi8 > (ins RC:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; > > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 > imm:$src2))))]>, VEX; > > def mi : AVXAIi8 > (ins x86memop_f:$src1, i8imm:$src2), > > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, $src1, > $src2}"), > > - [(set RC:$dst, (IntImm (f_frag addr:$src1), imm:$src2))]>, VEX; > > + [(set RC:$dst, > > + (vt (X86VPermilp (memop addr:$src1), (i8 imm:$src2))))]>, > VEX; > > } > > > > let ExeDomain = SSEPackedSingle in { > > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, f128mem, > i128mem, > > - memopv4f32, memopv2i64, > > - int_x86_avx_vpermilvar_ps, > > - int_x86_avx_vpermil_ps>; > > + memopv2i64, int_x86_avx_vpermilvar_ps, > v4f32>; > > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, f256mem, > i256mem, > > - memopv8f32, memopv4i64, > > - int_x86_avx_vpermilvar_ps_256, > > - int_x86_avx_vpermil_ps_256>; > > + memopv4i64, int_x86_avx_vpermilvar_ps_256, > v8f32>; > > } > > let ExeDomain = SSEPackedDouble in { > > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, f128mem, > i128mem, > > - memopv2f64, memopv2i64, > > - int_x86_avx_vpermilvar_pd, > > - int_x86_avx_vpermil_pd>; > > + memopv2i64, int_x86_avx_vpermilvar_pd, > v2f64>; > > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, f256mem, > i256mem, > > - memopv4f64, memopv4i64, > > - int_x86_avx_vpermilvar_pd_256, > > - int_x86_avx_vpermil_pd_256>; > > + memopv4i64, int_x86_avx_vpermilvar_pd_256, > v4f64>; > > } > > > > let Predicates = [HasAVX] in { > > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPSYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > - (VPERMILPDYri VR256:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPSYri VR256:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), > > (VPERMILPDYri VR256:$src1, imm:$imm)>; > > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSYmi addr:$src1, imm:$imm)>; > > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDYmi addr:$src1, imm:$imm)>; > > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), > > (i8 imm:$imm))), > > (VPERMILPSYmi addr:$src1, imm:$imm)>; > > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDYmi addr:$src1, imm:$imm)>; > > > > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPSri VR128:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > - (VPERMILPDri VR128:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), > > (VPERMILPDri VR128:$src1, imm:$imm)>; > > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPSmi addr:$src1, imm:$imm)>; > > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 imm:$imm))), > > - (VPERMILPDmi addr:$src1, imm:$imm)>; > > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 imm:$imm))), > > (VPERMILPDmi addr:$src1, imm:$imm)>; > > } > > > > > > _______________________________________________ > > llvm-commits mailing list > > llvm-commits at cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > > -- > ~Craig From spande at codeaurora.org Wed Feb 8 11:12:45 2012 From: spande at codeaurora.org (Sirish Pande) Date: Wed, 08 Feb 2012 11:12:45 -0600 Subject: [llvm-commits] Optimize sign-extends and negative predicates in Hexagon Message-ID: <4F32AD0D.9030606@codeaurora.org> I have attached a patch that optimizes the sign extends and negative predicates in Hexagon. This is very specific to Hexagon, and it won't affect any other target. This patch replaces the file HexagonOptimizeSZExtends.cpp with HexagonPeephole.cpp as it accomplishes more than optimizing sign extends. Sirish -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: Optimize-redundant-sign-extends-and-negative-predicates.patch Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/5094b443/attachment-0001.pl From craig.topper at gmail.com Wed Feb 8 11:21:22 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 09:21:22 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F32ACA8.9080805@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> Message-ID: On Wed, Feb 8, 2012 at 9:11 AM, Duncan Sands wrote: > Hi Craig, > > > On 08/02/12 08:44, Craig Topper wrote: > >> I only removed the builtin lines. I didn't delete the intrinsics >> themselves. >> > > I see that you removed all clang support for these builtins, rather than > having > clang turn the builtin into a shufflevector instruction (which is what I > thought > you did). Is that wise? You just reduced GCC compatibility, when you > could > have kept it by expanding the builtins into generic IR. > > Ciao, Duncan. > That's correct, but what I did is no different than what is already done for pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, pshufhw, etc. > > >> On Tue, Feb 7, 2012 at 11:30 PM, Duncan Sands > > wrote: >> >> Hi Craig, >> >> > Remove GCC builtins for vpermilp* intrinsics as clang no longer >> needs >> them. Custom lower the intrinsics to the vpermilp target specific node >> and >> remove intrinsic patterns. >> >> what about auto-upgrade? >> >> Ciao, Duncan. >> >> > >> > Modified: >> > llvm/trunk/include/llvm/**IntrinsicsX86.td >> > llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp >> > llvm/trunk/lib/Target/X86/**X86InstrSSE.td >> > >> > Modified: llvm/trunk/include/llvm/**IntrinsicsX86.td >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/include/** >> llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> > llvm/IntrinsicsX86.td?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/include/llvm/**IntrinsicsX86.td (original) >> > +++ llvm/trunk/include/llvm/**IntrinsicsX86.td Wed Feb 8 00:36:57 >> 2012 >> > @@ -1092,17 +1092,17 @@ >> > Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, >> > llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd : GCCBuiltin<"__builtin_ia32_** >> vpermilpd">, >> > + def int_x86_avx_vpermil_pd : >> > Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps : GCCBuiltin<"__builtin_ia32_** >> vpermilps">, >> > + def int_x86_avx_vpermil_ps : >> > Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > >> > - def int_x86_avx_vpermil_pd_256 : >> GCCBuiltin<"__builtin_ia32_**vpermilpd256">, >> > + def int_x86_avx_vpermil_pd_256 : >> > Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > - def int_x86_avx_vpermil_ps_256 : >> GCCBuiltin<"__builtin_ia32_**vpermilps256">, >> > + def int_x86_avx_vpermil_ps_256 : >> > Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty, >> > llvm_i8_ty], [IntrNoMem]>; >> > } >> > >> > Modified: llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/lib/Target/** >> X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> > X86/X86ISelLowering.cpp?rev=**150060&r1=150059&r2=150060&**view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp (original) >> > +++ llvm/trunk/lib/Target/X86/**X86ISelLowering.cpp Wed Feb 8 >> 00:36:57 2012 >> > @@ -9488,6 +9488,12 @@ >> > case Intrinsic::x86_avx2_**vperm2i128: >> > return DAG.getNode(X86ISD::**VPERM2X128, dl, >> Op.getValueType(), >> > Op.getOperand(1), Op.getOperand(2), >> Op.getOperand(3)); >> > + case Intrinsic::x86_avx_vpermil_ps: >> > + case Intrinsic::x86_avx_vpermil_pd: >> > + case Intrinsic::x86_avx_vpermil_ps_**256: >> > + case Intrinsic::x86_avx_vpermil_pd_**256: >> > + return DAG.getNode(X86ISD::VPERMILP, dl, Op.getValueType(), >> > + Op.getOperand(1), Op.getOperand(2)); >> > >> > // ptest and testp intrinsics. The intrinsic these come from are >> designed to >> > // return an integer value, not just an instruction so lower it >> to >> the ptest >> > >> > Modified: llvm/trunk/lib/Target/X86/**X86InstrSSE.td >> > URL: >> http://llvm.org/viewvc/llvm-**project/llvm/trunk/lib/Target/** >> X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> > X86/X86InstrSSE.td?rev=150060&**r1=150059&r2=150060&view=diff >> > >> > >> ==============================**==============================** >> ================== >> > --- llvm/trunk/lib/Target/X86/**X86InstrSSE.td (original) >> > +++ llvm/trunk/lib/Target/X86/**X86InstrSSE.td Wed Feb 8 00:36:57 >> 2012 >> > @@ -7129,8 +7129,8 @@ >> > // >> > multiclass avx_permil opc_rm, bits<8> opc_rmi, string >> OpcodeStr, >> > RegisterClass RC, X86MemOperand x86memop_f, >> > - X86MemOperand x86memop_i, PatFrag f_frag, >> PatFrag >> i_frag, >> > - Intrinsic IntVar, Intrinsic IntImm> { >> > + X86MemOperand x86memop_i, PatFrag i_frag, >> > + Intrinsic IntVar, ValueType vt> { >> > def rr : AVX8I> > (ins RC:$src1, RC:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, >> $src2}"), >> > @@ -7144,63 +7144,40 @@ >> > def ri : AVXAIi8> > (ins RC:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, >> $src2}"), >> > - [(set RC:$dst, (IntImm RC:$src1, imm:$src2))]>, VEX; >> > + [(set RC:$dst, (vt (X86VPermilp RC:$src1, (i8 >> imm:$src2))))]>, VEX; >> > def mi : AVXAIi8> > (ins x86memop_f:$src1, i8imm:$src2), >> > !strconcat(OpcodeStr, "\t{$src2, $src1, $dst|$dst, >> $src1, >> $src2}"), >> > - [(set RC:$dst, (IntImm (f_frag addr:$src1), >> imm:$src2))]>, VEX; >> > + [(set RC:$dst, >> > + (vt (X86VPermilp (memop addr:$src1), (i8 >> imm:$src2))))]>, >> VEX; >> > } >> > >> > let ExeDomain = SSEPackedSingle in { >> > defm VPERMILPS : avx_permil<0x0C, 0x04, "vpermilps", VR128, >> f128mem, >> i128mem, >> > - memopv4f32, memopv2i64, >> > - int_x86_avx_vpermilvar_ps, >> > - int_x86_avx_vpermil_ps>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_ps, >> v4f32>; >> > defm VPERMILPSY : avx_permil<0x0C, 0x04, "vpermilps", VR256, >> f256mem, >> i256mem, >> > - memopv8f32, memopv4i64, >> > - int_x86_avx_vpermilvar_ps_256, >> > - int_x86_avx_vpermil_ps_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_ps_256, >> v8f32>; >> > } >> > let ExeDomain = SSEPackedDouble in { >> > defm VPERMILPD : avx_permil<0x0D, 0x05, "vpermilpd", VR128, >> f128mem, >> i128mem, >> > - memopv2f64, memopv2i64, >> > - int_x86_avx_vpermilvar_pd, >> > - int_x86_avx_vpermil_pd>; >> > + memopv2i64, >> int_x86_avx_vpermilvar_pd, >> v2f64>; >> > defm VPERMILPDY : avx_permil<0x0D, 0x05, "vpermilpd", VR256, >> f256mem, >> i256mem, >> > - memopv4f64, memopv4i64, >> > - int_x86_avx_vpermilvar_pd_256, >> > - int_x86_avx_vpermil_pd_256>; >> > + memopv4i64, >> int_x86_avx_vpermilvar_pd_256, >> v4f64>; >> > } >> > >> > let Predicates = [HasAVX] in { >> > -def : Pat<(v8f32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > - (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPSYri VR256:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp VR256:$src1, (i8 imm:$imm))), >> > (VPERMILPDYri VR256:$src1, imm:$imm)>; >> > -def : Pat<(v8f32 (X86VPermilp (memopv8f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v4f64 (X86VPermilp (memopv4f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v8i32 (X86VPermilp (bc_v8i32 (memopv4i64 addr:$src1)), >> > (i8 imm:$imm))), >> > (VPERMILPSYmi addr:$src1, imm:$imm)>; >> > def : Pat<(v4i64 (X86VPermilp (memopv4i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDYmi addr:$src1, imm:$imm)>; >> > >> > -def : Pat<(v4f32 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPSri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > - (VPERMILPDri VR128:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp VR128:$src1, (i8 imm:$imm))), >> > (VPERMILPDri VR128:$src1, imm:$imm)>; >> > -def : Pat<(v4f32 (X86VPermilp (memopv4f32 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPSmi addr:$src1, imm:$imm)>; >> > -def : Pat<(v2f64 (X86VPermilp (memopv2f64 addr:$src1), (i8 >> imm:$imm))), >> > - (VPERMILPDmi addr:$src1, imm:$imm)>; >> > def : Pat<(v2i64 (X86VPermilp (memopv2i64 addr:$src1), (i8 >> imm:$imm))), >> > (VPERMILPDmi addr:$src1, imm:$imm)>; >> > } >> > >> > >> > ______________________________**_________________ >> > llvm-commits mailing list >> > llvm-commits at cs.uiuc.edu >> > >> >> > http://lists.cs.uiuc.edu/**mailman/listinfo/llvm-commits >> >> ______________________________**_________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> > >> http://lists.cs.uiuc.edu/**mailman/listinfo/llvm-commits >> >> >> >> >> -- >> ~Craig >> > > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/d247dc01/attachment.html From kcc at google.com Wed Feb 8 11:30:39 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 8 Feb 2012 09:30:39 -0800 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) In-Reply-To: <20cf306f77fedd845c04b875ae3b@google.com> References: <20cf306f77fedd845c04b875ae3b@google.com> Message-ID: Looks good! On Wed, Feb 8, 2012 at 7:38 AM, wrote: > kcc@: > 1) Moved auxiliary functions under __interception namespace. > 2) Why can't we for simplicity declare real_f inside __interception > namespace as well? ok > This may break if two different libraries using > interception are linked together, but it's a mess anyway, as they'll > have interceptors for the same functions. > 3) This CL is large already, so I'd prefer to resolve some FIXMEs after > this CL is submitted, if you don't mind. > ok > > glider@ suggested we should remove all OS-specific > details from the header "interception.h", so I moved them > to OS-specific headers. In this way the user code will not include > or mach_override.h > > > > http://codereview.appspot.com/**5642046/diff/1012/asan_**interceptors.h > File asan_interceptors.h (right): > > http://codereview.appspot.com/**5642046/diff/1012/asan_** > interceptors.h#newcode34 > asan_interceptors.h:34: size_t internal_strlen(const char *s); > On 2012/02/08 08:19:17, glider wrote: > >> BTW aren't these functions already declared in asan_internal.h? >> > > Not yet. > > http://codereview.appspot.com/**5642046/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/ce247591/attachment.html From stoklund at 2pi.dk Wed Feb 8 11:33:46 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 08 Feb 2012 17:33:46 -0000 Subject: [llvm-commits] [llvm] r150077 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120208173346.5E7682A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 11:33:45 2012 New Revision: 150077 URL: http://llvm.org/viewvc/llvm-project?rev=150077&view=rev Log: Keep track of register masks in LiveIntervalAnalysis. Build an ordered vector of register mask operands (i.e., calls) when computing live intervals. Provide a checkRegMaskInterference() function that computes a bit mask of usable registers for a live range. This is a quick way of determining of a live range crosses any calls, and restricting it to the callee saved registers if it does. Previously, we had to discover call clobbers for each candidate register independently. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=150077&r1=150076&r2=150077&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Wed Feb 8 11:33:45 2012 @@ -63,6 +63,25 @@ /// allocatableRegs_ - A bit vector of allocatable registers. BitVector allocatableRegs_; + /// RegMaskSlots - Sorted list of instructions with register mask operands. + /// Always use the 'r' slot, RegMasks are normal clobbers, not early + /// clobbers. + SmallVector RegMaskSlots; + + /// RegMaskBits - This vector is parallel to RegMaskSlots, it holds a + /// pointer to the corresponding register mask. This pointer can be + /// recomputed as: + /// + /// MI = Indexes->getInstructionFromIndex(RegMaskSlot[N]); + /// unsigned OpNum = findRegMaskOperand(MI); + /// RegMaskBits[N] = MI->getOperand(OpNum).getRegMask(); + /// + /// This is kept in a separate vector partly because some standard + /// libraries don't support lower_bound() with mixed objects, partly to + /// improve locality when searching in RegMaskSlots. + /// Also see the comment in LiveInterval::find(). + SmallVector RegMaskBits; + public: static char ID; // Pass identification, replacement for typeid LiveIntervals() : MachineFunctionPass(ID) { @@ -249,6 +268,30 @@ /// point can be above or below mi, but must be in the same basic block. void moveInstr(MachineBasicBlock::iterator insertPt, MachineInstr* mi); + // Register mask functions. + // + // Machine instructions may use a register mask operand to indicate that a + // large number of registers are clobbered by the instruction. This is + // typically used for calls. + // + // For compile time performance reasons, these clobbers are not recorded in + // the live intervals for individual physical registers. Instead, + // LiveIntervalAnalysis maintains a sorted list of instructions with + // register mask operands. + + /// getRegMaskSlots - Returns asorted array of slot indices of all + /// instructions with register mask operands. + ArrayRef getRegMaskSlots() const { return RegMaskSlots; } + + /// checkRegMaskInterference - Test if LI is live across any register mask + /// instructions, and compute a bit mask of physical registers that are not + /// clobbered by any of them. + /// + /// Returns false if LI doesn't cross any register mask instructions. In + /// that case, the bit vector is not filled in. + bool checkRegMaskInterference(LiveInterval &LI, + BitVector &UsableRegs); + private: /// computeIntervals - Compute live intervals. void computeIntervals(); Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150077&r1=150076&r2=150077&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Feb 8 11:33:45 2012 @@ -88,6 +88,8 @@ delete I->second; r2iMap_.clear(); + RegMaskSlots.clear(); + RegMaskBits.clear(); // Release VNInfo memory regions, VNInfo objects don't need to be dtor'd. VNInfoAllocator.Reset(); @@ -558,10 +560,20 @@ DEBUG(dbgs() << MIIndex << "\t" << *MI); if (MI->isDebugValue()) continue; + assert(indexes_->getInstructionFromIndex(MIIndex) == MI && + "Lost SlotIndex synchronization"); // Handle defs. for (int i = MI->getNumOperands() - 1; i >= 0; --i) { MachineOperand &MO = MI->getOperand(i); + + // Collect register masks. + if (MO.isRegMask()) { + RegMaskSlots.push_back(MIIndex.getRegSlot()); + RegMaskBits.push_back(MO.getRegMask()); + continue; + } + if (!MO.isReg() || !MO.getReg()) continue; @@ -1111,3 +1123,53 @@ return LR; } + + +//===----------------------------------------------------------------------===// +// Register mask functions +//===----------------------------------------------------------------------===// + +bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI, + BitVector &UsableRegs) { + if (LI.empty()) + return false; + + // We are going to enumerate all the register mask slots contained in LI. + // Start with a binary search of RegMaskSlots to find a starting point. + LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); + ArrayRef Slots = getRegMaskSlots(); + ArrayRef::iterator SlotI = + std::lower_bound(Slots.begin(), Slots.end(), LiveI->start); + ArrayRef::iterator SlotE = Slots.end(); + + // No slots in range, LI begins after the last call. + if (SlotI == SlotE) + return false; + + bool Found = false; + for (;;) { + assert(*SlotI >= LiveI->start); + // Loop over all slots overlapping this segment. + while (*SlotI < LiveI->end) { + // *SlotI overlaps LI. Collect mask bits. + if (!Found) { + // This is the first overlap. Initialize UsableRegs to all ones. + UsableRegs.clear(); + UsableRegs.resize(tri_->getNumRegs(), true); + Found = true; + } + // Remove usable registers clobbered by this mask. + UsableRegs.clearBitsNotInMask(RegMaskBits[SlotI-Slots.begin()]); + if (++SlotI == SlotE) + return Found; + } + // *SlotI is beyond the current LI segment. + LiveI = LI.advanceTo(LiveI, *SlotI); + if (LiveI == LiveE) + return Found; + // Advance SlotI until it overlaps. + while (*SlotI < LiveI->start) + if (++SlotI == SlotE) + return Found; + } +} From dag at cray.com Wed Feb 8 11:51:54 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 11:51:54 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F32AAF0.6090601@free.fr> (Duncan Sands's message of "Wed, 08 Feb 2012 18:03:44 +0100") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> Message-ID: Duncan Sands writes: >>> then I guess you will have to use inline asm. >> >> We can't use inline asm. Our compiler does not support it. > > your front-end can expand the builtin into the corresponding LLVM inline > asm expression when generating the IR. So now our frontend has to be a code generator? And understand all possible targets, asm formats, etc.? That's ridiculous. What is so difficult about keeping intrinsics around? Are they causing some major issue? -Dave From konstantin.s.serebryany at gmail.com Wed Feb 8 12:03:10 2012 From: konstantin.s.serebryany at gmail.com (konstantin.s.serebryany at gmail.com) Date: Wed, 08 Feb 2012 18:03:10 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf300faf255d849404b877b52c@google.com> http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc File lib/asan/asan_allocator.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc#newcode692 lib/asan/asan_allocator.cc:692: #if defined(_WIN32) instead of the ifdef clatter, I'd prefer to have if (WINDOWS) http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode32 lib/asan/asan_interceptors.cc:32: # include // FIXME: remove when we start intercepting on Windows. Why do you need this now? http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode626 lib/asan/asan_interceptors.cc:626: #ifdef _WIN32 if (WINDOWS) please or "if (ASAN_WINDOWS)" also, feel free to change the code below to if (ASAN_APPLE) http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode37 lib/asan/asan_win.cc:37: // FIXME: what is mem_type? memtype is a string used for reporting mmap errors http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode98 lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); OMG. Ok for now, but in the long run this is not going to work. We will need our own unwinder. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode167 lib/asan/asan_win.cc:167: AsanLock::AsanLock(LinkerInitialized li) { This is in fact *not* linker-initialized. Is there a way to create a linker-initialized lock on windows? http://codereview.appspot.com/5647052/ From bob.wilson at apple.com Wed Feb 8 12:11:30 2012 From: bob.wilson at apple.com (Bob Wilson) Date: Wed, 08 Feb 2012 10:11:30 -0800 Subject: [llvm-commits] [llvm] r149851 - /llvm/trunk/include/llvm/ADT/SmallVector.h In-Reply-To: <20120205224831.E09B12A6C12C@llvm.org> References: <20120205224831.E09B12A6C12C@llvm.org> Message-ID: On Feb 5, 2012, at 2:48 PM, Benjamin Kramer wrote: > Author: d0k > Date: Sun Feb 5 16:48:31 2012 > New Revision: 149851 > > URL: http://llvm.org/viewvc/llvm-project?rev=149851&view=rev > Log: > SmallVector's construct_range is the same thing as std::uninitialized_fill, no need to reinvent it. > > Modified: > llvm/trunk/include/llvm/ADT/SmallVector.h We're seeing a very small but repeatable compile regression from this change. For example, compiling MultiSource/Benchmarks/MiBench/consumer-typeset we measured an increase from 2.766 to 2.785 seconds (user time). The std deviation on those times is high so it may be a little bit hard to see the change. Daniel did some quick investigation and it seemed like there was a difference in loop unrolling between the two versions. He looked at a simple function like: #include "llvm/ADT/SmallVector.h" using namespace llvm; void f0(SmallVector a) { a.assign(20, 0); } When compiled with the old version (using construct_range), the IR does not get unrolled. When compiled with std::uninitialized_fill then the IR does get unrolled. Any chance you'd be up for investigating that? If not, how would you feel about temporarily reverting the patch until someone has a chance to fix up the optimizer to handle this better? > > Modified: llvm/trunk/include/llvm/ADT/SmallVector.h > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallVector.h?rev=149851&r1=149850&r2=149851&view=diff > ============================================================================== > --- llvm/trunk/include/llvm/ADT/SmallVector.h (original) > +++ llvm/trunk/include/llvm/ADT/SmallVector.h Sun Feb 5 16:48:31 2012 > @@ -299,7 +299,7 @@ > } else if (N > this->size()) { > if (this->capacity() < N) > this->grow(N); > - this->construct_range(this->end(), this->begin()+N, T()); > + std::uninitialized_fill(this->end(), this->begin()+N, T()); > this->setEnd(this->begin()+N); > } > } > @@ -311,7 +311,7 @@ > } else if (N > this->size()) { > if (this->capacity() < N) > this->grow(N); > - construct_range(this->end(), this->begin()+N, NV); > + std::uninitialized_fill(this->end(), this->begin()+N, NV); > this->setEnd(this->begin()+N); > } > } > @@ -378,7 +378,7 @@ > if (this->capacity() < NumElts) > this->grow(NumElts); > this->setEnd(this->begin()+NumElts); > - construct_range(this->begin(), this->end(), Elt); > + std::uninitialized_fill(this->begin(), this->end(), Elt); > } > > iterator erase(iterator I) { > @@ -556,12 +556,6 @@ > assert(N <= this->capacity()); > this->setEnd(this->begin() + N); > } > - > -private: > - static void construct_range(T *S, T *E, const T &Elt) { > - for (; S != E; ++S) > - new (S) T(Elt); > - } > }; > > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From resistor at mac.com Wed Feb 8 12:16:21 2012 From: resistor at mac.com (Owen Anderson) Date: Wed, 08 Feb 2012 10:16:21 -0800 Subject: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE In-Reply-To: <000001cce63c$8289ffd0$879dff70$%molloy@arm.com> References: <000c01cce4bc$173fe630$45bfb290$%molloy@arm.com> <9F39D766-682D-4279-8D04-814291A11FBA@mac.com> <000001cce63c$8289ffd0$879dff70$%molloy@arm.com> Message-ID: Go ahead with it. --Owen On Feb 8, 2012, at 12:34 AM, James Molloy wrote: > Hi Owen, > > Do you have any other comments about this patch or is it OK to commit? > > Cheers, > > James > > -----Original Message----- > From: llvm-commits-bounces at cs.uiuc.edu > [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of James Molloy > Sent: 06 February 2012 19:15 > To: Owen Anderson > Cc: llvm-commits at cs.uiuc.edu > Subject: Re: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE > > Hi Owen, > > For the generated disassembler it only adds two lines of code and only on > instructions that require it. The difference in size before and after this > patch is +2 lines, because it is only hooked up to tBX. > > There is no noticeable build time difference. > > Cheers, > > James > ________________________________________ > From: Owen Anderson [resistor at mac.com] > Sent: 06 February 2012 18:19 > To: James Molloy > Cc: llvm-commits at cs.uiuc.edu > Subject: Re: [llvm-commits] [PATCH] Teach the MC about UNPREDICTABLE > > James, > > I like the concept of this feature, and it'd be nice if it could help use > eliminate more of the hand-written decoding hooks. However, I'm concerned > about the impact it will have on LLVM's build time. Have you looked at how > much bigger this makes the generated disassembler file? It already takes a > very long time to compile, and I'm wage to avoid making it any worse. > > --Owen > > On Feb 6, 2012, at 2:42 AM, James Molloy wrote: > > Hi, > > ARM has the concept of an "unpredictable" instruction - one which is valid > (and will be executed) but whose results are not defined. An example of an > unpredictable instruction is a load with address increment and writeback > where the writeback register is the same as the load destination. > > The MC disassembler has the concept of a "soft failure" which maps well to > unpredictability (coincidentally because it was added for that purpose). > However this soft failure can currently only be triggered by manual C++ code > such as that in ARMDisassembler.cpp - it cannot be triggered from > tablegen-generated code. > > The attached patch adds this functionality. It adds the ability for the > FixedLenDecoderEmitter to take into account a bitfield in a tablegen record > called "SoftFail" that mirrors the "Inst" field. > > If a bitpattern BP matches the Inst field of an instruction record but > differs from Inst in any bits which are set to '1' in the SoftFail field, > then that instruction is matched by the disassembler but the status SoftFail > is returned instead of Success. > > For example, this is a modified Thumb BX instruction with unpredictability > modelled as per the ARMARM: > > def tBX : TI<(outs), (ins GPR:$Rm, pred:$p), IIC_Br, "bx${p}\t$Rm", []>, > T1Special<{1,1,0,?}> { > // A6.2.3 & A8.6.25 > bits<4> Rm; > let Inst{6-3} = Rm; > let Inst{2-0} = 0b000; > // Any of the bottom 3 bits set is unpredictable. > let SoftFail{2-0} = 0b111; > } > > And this is the generated disassembler code (new code bolded): > > if ((Bits & ARM::ModeThumb)) { > if (insn & 0x7) > S = MCDisassembler::SoftFail; > MI.setOpcode(2662); > tmp = fieldFromInstruction16(insn, 3, 4); > if (!Check(S, DecodeGPRRegisterClass(MI, tmp, Address, Decoder))) return > MCDisassembler::Fail; > return S; // tBXT > } > > This results in the MC now correctly identifying such an instruction: > > $ echo '0x01 0x47' | ./bin/llvm-mc -triple thumbv7 -disassemble > :1:1: warning: potentially undefined instruction encoding > 0x01 0x47 > ^ > bx r0 > > The patch works by removing any bits that could SoftFail from the set of > possible disassembly island values, and emitting an extra test if required > in the generated disassembler. If no SoftFail bits are set, no extra code > will be emitted. > > In the ARM tablegen files, this patch aliases SoftFail to "Unpredictable" so > it is more recognisable what it is doing in the ARM world. > > Please review! It wires the new functionality up to "tBX" as a proof of > concept and testing codepath, and adds a regression test. > > Cheers, > > James > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > -- IMPORTANT NOTICE: The contents of this email and any attachments are > confidential and may also be privileged. If you are not the intended > recipient, please notify the sender immediately and do not disclose the > contents to any other person, use it for any purpose, or store or copy the > information in any medium. Thank you. > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > > > > From Aaron.Ballman at gmail.com Wed Feb 8 12:19:20 2012 From: Aaron.Ballman at gmail.com (Aaron.Ballman at gmail.com) Date: Wed, 08 Feb 2012 18:19:20 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf301af8ff36140304b877ef43@google.com> Added previous comments as well as one new one about DbgHelp being thread unsafe. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode88 lib/asan/asan_win.cc:88: CHECK(VirtualQuery(&mbi /* on stack */, The stack will always be a single block, but I think what you're getting there is including the stack's guard page. Are you sure you want that? Also, I think that's only getting you the reserved size and not the committed size. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode98 lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); On 2012/02/08 18:03:10, kcc wrote: > OMG. Ok for now, but in the long run this is not going to work. > We will need our own unwinder. Even with our own unwinder, the symbolicator is single-threaded only on Windows. So we'll need some form of locking in WinSymbolize. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode103 lib/asan/asan_win.cc:103: size_t cs_ret = CaptureStackBackTrace(1, max_size, tmp, NULL), Since you're already using DbgHelp APIs, would StackWalk64 make a bit more sense? IIRC, it's a bit more accurate than CaptureStackBackTrace. Certainly it gives you more control. You may want to look at LLVMUnhandledExceptionFilter in Signals.inc because a lot of the stack walking fun is already done there. Perhaps we could refactor it to use common code? http://codereview.appspot.com/5647052/ From bcahoon at codeaurora.org Wed Feb 8 12:25:48 2012 From: bcahoon at codeaurora.org (Brendon Cahoon) Date: Wed, 08 Feb 2012 18:25:48 -0000 Subject: [llvm-commits] [llvm] r150078 - in /llvm/trunk/lib/Target/Hexagon: HexagonInstrFormats.td HexagonInstrInfo.cpp HexagonInstrInfo.h HexagonInstrInfo.td HexagonInstrInfoV4.td MCTargetDesc/HexagonBaseInfo.h Message-ID: <20120208182548.4DD142A6C12C@llvm.org> Author: bcahoon Date: Wed Feb 8 12:25:47 2012 New Revision: 150078 URL: http://llvm.org/viewvc/llvm-project?rev=150078&view=rev Log: Use TSFlag bit to describe instruction properties. Creating the isPredicated TSFlag enables the code to use the property defined in the instruction format instead of using a large switch statement. Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td?rev=150078&r1=150077&r2=150078&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrFormats.td Wed Feb 8 12:25:47 2012 @@ -7,23 +7,37 @@ // //===----------------------------------------------------------------------===// +//----------------------------------------------------------------------------// +// Hexagon Intruction Flags + +// +// *** Must match HexagonBaseInfo.h *** +//----------------------------------------------------------------------------// + + +//----------------------------------------------------------------------------// +// Intruction Class Declaration + +//----------------------------------------------------------------------------// + class InstHexagon pattern, - string cstr, - InstrItinClass itin> : Instruction { + string cstr, InstrItinClass itin> : Instruction { field bits<32> Inst; let Namespace = "Hexagon"; -/* Commented out for Hexagon - bits<2> op; - let Inst{31-30} = op; */ // Top two bits are the 'op' field - dag OutOperandList = outs; dag InOperandList = ins; let AsmString = asmstr; let Pattern = pattern; let Constraints = cstr; let Itinerary = itin; + + // *** The code below must match HexagonBaseInfo.h *** + + // Predicated instructions. + bits<1> isPredicated = 0; + let TSFlags{1} = isPredicated; + + // *** The code above must match HexagonBaseInfo.h *** } //----------------------------------------------------------------------------// Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp?rev=150078&r1=150077&r2=150078&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.cpp Wed Feb 8 12:25:47 2012 @@ -861,213 +861,9 @@ bool HexagonInstrInfo::isPredicated(const MachineInstr *MI) const { - switch (MI->getOpcode()) { - case Hexagon::TFR_cPt: - case Hexagon::TFR_cNotPt: - case Hexagon::TFRI_cPt: - case Hexagon::TFRI_cNotPt: - case Hexagon::TFR_cdnPt: - case Hexagon::TFR_cdnNotPt: - case Hexagon::TFRI_cdnPt: - case Hexagon::TFRI_cdnNotPt: - return true; - - case Hexagon::JMP_Pred: - case Hexagon::JMP_PredNot: - case Hexagon::BRCOND: - case Hexagon::JMP_PredPt: - case Hexagon::JMP_PredNotPt: - case Hexagon::JMP_PredPnt: - case Hexagon::JMP_PredNotPnt: - return true; - - case Hexagon::LDrid_indexed_cPt_V4 : - case Hexagon::LDrid_indexed_cdnPt_V4 : - case Hexagon::LDrid_indexed_cNotPt_V4 : - case Hexagon::LDrid_indexed_cdnNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnPt_V4 : - case Hexagon::LDrid_indexed_shl_cNotPt_V4 : - case Hexagon::LDrid_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_cPt_V4 : - case Hexagon::LDrib_indexed_cdnPt_V4 : - case Hexagon::LDrib_indexed_cNotPt_V4 : - case Hexagon::LDrib_indexed_cdnNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnPt_V4 : - case Hexagon::LDrib_indexed_shl_cNotPt_V4 : - case Hexagon::LDrib_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_cPt_V4 : - case Hexagon::LDriub_indexed_cdnPt_V4 : - case Hexagon::LDriub_indexed_cNotPt_V4 : - case Hexagon::LDriub_indexed_cdnNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnPt_V4 : - case Hexagon::LDriub_indexed_shl_cNotPt_V4 : - case Hexagon::LDriub_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_cPt_V4 : - case Hexagon::LDrih_indexed_cdnPt_V4 : - case Hexagon::LDrih_indexed_cNotPt_V4 : - case Hexagon::LDrih_indexed_cdnNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnPt_V4 : - case Hexagon::LDrih_indexed_shl_cNotPt_V4 : - case Hexagon::LDrih_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_cPt_V4 : - case Hexagon::LDriuh_indexed_cdnPt_V4 : - case Hexagon::LDriuh_indexed_cNotPt_V4 : - case Hexagon::LDriuh_indexed_cdnNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnPt_V4 : - case Hexagon::LDriuh_indexed_shl_cNotPt_V4 : - case Hexagon::LDriuh_indexed_shl_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_cPt_V4 : - case Hexagon::LDriw_indexed_cdnPt_V4 : - case Hexagon::LDriw_indexed_cNotPt_V4 : - case Hexagon::LDriw_indexed_cdnNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnPt_V4 : - case Hexagon::LDriw_indexed_shl_cNotPt_V4 : - case Hexagon::LDriw_indexed_shl_cdnNotPt_V4 : - return true; - - case Hexagon::LDrid_cPt : - case Hexagon::LDrid_cNotPt : - case Hexagon::LDrid_indexed_cPt : - case Hexagon::LDrid_indexed_cNotPt : - case Hexagon::POST_LDrid_cPt : - case Hexagon::POST_LDrid_cNotPt : - case Hexagon::LDriw_cPt : - case Hexagon::LDriw_cNotPt : - case Hexagon::LDriw_indexed_cPt : - case Hexagon::LDriw_indexed_cNotPt : - case Hexagon::POST_LDriw_cPt : - case Hexagon::POST_LDriw_cNotPt : - case Hexagon::LDrih_cPt : - case Hexagon::LDrih_cNotPt : - case Hexagon::LDrih_indexed_cPt : - case Hexagon::LDrih_indexed_cNotPt : - case Hexagon::POST_LDrih_cPt : - case Hexagon::POST_LDrih_cNotPt : - case Hexagon::LDrib_cPt : - case Hexagon::LDrib_cNotPt : - case Hexagon::LDrib_indexed_cPt : - case Hexagon::LDrib_indexed_cNotPt : - case Hexagon::POST_LDrib_cPt : - case Hexagon::POST_LDrib_cNotPt : - case Hexagon::LDriuh_cPt : - case Hexagon::LDriuh_cNotPt : - case Hexagon::LDriuh_indexed_cPt : - case Hexagon::LDriuh_indexed_cNotPt : - case Hexagon::POST_LDriuh_cPt : - case Hexagon::POST_LDriuh_cNotPt : - case Hexagon::LDriub_cPt : - case Hexagon::LDriub_cNotPt : - case Hexagon::LDriub_indexed_cPt : - case Hexagon::LDriub_indexed_cNotPt : - case Hexagon::POST_LDriub_cPt : - case Hexagon::POST_LDriub_cNotPt : - return true; - - case Hexagon::LDrid_cdnPt : - case Hexagon::LDrid_cdnNotPt : - case Hexagon::LDrid_indexed_cdnPt : - case Hexagon::LDrid_indexed_cdnNotPt : - case Hexagon::POST_LDrid_cdnPt_V4 : - case Hexagon::POST_LDrid_cdnNotPt_V4 : - case Hexagon::LDriw_cdnPt : - case Hexagon::LDriw_cdnNotPt : - case Hexagon::LDriw_indexed_cdnPt : - case Hexagon::LDriw_indexed_cdnNotPt : - case Hexagon::POST_LDriw_cdnPt_V4 : - case Hexagon::POST_LDriw_cdnNotPt_V4 : - case Hexagon::LDrih_cdnPt : - case Hexagon::LDrih_cdnNotPt : - case Hexagon::LDrih_indexed_cdnPt : - case Hexagon::LDrih_indexed_cdnNotPt : - case Hexagon::POST_LDrih_cdnPt_V4 : - case Hexagon::POST_LDrih_cdnNotPt_V4 : - case Hexagon::LDrib_cdnPt : - case Hexagon::LDrib_cdnNotPt : - case Hexagon::LDrib_indexed_cdnPt : - case Hexagon::LDrib_indexed_cdnNotPt : - case Hexagon::POST_LDrib_cdnPt_V4 : - case Hexagon::POST_LDrib_cdnNotPt_V4 : - case Hexagon::LDriuh_cdnPt : - case Hexagon::LDriuh_cdnNotPt : - case Hexagon::LDriuh_indexed_cdnPt : - case Hexagon::LDriuh_indexed_cdnNotPt : - case Hexagon::POST_LDriuh_cdnPt_V4 : - case Hexagon::POST_LDriuh_cdnNotPt_V4 : - case Hexagon::LDriub_cdnPt : - case Hexagon::LDriub_cdnNotPt : - case Hexagon::LDriub_indexed_cdnPt : - case Hexagon::LDriub_indexed_cdnNotPt : - case Hexagon::POST_LDriub_cdnPt_V4 : - case Hexagon::POST_LDriub_cdnNotPt_V4 : - return true; - - case Hexagon::ADD_ri_cPt: - case Hexagon::ADD_ri_cNotPt: - case Hexagon::ADD_ri_cdnPt: - case Hexagon::ADD_ri_cdnNotPt: - case Hexagon::ADD_rr_cPt: - case Hexagon::ADD_rr_cNotPt: - case Hexagon::ADD_rr_cdnPt: - case Hexagon::ADD_rr_cdnNotPt: - case Hexagon::XOR_rr_cPt: - case Hexagon::XOR_rr_cNotPt: - case Hexagon::XOR_rr_cdnPt: - case Hexagon::XOR_rr_cdnNotPt: - case Hexagon::AND_rr_cPt: - case Hexagon::AND_rr_cNotPt: - case Hexagon::AND_rr_cdnPt: - case Hexagon::AND_rr_cdnNotPt: - case Hexagon::OR_rr_cPt: - case Hexagon::OR_rr_cNotPt: - case Hexagon::OR_rr_cdnPt: - case Hexagon::OR_rr_cdnNotPt: - case Hexagon::SUB_rr_cPt: - case Hexagon::SUB_rr_cNotPt: - case Hexagon::SUB_rr_cdnPt: - case Hexagon::SUB_rr_cdnNotPt: - case Hexagon::COMBINE_rr_cPt: - case Hexagon::COMBINE_rr_cNotPt: - case Hexagon::COMBINE_rr_cdnPt: - case Hexagon::COMBINE_rr_cdnNotPt: - return true; - - case Hexagon::ASLH_cPt_V4: - case Hexagon::ASLH_cNotPt_V4: - case Hexagon::ASRH_cPt_V4: - case Hexagon::ASRH_cNotPt_V4: - case Hexagon::SXTB_cPt_V4: - case Hexagon::SXTB_cNotPt_V4: - case Hexagon::SXTH_cPt_V4: - case Hexagon::SXTH_cNotPt_V4: - case Hexagon::ZXTB_cPt_V4: - case Hexagon::ZXTB_cNotPt_V4: - case Hexagon::ZXTH_cPt_V4: - case Hexagon::ZXTH_cNotPt_V4: - return true; + const uint64_t F = MI->getDesc().TSFlags; - case Hexagon::ASLH_cdnPt_V4: - case Hexagon::ASLH_cdnNotPt_V4: - case Hexagon::ASRH_cdnPt_V4: - case Hexagon::ASRH_cdnNotPt_V4: - case Hexagon::SXTB_cdnPt_V4: - case Hexagon::SXTB_cdnNotPt_V4: - case Hexagon::SXTH_cdnPt_V4: - case Hexagon::SXTH_cdnNotPt_V4: - case Hexagon::ZXTB_cdnPt_V4: - case Hexagon::ZXTB_cdnNotPt_V4: - case Hexagon::ZXTH_cdnPt_V4: - case Hexagon::ZXTH_cdnNotPt_V4: - return true; - - default: - return false; - } + return ((F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask); } Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h?rev=150078&r1=150077&r2=150078&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.h Wed Feb 8 12:25:47 2012 @@ -14,6 +14,7 @@ #ifndef HexagonINSTRUCTIONINFO_H #define HexagonINSTRUCTIONINFO_H +#include "MCTargetDesc/HexagonBaseInfo.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetFrameLowering.h" #include "HexagonRegisterInfo.h" Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td?rev=150078&r1=150077&r2=150078&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfo.td Wed Feb 8 12:25:47 2012 @@ -319,49 +319,49 @@ //===----------------------------------------------------------------------===// // Conditional add. -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), "if ($src1) $dst = add($src2, #$src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), "if (!$src1) $dst = add($src2, #$src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cdnPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), "if ($src1.new) $dst = add($src2, #$src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_ri_cdnNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, s16Imm:$src3), "if (!$src1.new) $dst = add($src2, #$src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_rr_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = add($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = add($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = add($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ADD_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = add($src2, $src3)", @@ -370,25 +370,25 @@ // Conditional combine. -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def COMBINE_rr_cPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = combine($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def COMBINE_rr_cNotPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = combine($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def COMBINE_rr_cdnPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = combine($src2, $src3)", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = combine($src2, $src3)", @@ -396,61 +396,73 @@ // Conditional logical operations. +let isPredicated = 1 in def XOR_rr_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = xor($src2, $src3)", []>; +let isPredicated = 1 in def XOR_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = xor($src2, $src3)", []>; +let isPredicated = 1 in def XOR_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = xor($src2, $src3)", []>; +let isPredicated = 1 in def XOR_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = xor($src2, $src3)", []>; +let isPredicated = 1 in def AND_rr_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = and($src2, $src3)", []>; +let isPredicated = 1 in def AND_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = and($src2, $src3)", []>; +let isPredicated = 1 in def AND_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = and($src2, $src3)", []>; +let isPredicated = 1 in def AND_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = and($src2, $src3)", []>; +let isPredicated = 1 in def OR_rr_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = or($src2, $src3)", []>; +let isPredicated = 1 in def OR_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = or($src2, $src3)", []>; +let isPredicated = 1 in def OR_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = or($src2, $src3)", []>; +let isPredicated = 1 in def OR_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = or($src2, $src3)", @@ -459,21 +471,25 @@ // Conditional subtract. +let isPredicated = 1 in def SUB_rr_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst = sub($src2, $src3)", []>; +let isPredicated = 1 in def SUB_rr_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst = sub($src2, $src3)", []>; +let isPredicated = 1 in def SUB_rr_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst = sub($src2, $src3)", []>; +let isPredicated = 1 in def SUB_rr_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst = sub($src2, $src3)", @@ -482,47 +498,47 @@ // Conditional transfer. -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFR_cPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = $src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFR_cNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = $src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFRI_cPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2), "if ($src1) $dst = #$src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFRI_cNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2), "if (!$src1) $dst = #$src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFR_cdnPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = $src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFR_cdnNotPt : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = $src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFRI_cdnPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2), "if ($src1.new) $dst = #$src2", []>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def TFRI_cdnNotPt : ALU32_ri<(outs IntRegs:$dst), (ins PredRegs:$src1, s12Imm:$src2), "if (!$src1.new) $dst = #$src2", @@ -743,7 +759,8 @@ } // if (p0) jump -let isBranch = 1, isTerminator=1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, Defs = [PC], + isPredicated = 1 in { def JMP_Pred : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src) jump $offset", @@ -751,14 +768,16 @@ } // if (!p0) jump -let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def JMP_PredNot : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src) jump $offset", []>; } -let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC] in { +let isTerminator = 1, isBranch = 1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def BRCOND : JInst < (outs), (ins PredRegs:$pred, brtarget:$dst), "if ($pred) jump $dst", []>; @@ -766,7 +785,8 @@ // Jump to address conditioned on new predicate. // if (p0) jump:t -let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def JMP_PredPt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src.new) jump:t $offset", @@ -774,7 +794,8 @@ } // if (!p0) jump:t -let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def JMP_PredNotPt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src.new) jump:t $offset", @@ -782,7 +803,8 @@ } // Not taken. -let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def JMP_PredPnt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if ($src.new) jump:nt $offset", @@ -790,7 +812,8 @@ } // Not taken. -let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC] in { +let isBranch = 1, isTerminator=1, neverHasSideEffects = 1, Defs = [PC], + isPredicated = 1 in { def JMP_PredNotPnt : JInst< (outs), (ins PredRegs:$src, brtarget:$offset), "if (!$src.new) jump:nt $offset", @@ -1779,7 +1802,8 @@ "$src3 = $dst">; // if (!Pv) memd(Rx++#s4:3)=Rtt -let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1 in +let AddedComplexity = 10, mayStore = 1, neverHasSideEffects = 1, + isPredicated = 1 in def POST_STdri_cNotPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, DoubleRegs:$src2, IntRegs:$src3, s4_3Imm:$offset), @@ -1859,14 +1883,14 @@ // if ([!]Pv) memb(Rx++#s4:0)=Rt // if (Pv) memb(Rx++#s4:0)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_STbri_cPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if ($src1) memb($src3++#$offset) = $src2", [],"$src3 = $dst">; // if (!Pv) memb(Rx++#s4:0)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_STbri_cNotPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_0Imm:$offset), "if (!$src1) memb($src3++#$offset) = $src2", @@ -1944,14 +1968,14 @@ // if ([!]Pv) memh(Rx++#s4:1)=Rt // if (Pv) memh(Rx++#s4:1)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_SThri_cPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if ($src1) memh($src3++#$offset) = $src2", [],"$src3 = $dst">; // if (!Pv) memh(Rx++#s4:1)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_SThri_cNotPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_1Imm:$offset), "if (!$src1) memh($src3++#$offset) = $src2", @@ -2030,14 +2054,14 @@ // if ([!]Pv) memw(Rx++#s4:2)=Rt // if (Pv) memw(Rx++#s4:2)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_STwri_cPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if ($src1) memw($src3++#$offset) = $src2", [],"$src3 = $dst">; // if (!Pv) memw(Rx++#s4:2)=Rt -let mayStore = 1, hasCtrlDep = 1 in +let mayStore = 1, hasCtrlDep = 1, isPredicated = 1 in def POST_STwri_cNotPt : STInstPI<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, s4_2Imm:$offset), "if (!$src1) memw($src3++#$offset) = $src2", Modified: llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td?rev=150078&r1=150077&r2=150078&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonInstrInfoV4.td Wed Feb 8 12:25:47 2012 @@ -77,48 +77,56 @@ // Shift halfword. +let isPredicated = 1 in def ASLH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = aslh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASLH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = aslh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASLH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = aslh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASLH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = aslh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASRH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = asrh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASRH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = asrh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASRH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = asrh($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def ASRH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = asrh($src2)", @@ -127,24 +135,28 @@ // Sign extend. +let isPredicated = 1 in def SXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = sxtb($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = sxtb($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = sxtb($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = sxtb($src2)", @@ -152,24 +164,28 @@ Requires<[HasV4T]>; +let isPredicated = 1 in def SXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = sxth($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = sxth($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = sxth($src2)", []>, Requires<[HasV4T]>; +let isPredicated = 1 in def SXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = sxth($src2)", @@ -178,56 +194,56 @@ // Zero exten. -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTB_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = zxtb($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTB_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = zxtb($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTB_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = zxtb($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTB_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = zxtb($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTH_cPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1) $dst = zxth($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTH_cNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1) $dst = zxth($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTH_cdnPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if ($src1.new) $dst = zxth($src2)", []>, Requires<[HasV4T]>; -let neverHasSideEffects = 1 in +let neverHasSideEffects = 1, isPredicated = 1 in def ZXTH_cdnNotPt_V4 : ALU32_rr<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2), "if (!$src1.new) $dst = zxth($src2)", @@ -276,7 +292,7 @@ //// Load doubleword conditionally. // if ([!]Pv[.new]) Rd=memd(Rs+Rt<<#u2) // if (Pv) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrid_indexed_cPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memd($src2+$src3<<#0)", @@ -284,7 +300,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrid_indexed_cdnPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memd($src2+$src3<<#0)", @@ -292,7 +308,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrid_indexed_cNotPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memd($src2+$src3<<#0)", @@ -300,7 +316,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrid_indexed_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memd($src2+$src3<<#0)", @@ -308,7 +324,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrid_indexed_shl_cPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -317,7 +333,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrid_indexed_shl_cdnPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -326,7 +342,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrid_indexed_shl_cNotPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -335,7 +351,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memd(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrid_indexed_shl_cdnNotPt_V4 : LDInst<(outs DoubleRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -405,7 +421,7 @@ //// Load byte conditionally. // if ([!]Pv[.new]) Rd=memb(Rs+Rt<<#u2) // if (Pv) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrib_indexed_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memb($src2+$src3<<#0)", @@ -413,7 +429,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrib_indexed_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memb($src2+$src3<<#0)", @@ -421,7 +437,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrib_indexed_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memb($src2+$src3<<#0)", @@ -429,7 +445,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrib_indexed_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memb($src2+$src3<<#0)", @@ -437,7 +453,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrib_indexed_shl_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -446,7 +462,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrib_indexed_shl_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -455,7 +471,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrib_indexed_shl_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -464,7 +480,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memb(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrib_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -475,7 +491,7 @@ //// Load unsigned byte conditionally. // if ([!]Pv[.new]) Rd=memub(Rs+Rt<<#u2) // if (Pv) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriub_indexed_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memub($src2+$src3<<#0)", @@ -483,7 +499,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriub_indexed_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memub($src2+$src3<<#0)", @@ -491,7 +507,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriub_indexed_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memub($src2+$src3<<#0)", @@ -499,7 +515,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriub_indexed_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memub($src2+$src3<<#0)", @@ -507,7 +523,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriub_indexed_shl_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -516,7 +532,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriub_indexed_shl_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -525,7 +541,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriub_indexed_shl_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -534,7 +550,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memub(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriub_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -606,7 +622,7 @@ //// Load halfword conditionally. // if ([!]Pv[.new]) Rd=memh(Rs+Rt<<#u2) // if (Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrih_indexed_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memh($src2+$src3<<#0)", @@ -614,7 +630,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrih_indexed_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memh($src2+$src3<<#0)", @@ -622,7 +638,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrih_indexed_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memh($src2+$src3<<#0)", @@ -630,7 +646,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDrih_indexed_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memh($src2+$src3<<#0)", @@ -638,7 +654,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrih_indexed_shl_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -647,7 +663,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrih_indexed_shl_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -656,7 +672,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrih_indexed_shl_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -665,7 +681,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDrih_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -676,7 +692,7 @@ //// Load unsigned halfword conditionally. // if ([!]Pv[.new]) Rd=memuh(Rs+Rt<<#u2) // if (Pv) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriuh_indexed_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memuh($src2+$src3<<#0)", @@ -684,7 +700,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriuh_indexed_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memuh($src2+$src3<<#0)", @@ -692,7 +708,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriuh_indexed_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memuh($src2+$src3<<#0)", @@ -700,7 +716,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriuh_indexed_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memuh($src2+$src3<<#0)", @@ -708,7 +724,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriuh_indexed_shl_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -717,7 +733,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriuh_indexed_shl_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -726,7 +742,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriuh_indexed_shl_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -735,7 +751,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memuh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriuh_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -770,7 +786,7 @@ //// Load word conditionally. // if ([!]Pv[.new]) Rd=memw(Rs+Rt<<#u2) // if (Pv) Rd=memw(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriw_indexed_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1) $dst=memw($src2+$src3<<#0)", @@ -778,7 +794,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriw_indexed_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if ($src1.new) $dst=memw($src2+$src3<<#0)", @@ -786,7 +802,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriw_indexed_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1) $dst=memw($src2+$src3<<#0)", @@ -794,7 +810,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 15 in +let mayLoad = 1, AddedComplexity = 15, isPredicated = 1 in def LDriw_indexed_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3), "if (!$src1.new) $dst=memw($src2+$src3<<#0)", @@ -802,7 +818,7 @@ Requires<[HasV4T]>; // if (Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriw_indexed_shl_cPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -811,7 +827,7 @@ Requires<[HasV4T]>; // if (Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriw_indexed_shl_cdnPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -820,7 +836,7 @@ Requires<[HasV4T]>; // if (!Pv) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriw_indexed_shl_cNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -829,7 +845,7 @@ Requires<[HasV4T]>; // if (!Pv.new) Rd=memh(Rs+Rt<<#u2) -let mayLoad = 1, AddedComplexity = 45 in +let mayLoad = 1, AddedComplexity = 45, isPredicated = 1 in def LDriw_indexed_shl_cdnNotPt_V4 : LDInst<(outs IntRegs:$dst), (ins PredRegs:$src1, IntRegs:$src2, IntRegs:$src3, u2Imm:$offset), @@ -843,7 +859,7 @@ // Post-inc Load, Predicated, Dot new -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrid_cdnPt_V4 : LDInstPI<(outs DoubleRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3), "if ($src1.new) $dst1 = memd($src2++#$src3)", @@ -851,7 +867,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrid_cdnNotPt_V4 : LDInstPI<(outs DoubleRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_3Imm:$src3), "if (!$src1.new) $dst1 = memd($src2++#$src3)", @@ -859,7 +875,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrib_cdnPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3), "if ($src1.new) $dst1 = memb($src2++#$src3)", @@ -867,7 +883,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrib_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3), "if (!$src1.new) $dst1 = memb($src2++#$src3)", @@ -875,7 +891,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrih_cdnPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3), "if ($src1.new) $dst1 = memh($src2++#$src3)", @@ -883,7 +899,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDrih_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3), "if (!$src1.new) $dst1 = memh($src2++#$src3)", @@ -891,7 +907,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriub_cdnPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3), "if ($src1.new) $dst1 = memub($src2++#$src3)", @@ -899,7 +915,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriub_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_0Imm:$src3), "if (!$src1.new) $dst1 = memub($src2++#$src3)", @@ -907,7 +923,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriuh_cdnPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3), "if ($src1.new) $dst1 = memuh($src2++#$src3)", @@ -915,7 +931,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriuh_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_1Imm:$src3), "if (!$src1.new) $dst1 = memuh($src2++#$src3)", @@ -923,7 +939,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriw_cdnPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3), "if ($src1.new) $dst1 = memw($src2++#$src3)", @@ -931,7 +947,7 @@ "$src2 = $dst2">, Requires<[HasV4T]>; -let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1 in +let mayLoad = 1, hasCtrlDep = 1, neverHasSideEffects = 1, isPredicated = 1 in def POST_LDriw_cdnNotPt_V4 : LDInstPI<(outs IntRegs:$dst1, IntRegs:$dst2), (ins PredRegs:$src1, IntRegs:$src2, s4_2Imm:$src3), "if (!$src1.new) $dst1 = memw($src2++#$src3)", Added: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h?rev=150078&view=auto ============================================================================== --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h (added) +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Wed Feb 8 12:25:47 2012 @@ -0,0 +1,43 @@ +//===-- HexagonBaseInfo.h - Top level definitions for Hexagon -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the Hexagon target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef HEXAGONBASEINFO_H +#define HEXAGONBASEINFO_H + +namespace llvm { + +/// HexagonII - This namespace holds all of the target specific flags that +/// instruction info tracks. +/// +namespace HexagonII { + + // *** The code below must match HexagonInstrFormat*.td *** + + // MCInstrDesc TSFlags + enum { + + // Predicated instructions. + PredicatedPos = 1, + PredicatedMask = 0x1 + }; + + // *** The code above must match HexagonInstrFormat*.td *** + +} // End namespace HexagonII. + +} // End namespace llvm. + +#endif From bcahoon at codeaurora.org Wed Feb 8 12:33:11 2012 From: bcahoon at codeaurora.org (Brendon Cahoon) Date: Wed, 8 Feb 2012 12:33:11 -0600 Subject: [llvm-commits] Use of TSFlag in Hexagon In-Reply-To: <4F305B9F.5040102@codeaurora.org> References: <4F305B9F.5040102@codeaurora.org> Message-ID: <024301cce690$1cbd2a20$56377e60$@org> Committed as r150078. -- Brendon -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum -----Original Message----- From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Sirish Pande Sent: Monday, February 06, 2012 5:01 PM To: llvm-commits at cs.uiuc.edu Subject: [llvm-commits] Use of TSFlag in Hexagon I have attached a patch that replaces a big switch-case statement with a bit in TSFlag. This is very specific to Hexagon, and it won't affect any other target. This patch essentially replaces the huge body of a function in HexagonInstrInfo.cpp with a use of the TSFlag. Sirish -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum From kcc at google.com Wed Feb 8 12:39:34 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 8 Feb 2012 10:39:34 -0800 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) In-Reply-To: <20cf301af8ff36140304b877ef43@google.com> References: <20cf301af8ff36140304b877ef43@google.com> Message-ID: On Wed, Feb 8, 2012 at 10:19 AM, wrote: > Added previous comments as well as one new one about DbgHelp being > thread unsafe. > > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/**asan_win.cc > File lib/asan/asan_win.cc (right): > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode88 > lib/asan/asan_win.cc:88: CHECK(VirtualQuery(&mbi /* on stack */, > > The stack will always be a single block, but I think what you're getting > there is including the stack's guard page. Are you sure you want that? > Also, I think that's only getting you the reserved size and not the > committed size. > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode98 > lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); > On 2012/02/08 18:03:10, kcc wrote: > >> OMG. Ok for now, but in the long run this is not going to work. >> We will need our own unwinder. >> > > Even with our own unwinder, the symbolicator is single-threaded only on > Windows. So we'll need some form of locking in WinSymbolize. > [replying using the kosher e-mail] I don't care about the performance of symbolicator too much -- it is invoked only once. But the performance of the unwinder is very important since it is invoked on every malloc/free. Even our super fast unwinder on linux is responsible for up-to 20% of asan run-time cost. --kcc > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode103 > lib/asan/asan_win.cc:103: size_t cs_ret = CaptureStackBackTrace(1, > max_size, tmp, NULL), > > Since you're already using DbgHelp APIs, would StackWalk64 make a bit > more sense? IIRC, it's a bit more accurate than > CaptureStackBackTrace. Certainly it gives you more control. > > You may want to look at LLVMUnhandledExceptionFilter in Signals.inc > because a lot of the stack walking fun is already done there. Perhaps > we could refactor it to use common code? > > http://codereview.appspot.com/**5647052/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/c22788b2/attachment.html From echristo at apple.com Wed Feb 8 12:43:08 2012 From: echristo at apple.com (Eric Christopher) Date: Wed, 08 Feb 2012 10:43:08 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: <91C216B9-0938-45CB-B077-10361711CADC@apple.com> On Feb 8, 2012, at 8:43 AM, David A. Greene wrote: > Duncan Sands writes: > >>> My experience with the C backend says otherwise. I've run across lots >>> of cases where shuffles could not be handled. >> >> then fix the C backend? > > Not possible with the current C backend. It uses illegal types, for > one. > It's going to be removed anyhow. >>> I don't know of any way to generate generic IR and guarantee that the >>> instruction the user selected through an intrinsic will be the >>> instruction selected by LLVM's isel. There are too many transformation >>> steps in-between. >> >> Of course there is no such guarantee. The question is whether doing things >> using generic IR is mostly a win or not. Maybe today it's often not a win, >> but since that's fixable it seems to me that the "use generic IR if not too >> crazy" path is on the whole the right way to go. > > Whether generic IR is a "win" isn't the primary issue here. The issue > is that the user wrote code using intrinsics and expects that exact code > to be in the asm. Whether or not that is the best performing code > possible doesn't matter. It's what they want and we have to respect it. > Our customers demand it. Then make the generic IR match what you think should happen. I see no win for anyone with this. -eric From konstantin.s.serebryany at gmail.com Wed Feb 8 12:37:46 2012 From: konstantin.s.serebryany at gmail.com (Konstantin Serebryany) Date: Wed, 8 Feb 2012 10:37:46 -0800 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) In-Reply-To: <20cf301af8ff36140304b877ef43@google.com> References: <20cf301af8ff36140304b877ef43@google.com> Message-ID: On Wed, Feb 8, 2012 at 10:19 AM, wrote: > Added previous comments as well as one new one about DbgHelp being > thread unsafe. > > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/**asan_win.cc > File lib/asan/asan_win.cc (right): > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode88 > lib/asan/asan_win.cc:88: CHECK(VirtualQuery(&mbi /* on stack */, > The stack will always be a single block, but I think what you're getting > there is including the stack's guard page. Are you sure you want that? > Also, I think that's only getting you the reserved size and not the > committed size. > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode98 > lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); > On 2012/02/08 18:03:10, kcc wrote: > >> OMG. Ok for now, but in the long run this is not going to work. >> We will need our own unwinder. >> > > Even with our own unwinder, the symbolicator is single-threaded only on > Windows. So we'll need some form of locking in WinSymbolize. > I don't care about the performance of symbolicator too much -- it is invoked only once. But the performance of the unwinder is very important since it is invoked on every malloc/free. Even our super fast unwinder on linux is responsible for up-to 20% of asan run-time cost. > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode103 > lib/asan/asan_win.cc:103: size_t cs_ret = CaptureStackBackTrace(1, > max_size, tmp, NULL), > Since you're already using DbgHelp APIs, would StackWalk64 make a bit > more sense? IIRC, it's a bit more accurate than > CaptureStackBackTrace. Certainly it gives you more control. > > You may want to look at LLVMUnhandledExceptionFilter in Signals.inc > because a lot of the stack walking fun is already done there. Perhaps > we could refactor it to use common code? > > http://codereview.appspot.com/**5647052/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/749aae5a/attachment-0001.html From benny.kra at googlemail.com Wed Feb 8 12:46:27 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Wed, 08 Feb 2012 18:46:27 -0000 Subject: [llvm-commits] [llvm] r150080 - /llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20120208184627.379302A6C12C@llvm.org> Author: d0k Date: Wed Feb 8 12:46:26 2012 New Revision: 150080 URL: http://llvm.org/viewvc/llvm-project?rev=150080&view=rev Log: Don't map registers to the invalid dwarf register (-1). It's the default value. X86GenRegisterInfo.inc | 1032 ------------------------------------------------- 1 file changed, 1032 deletions(-) Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=150080&r1=150079&r2=150080&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Wed Feb 8 12:46:26 2012 @@ -187,6 +187,9 @@ for (DwarfRegNumsMapTy::iterator I = DwarfRegNums.begin(), E = DwarfRegNums.end(); I != E; ++I) { int RegNo = I->second[i]; + if (RegNo == -1) // -1 is the default value, don't emit a mapping. + continue; + OS << " "; if (!isCtor) OS << "RI->"; From stoklund at 2pi.dk Wed Feb 8 12:54:36 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 08 Feb 2012 18:54:36 -0000 Subject: [llvm-commits] [llvm] r150081 - /llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Message-ID: <20120208185436.244882A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 12:54:35 2012 New Revision: 150081 URL: http://llvm.org/viewvc/llvm-project?rev=150081&view=rev Log: Add Register mask support to RABasic. When a virtual register is live across a call, limit the search space to call-preserved registers. Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocBasic.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocBasic.cpp?rev=150081&r1=150080&r2=150081&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocBasic.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocBasic.cpp Wed Feb 8 12:54:35 2012 @@ -72,6 +72,11 @@ std::auto_ptr SpillerInstance; std::priority_queue, CompSpillWeight> Queue; + + // Scratch space. Allocated here to avoid repeated malloc calls in + // selectOrSplit(). + BitVector UsableRegs; + public: RABasic(); @@ -234,6 +239,10 @@ // selectOrSplit(). unsigned RABasic::selectOrSplit(LiveInterval &VirtReg, SmallVectorImpl &SplitVRegs) { + // Check for register mask interference. When live ranges cross calls, the + // set of usable registers is reduced to the callee-saved ones. + bool CrossRegMasks = LIS->checkRegMaskInterference(VirtReg, UsableRegs); + // Populate a list of physical register spill candidates. SmallVector PhysRegSpillCands; @@ -244,6 +253,11 @@ ++I) { unsigned PhysReg = *I; + // If PhysReg is clobbered by a register mask, it isn't useful for + // allocation or spilling. + if (CrossRegMasks && !UsableRegs.test(PhysReg)) + continue; + // Check interference and as a side effect, intialize queries for this // VirtReg and its aliases. unsigned interfReg = checkPhysRegInterference(VirtReg, PhysReg); From samsonov at google.com Wed Feb 8 13:52:01 2012 From: samsonov at google.com (Alexey Samsonov) Date: Wed, 08 Feb 2012 19:52:01 -0000 Subject: [llvm-commits] [compiler-rt] r150083 - in /compiler-rt/trunk/lib/asan: Makefile.mk Makefile.old asan_interceptors.cc asan_interceptors.h asan_mac.cc asan_mac.h asan_malloc_mac.cc interception/ interception/Makefile.mk interception/interception.h interception/interception_linux.cc interception/interception_linux.h interception/interception_mac.cc interception/interception_mac.h Message-ID: <20120208195202.1EB582A6C12C@llvm.org> Author: samsonov Date: Wed Feb 8 13:52:01 2012 New Revision: 150083 URL: http://llvm.org/viewvc/llvm-project?rev=150083&view=rev Log: AddressSanitizer: start factoring out interception machinery Added: compiler-rt/trunk/lib/asan/interception/ compiler-rt/trunk/lib/asan/interception/Makefile.mk compiler-rt/trunk/lib/asan/interception/interception.h compiler-rt/trunk/lib/asan/interception/interception_linux.cc compiler-rt/trunk/lib/asan/interception/interception_linux.h compiler-rt/trunk/lib/asan/interception/interception_mac.cc compiler-rt/trunk/lib/asan/interception/interception_mac.h Modified: compiler-rt/trunk/lib/asan/Makefile.mk compiler-rt/trunk/lib/asan/Makefile.old compiler-rt/trunk/lib/asan/asan_interceptors.cc compiler-rt/trunk/lib/asan/asan_interceptors.h compiler-rt/trunk/lib/asan/asan_mac.cc compiler-rt/trunk/lib/asan/asan_mac.h compiler-rt/trunk/lib/asan/asan_malloc_mac.cc Modified: compiler-rt/trunk/lib/asan/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.mk?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/Makefile.mk (original) +++ compiler-rt/trunk/lib/asan/Makefile.mk Wed Feb 8 13:52:01 2012 @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# ModuleName := asan -SubDirs := mach_override +SubDirs := interception mach_override Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) ObjNames := $(Sources:%.cc=%.o) @@ -17,6 +17,8 @@ # FIXME: use automatic dependencies? Dependencies := $(wildcard $(Dir)/*.h) +Dependencies += $(wildcard $(Dir)/interception/*.h) +Dependencies += $(wildcard $(Dir)/mach_override/*.h) # Define a convenience variable for all the asan functions. AsanFunctions := $(Sources:%.cc=%) Modified: compiler-rt/trunk/lib/asan/Makefile.old URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.old?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/Makefile.old (original) +++ compiler-rt/trunk/lib/asan/Makefile.old Wed Feb 8 13:52:01 2012 @@ -178,6 +178,9 @@ asan_stats.h \ asan_thread.h \ asan_thread_registry.h \ + interception/interception.h \ + interception/interception_linux.h \ + interception/interception_mac.h \ mach_override/mach_override.h LIBASAN_OBJ=$(BIN)/asan_rtl$(SUFF).o \ @@ -195,6 +198,8 @@ $(BIN)/asan_stats$(SUFF).o \ $(BIN)/asan_thread$(SUFF).o \ $(BIN)/asan_thread_registry$(SUFF).o \ + $(BIN)/interception/interception_linux$(SUFF).o \ + $(BIN)/interception/interception_mac$(SUFF).o \ $(BIN)/mach_override/mach_override$(SUFF).o GTEST_ROOT=third_party/googletest @@ -215,9 +220,9 @@ t32: b32 $(BIN)/asan_test32 -b64: | $(BIN) +b64: | mk_bin_dir $(MAKE) -f $(MAKEFILE) ARCH=x86_64 asan_test asan_benchmarks -b32: | $(BIN) +b32: | mk_bin_dir $(MAKE) -f $(MAKEFILE) ARCH=i386 asan_test asan_benchmarks lib64: @@ -225,8 +230,9 @@ lib32: $(MAKE) $(MAKEFILE) ARCH=i386 lib -$(BIN): +mk_bin_dir: mkdir -p $(BIN) + mkdir -p $(BIN)/interception mkdir -p $(BIN)/mach_override clang: @@ -330,6 +336,7 @@ lint: third_party/cpplint/cpplint.py --filter=$(LLVM_LINT_FILTER) $(ADDRESS_SANITIZER_CPP) third_party/cpplint/cpplint.py --filter=$(RTL_LINT_FITLER) asan_*.cc asan_*.h + third_party/cpplint/cpplint.py --filter=$(RTL_LINT_FITLER) interception/interception*.h interception/interception*.cc third_party/cpplint/cpplint.py --filter=$(TEST_LINT_FITLER) tests/*.cc get_third_party: Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original) +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Feb 8 13:52:01 2012 @@ -21,74 +21,22 @@ #include "asan_stack.h" #include "asan_stats.h" #include "asan_thread_registry.h" +#include "interception/interception.h" #include #include #ifndef _WIN32 -#include #include -#endif +#endif // _WIN32 -// To replace weak system functions on Linux we just need to declare functions -// with same names in our library and then obtain the real function pointers -// using dlsym(). This is not so on Mac OS, where the two-level namespace makes -// our replacement functions invisible to other libraries. This may be overcomed -// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared -// libraries in Chromium were noticed when doing so. -// Instead we use mach_override, a handy framework for patching functions at -// runtime. To avoid possible name clashes, our replacement functions have -// the "wrap_" prefix on Mac. -// -// After interception, the calls to system functions will be substituted by -// calls to our interceptors. We store pointers to system function f() -// in __asan::real_f(). #if defined(__APPLE__) -// Include the declarations of the original functions. +// FIXME(samsonov): Gradually replace system headers with declarations of +// intercepted functions. #include #include #include - -#include "mach_override/mach_override.h" - -#define OVERRIDE_FUNCTION(oldfunc, newfunc) \ - do {CHECK(0 == __asan_mach_override_ptr_custom((void*)(oldfunc), \ - (void*)(newfunc), \ - (void**)&real_##oldfunc, \ - __asan_allocate_island, \ - __asan_deallocate_island)); \ - CHECK(real_##oldfunc != NULL); } while (0) - -#define OVERRIDE_FUNCTION_IF_EXISTS(oldfunc, newfunc) \ - do { __asan_mach_override_ptr_custom((void*)(oldfunc), \ - (void*)(newfunc), \ - (void**)&real_##oldfunc, \ - __asan_allocate_island, \ - __asan_deallocate_island); \ - } while (0) - -#define INTERCEPT_FUNCTION(func) \ - OVERRIDE_FUNCTION(func, WRAP(func)) - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - OVERRIDE_FUNCTION_IF_EXISTS(func, WRAP(func)) - -#elif defined(_WIN32) -// TODO(timurrrr): change these macros once we decide how to intercept -// functions on Windows. -#define INTERCEPT_FUNCTION(func) \ - do { } while (0) - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - do { } while (0) - -#else // __linux__ -#define INTERCEPT_FUNCTION(func) \ - CHECK((real_##func = (func##_f)dlsym(RTLD_NEXT, #func))); - -#define INTERCEPT_FUNCTION_IF_EXISTS(func) \ - do { real_##func = (func##_f)dlsym(RTLD_NEXT, #func); } while (0) -#endif +#endif // __APPLE__ namespace __asan { @@ -581,12 +529,12 @@ namespace __asan { void InitializeAsanInterceptors() { #ifndef __APPLE__ - INTERCEPT_FUNCTION(index); + CHECK(INTERCEPT_FUNCTION(index)); #else - OVERRIDE_FUNCTION(index, WRAP(strchr)); + CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); #endif - INTERCEPT_FUNCTION(memcmp); - INTERCEPT_FUNCTION(memmove); + CHECK(INTERCEPT_FUNCTION(memcmp)); + CHECK(INTERCEPT_FUNCTION(memmove)); #ifdef __APPLE__ // Wrap memcpy() on OS X 10.6 only, because on 10.7 memcpy() and memmove() // are resolved into memmove$VARIANT$sse42. @@ -594,44 +542,44 @@ // TODO(glider): need to check dynamically that memcpy() and memmove() are // actually the same function. if (GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD) { - INTERCEPT_FUNCTION(memcpy); + CHECK(INTERCEPT_FUNCTION(memcpy)); } else { REAL(memcpy) = REAL(memmove); } #else // Always wrap memcpy() on non-Darwin platforms. - INTERCEPT_FUNCTION(memcpy); + CHECK(INTERCEPT_FUNCTION(memcpy)); #endif - INTERCEPT_FUNCTION(memset); - INTERCEPT_FUNCTION(strcasecmp); - INTERCEPT_FUNCTION(strcat); // NOLINT - INTERCEPT_FUNCTION(strchr); - INTERCEPT_FUNCTION(strcmp); - INTERCEPT_FUNCTION(strcpy); // NOLINT - INTERCEPT_FUNCTION(strdup); - INTERCEPT_FUNCTION(strlen); - INTERCEPT_FUNCTION(strncasecmp); - INTERCEPT_FUNCTION(strncmp); - INTERCEPT_FUNCTION(strncpy); - - INTERCEPT_FUNCTION(sigaction); - INTERCEPT_FUNCTION(signal); - INTERCEPT_FUNCTION(longjmp); - INTERCEPT_FUNCTION(_longjmp); - INTERCEPT_FUNCTION_IF_EXISTS(__cxa_throw); - INTERCEPT_FUNCTION(pthread_create); + CHECK(INTERCEPT_FUNCTION(memset)); + CHECK(INTERCEPT_FUNCTION(strcasecmp)); + CHECK(INTERCEPT_FUNCTION(strcat)); // NOLINT + CHECK(INTERCEPT_FUNCTION(strchr)); + CHECK(INTERCEPT_FUNCTION(strcmp)); + CHECK(INTERCEPT_FUNCTION(strcpy)); // NOLINT + CHECK(INTERCEPT_FUNCTION(strdup)); + CHECK(INTERCEPT_FUNCTION(strlen)); + CHECK(INTERCEPT_FUNCTION(strncasecmp)); + CHECK(INTERCEPT_FUNCTION(strncmp)); + CHECK(INTERCEPT_FUNCTION(strncpy)); + + CHECK(INTERCEPT_FUNCTION(sigaction)); + CHECK(INTERCEPT_FUNCTION(signal)); + CHECK(INTERCEPT_FUNCTION(longjmp)); + CHECK(INTERCEPT_FUNCTION(_longjmp)); + INTERCEPT_FUNCTION(__cxa_throw); + CHECK(INTERCEPT_FUNCTION(pthread_create)); #ifdef __APPLE__ - INTERCEPT_FUNCTION(dispatch_async_f); - INTERCEPT_FUNCTION(dispatch_sync_f); - INTERCEPT_FUNCTION(dispatch_after_f); - INTERCEPT_FUNCTION(dispatch_barrier_async_f); - INTERCEPT_FUNCTION(dispatch_group_async_f); + CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_after_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_barrier_async_f)); + CHECK(INTERCEPT_FUNCTION(dispatch_group_async_f)); // We don't need to intercept pthread_workqueue_additem_np() to support the // libdispatch API, but it helps us to debug the unsupported functions. Let's // intercept it only during verbose runs. if (FLAG_v >= 2) { - INTERCEPT_FUNCTION(pthread_workqueue_additem_np); + CHECK(INTERCEPT_FUNCTION(pthread_workqueue_additem_np)); } // Normally CFStringCreateCopy should not copy constant CF strings. // Replacing the default CFAllocator causes constant strings to be copied @@ -640,15 +588,15 @@ // http://code.google.com/p/address-sanitizer/issues/detail?id=10 // Until this problem is fixed we need to check that the string is // non-constant before calling CFStringCreateCopy. - INTERCEPT_FUNCTION(CFStringCreateCopy); + CHECK(INTERCEPT_FUNCTION(CFStringCreateCopy)); #else // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it // there. - INTERCEPT_FUNCTION(siglongjmp); + CHECK(INTERCEPT_FUNCTION(siglongjmp)); #endif #ifndef __APPLE__ - INTERCEPT_FUNCTION(strnlen); + CHECK(INTERCEPT_FUNCTION(strnlen)); #endif if (FLAG_v > 0) { Printf("AddressSanitizer: libc interceptors initialized\n"); Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interceptors.h (original) +++ compiler-rt/trunk/lib/asan/asan_interceptors.h Wed Feb 8 13:52:01 2012 @@ -15,66 +15,7 @@ #define ASAN_INTERCEPTORS_H #include "asan_internal.h" - -// Suppose you need to wrap/replace system function (generally, from libc): -// int foo(const char *bar, double baz); -// You'll need to: -// 1) define INTERCEPT(int, foo, const char *bar, double baz) { ... } -// 2) add a line "INTERCEPT_FUNCTION(foo)" to InitializeAsanInterceptors() -// You can access original function by calling __asan::real_foo(bar, baz). -// By defualt, real_foo will be visible only inside your interceptor, and if -// you want to use it in other parts of RTL, you'll need to: -// 3a) add DECLARE_REAL(int, foo, const char*, double); to a -// header file. -// However, if you want to implement your interceptor somewhere outside -// asan_interceptors.cc, you'll instead need to: -// 3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double); -// to a header. - -#if defined(__APPLE__) -# define WRAP(x) wrap_##x -# define WRAPPER_NAME(x) "wrap_"#x -# define INTERCEPTOR_ATTRIBUTE -#elif defined(_WIN32) -// TODO(timurrrr): we're likely to use something else later on Windows. -# define WRAP(x) wrap_##x -# define WRAPPER_NAME(x) #x -# define INTERCEPTOR_ATTRIBUTE -#else -# define WRAP(x) x -# define WRAPPER_NAME(x) #x -# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) -#endif - -#define REAL(x) real_##x -#define FUNC_TYPE(x) x##_f - -#define DECLARE_REAL(ret_type, func, ...); \ - typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ - namespace __asan { \ - extern FUNC_TYPE(func) REAL(func); \ - } - -#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...); \ - DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ - extern "C" \ - ret_type WRAP(func)(__VA_ARGS__); - -// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR -// macros does its job. In exceptional cases you may need to call REAL(foo) -// without defining INTERCEPTOR(..., foo, ...). For example, if you override -// foo with interceptor for other function. -#define DEFINE_REAL(ret_type, func, ...); \ - typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ - namespace __asan { \ - FUNC_TYPE(func) REAL(func); \ - } - -#define INTERCEPTOR(ret_type, func, ...); \ - DEFINE_REAL(ret_type, func, __VA_ARGS__); \ - extern "C" \ - INTERCEPTOR_ATTRIBUTE \ - ret_type WRAP(func)(__VA_ARGS__) +#include "interception/interception.h" DECLARE_REAL(int, memcmp, const void *a1, const void *a2, size_t size); DECLARE_REAL(void*, memcpy, void *to, const void *from, size_t size); Modified: compiler-rt/trunk/lib/asan/asan_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_mac.cc (original) +++ compiler-rt/trunk/lib/asan/asan_mac.cc Wed Feb 8 13:52:01 2012 @@ -36,8 +36,6 @@ namespace __asan { -void *island_allocator_pos = NULL; - void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp) { ucontext_t *ucontext = (ucontext_t*)context; # if __WORDSIZE == 64 @@ -314,25 +312,26 @@ } } -// The range of pages to be used by __asan_mach_override_ptr for escape -// islands. +// The range of pages to be used for escape islands. // TODO(glider): instead of mapping a fixed range we must find a range of // unmapped pages in vmmap and take them. // These constants were chosen empirically and may not work if the shadow // memory layout changes. Unfortunately they do necessarily depend on // kHighMemBeg or kHighMemEnd. +static void *island_allocator_pos = NULL; + #if __WORDSIZE == 32 -#define kIslandEnd (0xffdf0000 - kPageSize) -#define kIslandBeg (kIslandEnd - 256 * kPageSize) +# define kIslandEnd (0xffdf0000 - kPageSize) +# define kIslandBeg (kIslandEnd - 256 * kPageSize) #else -#define kIslandEnd (0x7fffffdf0000 - kPageSize) -#define kIslandBeg (kIslandEnd - 256 * kPageSize) +# define kIslandEnd (0x7fffffdf0000 - kPageSize) +# define kIslandBeg (kIslandEnd - 256 * kPageSize) #endif extern "C" -mach_error_t __asan_allocate_island(void **ptr, - size_t unused_size, - void *unused_hint) { +mach_error_t __interception_allocate_island(void **ptr, + size_t unused_size, + void *unused_hint) { if (!island_allocator_pos) { island_allocator_pos = asan_mmap((void*)kIslandBeg, kIslandEnd - kIslandBeg, @@ -349,7 +348,7 @@ } extern "C" -mach_error_t __asan_deallocate_island(void *ptr) { +mach_error_t __interception_deallocate_island(void *ptr) { // Do nothing. // TODO(glider): allow to free and reuse the island memory. return err_none; Modified: compiler-rt/trunk/lib/asan/asan_mac.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.h?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_mac.h (original) +++ compiler-rt/trunk/lib/asan/asan_mac.h Wed Feb 8 13:52:01 2012 @@ -20,7 +20,6 @@ // TODO(glider): need to check if the OS X version is 10.6 or greater. #include -#include #include #include @@ -79,15 +78,6 @@ extern "C" { -// Allocate memory for the escape island. This cannot be moved to -// mach_override, because the allocator needs to know about the ASan shadow -// mappings. -// TODO(glider): in order to place a relative jump the allocated memory should -// be within 2 Gb from the hint address. -mach_error_t __asan_allocate_island(void **ptr, size_t unused_size, - void *unused_hint); -mach_error_t __asan_deallocate_island(void *ptr); - // dispatch_barrier_async_f() is not declared in . void dispatch_barrier_async_f(dispatch_queue_t dq, void *ctxt, dispatch_function_t func); Modified: compiler-rt/trunk/lib/asan/asan_malloc_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_mac.cc?rev=150083&r1=150082&r2=150083&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_mac.cc (original) +++ compiler-rt/trunk/lib/asan/asan_malloc_mac.cc Wed Feb 8 13:52:01 2012 @@ -310,7 +310,7 @@ namespace __asan { void ReplaceSystemMalloc() { static malloc_introspection_t asan_introspection; - __asan::REAL(memset)(&asan_introspection, 0, sizeof(asan_introspection)); + REAL(memset)(&asan_introspection, 0, sizeof(asan_introspection)); asan_introspection.enumerator = &mi_enumerator; asan_introspection.good_size = &mi_good_size; @@ -321,7 +321,7 @@ asan_introspection.force_unlock = &mi_force_unlock; static malloc_zone_t asan_zone; - __asan::REAL(memset)(&asan_zone, 0, sizeof(malloc_zone_t)); + REAL(memset)(&asan_zone, 0, sizeof(malloc_zone_t)); // Start with a version 4 zone which is used for OS X 10.4 and 10.5. asan_zone.version = 4; Added: compiler-rt/trunk/lib/asan/interception/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/Makefile.mk?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/Makefile.mk (added) +++ compiler-rt/trunk/lib/asan/interception/Makefile.mk Wed Feb 8 13:52:01 2012 @@ -0,0 +1,22 @@ +#===- lib/asan/interception/Makefile.mk --------------------*- Makefile -*--===# +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +#===------------------------------------------------------------------------===# + +ModuleName := asan +SubDirs := + +Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) +ObjNames := $(Sources:%.cc=%.o) + +Implementation := Generic + +# FIXME: use automatic dependencies? +Dependencies := $(wildcard $(Dir)/*.h) + +# Define a convenience variable for all the asan functions. +AsanFunctions += $(Sources:%.cc=%) Added: compiler-rt/trunk/lib/asan/interception/interception.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception.h?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception.h (added) +++ compiler-rt/trunk/lib/asan/interception/interception.h Wed Feb 8 13:52:01 2012 @@ -0,0 +1,136 @@ +//===-- interception.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Machinery for providing replacements/wrappers for system functions. +//===----------------------------------------------------------------------===// + +#ifndef INTERCEPTION_H +#define INTERCEPTION_H + +#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32) +# error "Interception doesn't work on this operating system." +#endif + +// How to use this library: +// 1) Include this header to define your own interceptors +// (see details below). +// 2) Build all *.cc files and link against them. +// On Mac you will also need to: +// 3) Provide your own implementation for the following functions: +// mach_error_t __interception::allocate_island(void **ptr, +// size_t size, +// void *hint); +// mach_error_t __interception::deallocate_island(void *ptr); +// See "interception_mac.h" for more details. + +// How to add an interceptor: +// Suppose you need to wrap/replace system function (generally, from libc): +// int foo(const char *bar, double baz); +// You'll need to: +// 1) define INTERCEPTOR(int, foo, const char *bar, double baz) { ... } in +// your source file. +// 2) Call "INTERCEPT_FUNCTION(foo)" prior to the first call of "foo". +// INTERCEPT_FUNCTION(foo) evaluates to "true" iff the function was +// intercepted successfully. +// You can access original function by calling REAL(foo)(bar, baz). +// By default, REAL(foo) will be visible only inside your interceptor, and if +// you want to use it in other parts of RTL, you'll need to: +// 3a) add DECLARE_REAL(int, foo, const char*, double); to a +// header file. +// However, if the call "INTERCEPT_FUNCTION(foo)" and definition for +// INTERCEPTOR(..., foo, ...) are in different files, you'll instead need to: +// 3b) add DECLARE_REAL_AND_INTERCEPTOR(int, foo, const char*, double); +// to a header file. + +// Notes: 1. Things may not work properly if macro INTERCEPT(...) {...} or +// DECLARE_REAL(...); are located inside namespaces. +// 2. On Mac you can also use: "OVERRIDE_FUNCTION(foo, zoo);" to +// effectively redirect calls from "foo" to "zoo". In this case +// you aren't required to implement +// INTERCEPTOR(int, foo, const char *bar, double baz); +// but instead you'll have to add +// DEFINE_REAL(int, foo, const char *bar, double baz); in your +// source file (to define a pointer to overriden function). + +// How it works: +// To replace weak system functions on Linux we just need to declare functions +// with same names in our library and then obtain the real function pointers +// using dlsym(). This is not so on Mac OS, where the two-level namespace makes +// our replacement functions invisible to other libraries. This may be overcomed +// using the DYLD_FORCE_FLAT_NAMESPACE, but some errors loading the shared +// libraries in Chromium were noticed when doing so. +// Instead we use mach_override, a handy framework for patching functions at +// runtime. To avoid possible name clashes, our replacement functions have +// the "wrap_" prefix on Mac. + +#if defined(__APPLE__) +# define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) "wrap_"#x +# define INTERCEPTOR_ATTRIBUTE +#elif defined(_WIN32) +// TODO(timurrrr): we're likely to use something else later on Windows. +# define WRAP(x) wrap_##x +# define WRAPPER_NAME(x) #x +# define INTERCEPTOR_ATTRIBUTE +#else +# define WRAP(x) x +# define WRAPPER_NAME(x) #x +# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) +#endif + +#define PTR_TO_REAL(x) real_##x +#define REAL(x) __interception::PTR_TO_REAL(x) +#define FUNC_TYPE(x) x##_f + +#define DECLARE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + namespace __interception { \ + extern FUNC_TYPE(func) PTR_TO_REAL(func); \ + } + +#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...); \ + DECLARE_REAL(ret_type, func, ##__VA_ARGS__); \ + extern "C" ret_type WRAP(func)(__VA_ARGS__); + +// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR +// macros does its job. In exceptional cases you may need to call REAL(foo) +// without defining INTERCEPTOR(..., foo, ...). For example, if you override +// foo with an interceptor for other function. +#define DEFINE_REAL(ret_type, func, ...); \ + typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ + namespace __interception { \ + FUNC_TYPE(func) PTR_TO_REAL(func); \ + } + +#define INTERCEPTOR(ret_type, func, ...) \ + DEFINE_REAL(ret_type, func, __VA_ARGS__); \ + extern "C" \ + INTERCEPTOR_ATTRIBUTE \ + ret_type WRAP(func)(__VA_ARGS__) + +#define INCLUDED_FROM_INTERCEPTION_LIB + +#if defined(__linux__) +# include "interception_linux.h" +# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX(func) +#elif defined(__APPLE__) +# include "interception_mac.h" +# define OVERRIDE_FUNCTION(old_func, new_func) \ + OVERRIDE_FUNCTION_MAC(old_func, new_func) +# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) +#else // defined(_WIN32) + // FIXME: deal with interception on Win. +# define INTERCEPT_FUNCTON(func) true +#endif + +#undef INCLUDED_FROM_INTERCEPTION_LIB + +#endif // INTERCEPTION_H Added: compiler-rt/trunk/lib/asan/interception/interception_linux.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_linux.cc?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception_linux.cc (added) +++ compiler-rt/trunk/lib/asan/interception/interception_linux.cc Wed Feb 8 13:52:01 2012 @@ -0,0 +1,27 @@ +//===-- interception_linux.cc -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Linux-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef __linux__ + +#include // for dlsym + +namespace __interception { +bool GetRealFunctionAddress(const char *func_name, void **func_addr) { + *func_addr = dlsym(RTLD_NEXT, func_name); + return (*func_addr != NULL); +} +} // namespace __interception + + +#endif // __linux__ Added: compiler-rt/trunk/lib/asan/interception/interception_linux.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_linux.h?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception_linux.h (added) +++ compiler-rt/trunk/lib/asan/interception/interception_linux.h Wed Feb 8 13:52:01 2012 @@ -0,0 +1,33 @@ +//===-- interception_linux.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Linux-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef __linux__ + +#if !defined(INCLUDED_FROM_INTERCEPTION_LIB) +# error "interception_mac.h should be included from interception library only" +#endif + +#ifndef INTERCEPTION_LINUX_H +#define INTERCEPTION_LINUX_H + +namespace __interception { +// returns true if a function with the given name was found. +bool GetRealFunctionAddress(const char *func_name, void **func_addr); +} // namespace __interception + +#define INTERCEPT_FUNCTION_LINUX(func) \ + ::__interception::GetRealFunctionAddress(#func, (void**)&REAL(func)) + +#endif // INTERCEPTION_LINUX_H +#endif // __linux__ Added: compiler-rt/trunk/lib/asan/interception/interception_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_mac.cc?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception_mac.cc (added) +++ compiler-rt/trunk/lib/asan/interception/interception_mac.cc Wed Feb 8 13:52:01 2012 @@ -0,0 +1,34 @@ +//===-- interception_mac.cc -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Mac-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef __APPLE__ + +#define INCLUDED_FROM_INTERCEPTION_LIB +#include "interception_mac.h" +#undef INCLUDED_FROM_INTERCEPTION_LIB +// FIXME(samsonov): Put mach_override/ under interception/ +#include "../mach_override/mach_override.h" + +namespace __interception { +bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { + *orig_old_func = NULL; + int res = __asan_mach_override_ptr_custom(old_func, new_func, + orig_old_func, + __interception_allocate_island, + __interception_deallocate_island); + return (res == 0) && (*orig_old_func != NULL); +} +} // namespace __interception + +#endif // __APPLE__ Added: compiler-rt/trunk/lib/asan/interception/interception_mac.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_mac.h?rev=150083&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception_mac.h (added) +++ compiler-rt/trunk/lib/asan/interception/interception_mac.h Wed Feb 8 13:52:01 2012 @@ -0,0 +1,47 @@ +//===-- interception_mac.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Mac-specific interception methods. +//===----------------------------------------------------------------------===// + +#ifdef __APPLE__ + +#if !defined(INCLUDED_FROM_INTERCEPTION_LIB) +# error "interception_mac.h should be included from interception.h only" +#endif + +#ifndef INTERCEPTION_MAC_H +#define INTERCEPTION_MAC_H + +#include +#include + +// Allocate memory for the escape island. This cannot be moved to +// mach_override, because each user of interceptors may specify its +// own memory range for escape islands. +extern "C" { +mach_error_t __interception_allocate_island(void **ptr, size_t unused_size, + void *unused_hint); +mach_error_t __interception_deallocate_island(void *ptr); +} // extern "C" + +namespace __interception { +// returns true if the old function existed. +bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func); +} // namespace __interception + +# define OVERRIDE_FUNCTION_MAC(old_func, new_func) \ + ::__interception::OverrideFunction((void*)old_func, (void*)new_func, \ + (void**)&REAL(old_func)) +# define INTERCEPT_FUNCTION_MAC(func) OVERRIDE_FUNCTION_MAC(func, WRAP(func)) + +#endif // INTERCEPTION_MAC_H +#endif // __APPLE__ From baldrick at free.fr Wed Feb 8 13:59:58 2012 From: baldrick at free.fr (Duncan Sands) Date: Wed, 08 Feb 2012 20:59:58 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> Message-ID: <4F32D43E.6010900@free.fr> Hi David, >>>> then I guess you will have to use inline asm. >>> >>> We can't use inline asm. Our compiler does not support it. >> >> your front-end can expand the builtin into the corresponding LLVM inline >> asm expression when generating the IR. > > So now our frontend has to be a code generator? And understand all > possible targets, asm formats, etc.? > > That's ridiculous. I didn't try, but turning __builtin_ia32_vpermilpd into an inline asm is presumably rather trivial. I'm not sure why you think you need to know all kinds of stuff to do so (maybe you do - as I said I didn't try). You obviously have a rather good idea of the target since these are x86 intrinsics, you already need to know the parameter types; hopefully sprinkling a little magic pixie dust would do the job. Anyway, it seems rather natural to me to use an inline asm: you say "my customers are using __builtin_ia32_vpermilpd because they want the vpermilpd instruction". I.e. they want it to act like an inline asm. So let it be one! But as I mentioned, it may be harder than I'm imagining - if it was easy to use inline asm, why were the intrinsics introduced in the first place? But why not give it a go? > What is so difficult about keeping intrinsics around? Are they causing > some major issue? I'm not the one removing intrinsics, and I don't know what the reason is. However keeping useless functionality does create a maintenance burden for no real benefit. I call these intrinsics useless since you can get the same semantic effect using generic IR, or exactly the instruction using inline asm. If turning them into inline asm is a real pain as you suspect, then I for one would vote to keep the intrinsics. Ciao, Duncan. From samsonov at google.com Wed Feb 8 14:05:40 2012 From: samsonov at google.com (samsonov at google.com) Date: Wed, 08 Feb 2012 20:05:40 +0000 Subject: [llvm-commits] AddressSanitizer: start factoring out interception machinery (issue 5642046) Message-ID: <20cf300faf257f3f0204b8796bfb@google.com> r150083 > Looks good! > On Wed, Feb 8, 2012 at 7:38 AM, wrote: > > kcc@: > > 1) Moved auxiliary functions under __interception namespace. > > 2) Why can't we for simplicity declare real_f inside __interception > > namespace as well? > ok > > This may break if two different libraries using > > interception are linked together, but it's a mess anyway, as they'll > > have interceptors for the same functions. > > 3) This CL is large already, so I'd prefer to resolve some FIXMEs after > > this CL is submitted, if you don't mind. > > > ok > > > > glider@ suggested we should remove all OS-specific > > details from the header "interception.h", so I moved them > > to OS-specific headers. In this way the user code will not include > > or mach_override.h > > > > > > > > http://codereview.appspot.com/**5642046/diff/1012/asan_**interceptors.h%3Chttp://codereview.appspot.com/5642046/diff/1012/asan_interceptors.h> > > File asan_interceptors.h (right): > > > > http://codereview.appspot.com/**5642046/diff/1012/asan_** > > interceptors.h#newcode34 > > asan_interceptors.h:34: size_t internal_strlen(const char *s); > > On 2012/02/08 08:19:17, glider wrote: > > > >> BTW aren't these functions already declared in asan_internal.h? > >> > > > > Not yet. > > > > http://codereview.appspot.com/**5642046/%3Chttp://codereview.appspot.com/5642046/> > > http://codereview.appspot.com/5642046/ From timurrrr at google.com Wed Feb 8 14:25:41 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Wed, 08 Feb 2012 20:25:41 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf3005ddc412706b04b879b3e5@google.com> Addressed most of the comments, except the _WIN32 vs WINDOWS ones. Forgot to mention: This code in asan_win.cc is not production quality, it's just an early prototype; it works on some simple tests but not expected to work on any non-trivial app. I expect much of it to be rewritten when I write more tests, do more debug and read more docs - especially the code near the "FIXME" comments. If it's OK I'd like to defer polishing the code there until we have "this code is bad" data from tests and runs on non-trivial apps. Kostya, Re: _WIN32 vs WINDOWS - is this a big issue? I expect to remove the new ifdefs eventually and there aren't too many "old" ones in the other places. If it turns out to be a problem - it'd be easy to `sed` through the code; but if possible I'd like to do it in a separate patch and only when it's a real problem. Please note that _WIN32/_WIN64 are the default macros "cl" automatically defines, see http://msdn.microsoft.com/en-us/library/b0084kay.aspx Having our custom WINDOWS macro (what about 64-bits? WINDOWS64?) will be somewhat against the standard win-code convention. Also, my simple "cl *.cc" command line will become more than twice as long :) I don't want to rely on Makefiles/CMake (yet?) to build ASan/RTL for Windows. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode32 lib/asan/asan_interceptors.cc:32: # include // FIXME: remove when we start intercepting on Windows. On 2012/02/08 18:03:10, kcc wrote: > Why do you need this now? Added a comment. Note it's a FIXME item, I'll need to re-do this anyways once we start intercepting functions properly. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc File lib/asan/asan_win.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode37 lib/asan/asan_win.cc:37: // FIXME: what is mem_type? On 2012/02/08 18:03:10, kcc wrote: > memtype is a string used for reporting mmap errors Got it, removed the comment. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode88 lib/asan/asan_win.cc:88: CHECK(VirtualQuery(&mbi /* on stack */, On 2012/02/08 18:19:20, Aaron.Ballman wrote: > The stack will always be a single block, but I think what you're getting there > is including the stack's guard page. Are you sure you want that? Also, I think > that's only getting you the reserved size and not the committed size. I'd like to defer answering this question until we add tests for stack accesses (correct and incorrect ones). I'll definitely return to it once we have more tests to judge the correctness. Is it OK to commit without investigating it given I've added the FIXME? http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode98 lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); On 2012/02/08 18:03:10, kcc wrote: > OMG. Ok for now, but in the long run this is not going to work. > We will need our own unwinder. I might have misread MSDN earlies (or misreading it now?) and/or copy-pasted this from some other code but turns out CaptureStackBackTrace DOES NOT require the dbghelp lock. I've removed it for now. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode103 lib/asan/asan_win.cc:103: size_t cs_ret = CaptureStackBackTrace(1, max_size, tmp, NULL), Added a few FIXMEs to look at if the performance is a problem On 2012/02/08 18:19:20, Aaron.Ballman wrote: > Since you're already using DbgHelp APIs, would StackWalk64 make a bit more > sense? IIRC, it's a bit more accurate than > CaptureStackBackTrace. Certainly it gives you more control. > You may want to look at LLVMUnhandledExceptionFilter in Signals.inc because a > lot of the stack walking fun is already done there. Perhaps we could refactor > it to use common code? http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_win.cc#newcode167 lib/asan/asan_win.cc:167: AsanLock::AsanLock(LinkerInitialized li) { On 2012/02/08 18:03:10, kcc wrote: > This is in fact *not* linker-initialized. > Is there a way to create a linker-initialized lock on windows? CRITICAL_SECTION contains nonzero values after InitializeCriticalSection call, so it can't simply be zero-initizlized. http://codereview.appspot.com/5647052/ From dag at cray.com Wed Feb 8 14:46:52 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 14:46:52 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F32D43E.6010900@free.fr> (Duncan Sands's message of "Wed, 08 Feb 2012 20:59:58 +0100") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> <4F32D43E.6010900@free.fr> Message-ID: Duncan Sands writes: >> So now our frontend has to be a code generator? And understand all >> possible targets, asm formats, etc.? >> >> That's ridiculous. > > I didn't try, but turning __builtin_ia32_vpermilpd into an inline asm is > presumably rather trivial. I don't know how hard it would be. The frontend would have to know about mnemonics, at least. And it would have to know whether to generate AT&T or Intel syntax. It strikes me as the wrong place to do this when the mechanisms already exist in the current codegen. > But why not give it a go? Because it works now, we've been using it for years and I have a million other things to fix and improve. Could it be done? Sure. Is it worth the expense to do it given an existing solution? No way. >> What is so difficult about keeping intrinsics around? Are they causing >> some major issue? > > I'm not the one removing intrinsics, and I don't know what the reason is. > However keeping useless functionality does create a maintenance burden for > no real benefit. They're not useless. We are using them. And I question whether it is much of a maintenance burden at all. Who goes and changes existing intrinsics? > I call these intrinsics useless since you can get the same > semantic effect using generic IR Users expect more than the same semantic effect. > or exactly the instruction using inline asm. With a lot of extra work which is completely unnecessary given that a solution already exists. > If turning them into inline asm is a real pain as you suspect, then I > for one would vote to keep the intrinsics. It is infinitely more painful than just using what we already have, what we know works and which requires zero effort to keep working. -Dave From dag at cray.com Wed Feb 8 14:48:11 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 14:48:11 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <91C216B9-0938-45CB-B077-10361711CADC@apple.com> (Eric Christopher's message of "Wed, 08 Feb 2012 10:43:08 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <91C216B9-0938-45CB-B077-10361711CADC@apple.com> Message-ID: Eric Christopher writes: >> Whether generic IR is a "win" isn't the primary issue here. The issue >> is that the user wrote code using intrinsics and expects that exact code >> to be in the asm. Whether or not that is the best performing code >> possible doesn't matter. It's what they want and we have to respect it. >> Our customers demand it. > > Then make the generic IR match what you think should happen. I see no win > for anyone with this. There is no way to do that. It's generic. By definition passes can change it. You see no benefit even though I have directly stated that their existance and use is critically important to us? Maybe no benefit for Apple, but we are not Apple. -Dave From anton at korobeynikov.info Wed Feb 8 14:55:55 2012 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 9 Feb 2012 00:55:55 +0400 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: David, > That's part of the reason I started to write a new C backend. ?Though > that's stalled at the moment, it's still on my TODO list. Maybe you can share what you have at the moment? Then someone else can continue work in this area? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From slarin at codeaurora.org Wed Feb 8 14:59:59 2012 From: slarin at codeaurora.org (Sergei Larin) Date: Wed, 8 Feb 2012 14:59:59 -0600 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: References: Message-ID: <114101cce6a4$9ecaaf10$dc600d30$@org> Everyone, Not that I do not like to read about every single commit going in to the tree, but I would like to see if there is any support to separation of llvm-commits into several project centric mailing lists - something along the line of llvm-commits-rt, llvm-commits-polly, llvm-commits etc. .? I do see some "lost patches"/review requests being blamed on high message volume, and deeply empathize. The only down side I can see is the need for moderation (ownership) on every new such list created. Sergei Larin -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum. From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Kostya Serebryany Sent: Tuesday, February 07, 2012 2:13 PM To: John McCall Cc: llvm-commits at cs.uiuc.edu Subject: Re: [llvm-commits] [llvm] r148553 - in /llvm/trunk: docs/LangRef.html include/llvm-c/Core.h include/llvm/Attributes.h lib/AsmParser/LLLexer.cpp lib/AsmParser/LLParser.cpp lib/AsmParser/LLParser.h lib/AsmParser/LLToken.h lib/Bitcode/Reader/BitcodeRead On Tue, Feb 7, 2012 at 11:42 AM, John McCall wrote: On Jan 20, 2012, at 9:56 AM, Kostya Serebryany wrote: > Author: kcc > Date: Fri Jan 20 11:56:17 2012 > New Revision: 148553 > > URL: http://llvm.org/viewvc/llvm-project?rev=148553 &view=rev > Log: > Extend Attributes to 64 bits > > Problem: LLVM needs more function attributes than currently available (32 bits). > One such proposed attribute is "address_safety", which shows that a function is being checked for address safety (by AddressSanitizer, SAFECode, etc). > > Solution: > - extend the Attributes from 32 bits to 64-bits > - wrap the object into a class so that unsigned is never erroneously used instead > - change "unsigned" to "Attributes" throughout the code, including one place in clang. > - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to support packing/unpacking. > - the class has "safe operator bool()" to support the common idiom: if (Attributes attr = getAttrs()) useAttrs(attr); > - The CTOR from uint64_t is marked explicit, so I had to add a few explicit CTOR calls > - Add the new attribute "address_safety". Doing it in the same commit to check that attributes beyond first 32 bits actually work. > - Some of the functions from the Attribute namespace are worth moving inside the class, but I'd prefer to have it as a separate commit. > > Tested: > "make check" on Linux (32-bit and 64-bit) and Mac (10.6) > built/run spec CPU 2006 on Linux with clang -O2. Using a class here is introducing global initializers into every translation unit that includes llvm/Attributes.h. Those initializers are optimized out at -O1 (by clang, at least), but it's still bad practice. Why? This code looks clean and effective (with >=O1). If you remove all the constructors from the class, you can use list-initialization instead, which (in this case) is essentially guaranteed to not require a global initializer; the only other alternative (given MSVC's limitations) What are these limitations? We can probably come up with something like a proxy class to initialize the Attribute constans, not sure if it's worth doing so. What are your suggestions? --kcc is to give up on type-safety and use a typedef for uint64_t, which I think is the easiest answer, if also the most dissatisfying. John. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/c913fc5a/attachment.html From konstantin.s.serebryany at gmail.com Wed Feb 8 15:00:44 2012 From: konstantin.s.serebryany at gmail.com (Konstantin Serebryany) Date: Wed, 8 Feb 2012 13:00:44 -0800 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) In-Reply-To: <20cf3005ddc412706b04b879b3e5@google.com> References: <20cf3005ddc412706b04b879b3e5@google.com> Message-ID: On Wed, Feb 8, 2012 at 12:25 PM, wrote: > Addressed most of the comments, except the > _WIN32 vs WINDOWS ones. > > Forgot to mention: > This code in asan_win.cc is not production quality, it's just an early > prototype; it works on some simple tests but not expected to work on any > non-trivial app. > I expect much of it to be rewritten when I write more tests, do more > debug and read more docs - especially the code near the "FIXME" > comments. > If it's OK I'd like to defer polishing the code there until we have > "this code is bad" data from tests and runs on non-trivial apps. > I am ok with it, as long as the code builds and does not hurt anyone's build bots. > > Kostya, > Re: _WIN32 vs WINDOWS - is this a big issue? > yes. Please do #if _WIN32 || _WIN64 #define ASAN_WINDOWS 1 #else # define ASAN_WINDOWS 0 #endif and use if (ASAN_WINDOWS) everywhere else in the code. This way is much more readable and we can make sure that the code compiles on all platforms and does not depend on OS-specific stuff. --kcc > I expect to remove the new ifdefs eventually and there aren't too many > "old" ones in the other places. > If it turns out to be a problem - it'd be easy to `sed` through the > code; but if possible I'd like to do it in a separate patch and only > when it's a real problem. > > Please note that _WIN32/_WIN64 are the default macros "cl" automatically > defines, see http://msdn.microsoft.com/en-**us/library/b0084kay.aspx > Having our custom WINDOWS macro (what about 64-bits? WINDOWS64?) will be > somewhat against the standard win-code convention. > > Also, my simple "cl *.cc" command line will become more than twice as > long :) > I don't want to rely on Makefiles/CMake (yet?) to build ASan/RTL for > Windows. > > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_interceptors.cc > File lib/asan/asan_interceptors.cc (right): > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_interceptors.cc#newcode32 > lib/asan/asan_interceptors.cc:**32: # include // FIXME: remove > when we start intercepting on Windows. > On 2012/02/08 18:03:10, kcc wrote: > >> Why do you need this now? >> > Added a comment. Note it's a FIXME item, I'll need to re-do this anyways > once we start intercepting functions properly. > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/**asan_win.cc > File lib/asan/asan_win.cc (right): > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode37 > lib/asan/asan_win.cc:37: // FIXME: what is mem_type? > On 2012/02/08 18:03:10, kcc wrote: > >> memtype is a string used for reporting mmap errors >> > Got it, removed the comment. > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode88 > lib/asan/asan_win.cc:88: CHECK(VirtualQuery(&mbi /* on stack */, > On 2012/02/08 18:19:20, Aaron.Ballman wrote: > >> The stack will always be a single block, but I think what you're >> > getting there > >> is including the stack's guard page. Are you sure you want that? >> > Also, I think > >> that's only getting you the reserved size and not the committed size. >> > I'd like to defer answering this question until we add tests for stack > accesses (correct and incorrect ones). > I'll definitely return to it once we have more tests to judge the > correctness. > Is it OK to commit without investigating it given I've added the FIXME? > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode98 > lib/asan/asan_win.cc:98: ScopedLock lock(&dbghelp_lock); > On 2012/02/08 18:03:10, kcc wrote: > >> OMG. Ok for now, but in the long run this is not going to work. >> We will need our own unwinder. >> > > I might have misread MSDN earlies (or misreading it now?) and/or > copy-pasted this from some other code > but turns out CaptureStackBackTrace DOES NOT require the dbghelp lock. > I've removed it for now. > > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode103 > lib/asan/asan_win.cc:103: size_t cs_ret = CaptureStackBackTrace(1, > max_size, tmp, NULL), > Added a few FIXMEs to look at if the performance is a problem > > > On 2012/02/08 18:19:20, Aaron.Ballman wrote: > >> Since you're already using DbgHelp APIs, would StackWalk64 make a bit >> > more > >> sense? IIRC, it's a bit more accurate than >> CaptureStackBackTrace. Certainly it gives you more control. >> > > You may want to look at LLVMUnhandledExceptionFilter in Signals.inc >> > because a > >> lot of the stack walking fun is already done there. Perhaps we could >> > refactor > >> it to use common code? >> > > http://codereview.appspot.com/**5647052/diff/6001/lib/asan/** > asan_win.cc#newcode167 > lib/asan/asan_win.cc:167: AsanLock::AsanLock(**LinkerInitialized li) { > On 2012/02/08 18:03:10, kcc wrote: > >> This is in fact *not* linker-initialized. >> Is there a way to create a linker-initialized lock on windows? >> > CRITICAL_SECTION contains nonzero values after InitializeCriticalSection > call, so it can't simply be zero-initizlized. > > http://codereview.appspot.com/**5647052/ > -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/0fd7bd20/attachment-0001.html From atrick at apple.com Wed Feb 8 15:22:30 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:30 -0000 Subject: [llvm-commits] [llvm] r150091 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/Passes.cpp lib/CodeGen/TailDuplication.cpp lib/Target/PTX/PTXTargetMachine.cpp Message-ID: <20120208212231.0F30B2A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:30 2012 New Revision: 150091 URL: http://llvm.org/viewvc/llvm-project?rev=150091&view=rev Log: Move pass configuration out of pass constructors: TailDuplicate::PreRegAlloc Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/CodeGen/TailDuplication.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150091&r1=150090&r2=150091&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:30 2012 @@ -272,7 +272,7 @@ /// TailDuplicate Pass - Duplicate blocks with unconditional branches /// into tails of their predecessors. - FunctionPass *createTailDuplicatePass(bool PreRegAlloc = false); + FunctionPass *createTailDuplicatePass(); /// IfConverter Pass - This pass performs machine code if conversion. FunctionPass *createIfConverterPass(); Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150091&r1=150090&r2=150091&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:30 2012 @@ -178,7 +178,7 @@ // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { - PM.add(createTailDuplicatePass(true)); + PM.add(createTailDuplicatePass()); printAndVerify("After Pre-RegAlloc TailDuplicate"); } @@ -250,7 +250,7 @@ // Tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { - PM.add(createTailDuplicatePass(false)); + PM.add(createTailDuplicatePass()); printNoVerify("After TailDuplicate"); } Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=150091&r1=150090&r2=150091&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Wed Feb 8 15:22:30 2012 @@ -56,10 +56,10 @@ namespace { /// TailDuplicatePass - Perform tail duplication. class TailDuplicatePass : public MachineFunctionPass { - bool PreRegAlloc; const TargetInstrInfo *TII; MachineModuleInfo *MMI; MachineRegisterInfo *MRI; + bool PreRegAlloc; // SSAUpdateVRs - A list of virtual registers for which to update SSA form. SmallVector SSAUpdateVRs; @@ -70,8 +70,8 @@ public: static char ID; - explicit TailDuplicatePass(bool PreRA) : - MachineFunctionPass(ID), PreRegAlloc(PreRA) {} + explicit TailDuplicatePass() : + MachineFunctionPass(ID), PreRegAlloc(false) {} virtual bool runOnMachineFunction(MachineFunction &MF); virtual const char *getPassName() const { return "Tail Duplication"; } @@ -118,14 +118,15 @@ char TailDuplicatePass::ID = 0; } -FunctionPass *llvm::createTailDuplicatePass(bool PreRegAlloc) { - return new TailDuplicatePass(PreRegAlloc); +FunctionPass *llvm::createTailDuplicatePass() { + return new TailDuplicatePass(); } bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); MRI = &MF.getRegInfo(); MMI = getAnalysisIfAvailable(); + PreRegAlloc = MRI->isSSA(); bool MadeChange = false; while (TailDuplicateBlocks(MF)) @@ -823,7 +824,7 @@ SmallVector PriorCond; // This has to check PrevBB->succ_size() because EH edges are ignored by // AnalyzeBranch. - if (PrevBB->succ_size() == 1 && + if (PrevBB->succ_size() == 1 && !TII->AnalyzeBranch(*PrevBB, PriorTBB, PriorFBB, PriorCond, true) && PriorCond.empty() && !PriorTBB && TailBB->pred_size() == 1 && !TailBB->hasAddressTaken()) { Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150091&r1=150090&r2=150091&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:22:30 2012 @@ -284,7 +284,7 @@ // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createTailDuplicatePass(true)); + PM.add(createTailDuplicatePass()); printAndVerify("After Pre-RegAlloc TailDuplicate"); } @@ -365,7 +365,7 @@ // Tail duplication. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createTailDuplicatePass(false)); + PM.add(createTailDuplicatePass()); printNoVerify("After TailDuplicate"); } From atrick at apple.com Wed Feb 8 15:22:35 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:35 -0000 Subject: [llvm-commits] [llvm] r150092 - in /llvm/trunk: include/llvm/CodeGen/Passes.h include/llvm/Pass.h lib/CodeGen/Passes.cpp lib/VMCore/Pass.cpp Message-ID: <20120208212235.3AB752A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:34 2012 New Revision: 150092 URL: http://llvm.org/viewvc/llvm-project?rev=150092&view=rev Log: Added Pass::createPass(ID) to handle pass configuration by ID Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/Pass.h llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/VMCore/Pass.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150092&r1=150091&r2=150092&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:34 2012 @@ -135,7 +135,7 @@ /// /// Add a target-independent CodeGen pass at this point in the pipeline. - void addCommonPass(char &ID); + void addPass(char &ID); /// printNoVerify - Add a pass to dump the machine function, if debugging is /// enabled. Modified: llvm/trunk/include/llvm/Pass.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Pass.h?rev=150092&r1=150091&r2=150092&view=diff ============================================================================== --- llvm/trunk/include/llvm/Pass.h (original) +++ llvm/trunk/include/llvm/Pass.h Wed Feb 8 15:22:34 2012 @@ -175,6 +175,10 @@ // argument string, or null if it is not known. static const PassInfo *lookupPassInfo(StringRef Arg); + // createPass - Create a object for the specified pass class, + // or null if it is not known. + static Pass *createPass(char &TI); + /// getAnalysisIfAvailable() - Subclasses use this function to /// get analysis information that might be around, for example to update it. /// This is different than getAnalysis in that it can fail (if the analysis Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150092&r1=150091&r2=150092&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:34 2012 @@ -103,8 +103,12 @@ llvm_unreachable("TargetPassConfig should not be constructed on-the-fly"); } -void TargetPassConfig::addCommonPass(char &ID) { - // FIXME: about to be implemented. +void TargetPassConfig::addPass(char &ID) { + // FIXME: check user overrides + Pass *P = Pass::createPass(ID); + if (!P) + llvm_unreachable("Pass ID not registered"); + PM.add(P); } void TargetPassConfig::printNoVerify(const char *Banner) const { Modified: llvm/trunk/lib/VMCore/Pass.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Pass.cpp?rev=150092&r1=150091&r2=150092&view=diff ============================================================================== --- llvm/trunk/lib/VMCore/Pass.cpp (original) +++ llvm/trunk/lib/VMCore/Pass.cpp Wed Feb 8 15:22:34 2012 @@ -189,6 +189,13 @@ return PassRegistry::getPassRegistry()->getPassInfo(Arg); } +Pass *Pass::createPass(char &TI) { + const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(&TI); + if (!PI) + return NULL; + return PI->createPass(); +} + Pass *PassInfo::createPass() const { assert((!isAnalysisGroup() || NormalCtor) && "No default implementation found for analysis group!"); From atrick at apple.com Wed Feb 8 15:22:39 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:39 -0000 Subject: [llvm-commits] [llvm] r150093 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/LLVMTargetMachine.cpp lib/CodeGen/Passes.cpp lib/Target/PTX/PTXTargetMachine.cpp Message-ID: <20120208212239.DA66C2A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:39 2012 New Revision: 150093 URL: http://llvm.org/viewvc/llvm-project?rev=150093&view=rev Log: Added TargetPassConfig::setOpt Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150093&r1=150092&r2=150093&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:39 2012 @@ -39,6 +39,7 @@ protected: TargetMachine *TM; PassManagerBase &PM; + bool Initialized; // Flagged after all passes are configured. // Target Pass Options // @@ -62,6 +63,8 @@ return TM->getTargetLowering(); } + void setInitialized() { Initialized = true; } + CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } void setDisableVerify(bool disable) { DisableVerify = disable; } @@ -84,6 +87,9 @@ /// Fully developed targets will not generally override this. virtual void addMachinePasses(); protected: + // Helper to verify the analysis is really immutable. + void setOpt(bool &Opt, bool Val); + /// Methods with trivial inline returns are convenient points in the common /// codegen pass pipeline where targets may insert passes. Methods with /// out-of-line standard implementations are major CodeGen stages called by Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=150093&r1=150092&r2=150093&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original) +++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Wed Feb 8 15:22:39 2012 @@ -147,6 +147,8 @@ PassConfig->addMachinePasses(); + PassConfig->setInitialized(); + return Context; } Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150093&r1=150092&r2=150093&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:39 2012 @@ -84,7 +84,10 @@ TargetPassConfig::~TargetPassConfig() {} TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) - : ImmutablePass(ID), TM(tm), PM(pm), DisableVerify(false) { + : ImmutablePass(ID), TM(tm), PM(pm), Initialized(false), + DisableVerify(false), + EnableTailMerge(true) { + // Register all target independent codegen passes to activate their PassIDs, // including this pass itself. initializeCodeGen(*PassRegistry::getPassRegistry()); @@ -103,6 +106,12 @@ llvm_unreachable("TargetPassConfig should not be constructed on-the-fly"); } +// Helper to verify the analysis is really immutable. +void TargetPassConfig::setOpt(bool &Opt, bool Val) { + assert(!Initialized && "PassConfig is immutable"); + Opt = Val; +} + void TargetPassConfig::addPass(char &ID) { // FIXME: check user overrides Pass *P = Pass::createPass(ID); Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150093&r1=150092&r2=150093&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:22:39 2012 @@ -385,5 +385,7 @@ PM.add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel())); PM.add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel())); + setInitialized(); + return false; } From atrick at apple.com Wed Feb 8 15:22:43 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:43 -0000 Subject: [llvm-commits] [llvm] r150094 - in /llvm/trunk/lib/CodeGen: BranchFolding.cpp DeadMachineInstructionElim.cpp GCStrategy.cpp MachineCSE.cpp MachineCopyPropagation.cpp MachineSink.cpp PeepholeOptimizer.cpp StackSlotColoring.cpp Message-ID: <20120208212243.C2E782A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:43 2012 New Revision: 150094 URL: http://llvm.org/viewvc/llvm-project?rev=150094&view=rev Log: whitespace Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp llvm/trunk/lib/CodeGen/GCStrategy.cpp llvm/trunk/lib/CodeGen/MachineCSE.cpp llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp llvm/trunk/lib/CodeGen/MachineSink.cpp llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Feb 8 15:22:43 2012 @@ -208,7 +208,7 @@ delete RS; return MadeChange; } - + // Walk the function to find jump tables that are live. BitVector JTIsLive(JTI->getJumpTables().size()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); @@ -1095,7 +1095,7 @@ MachineBasicBlock::iterator PrevBBIter = PrevBB.end(); --PrevBBIter; MachineBasicBlock::iterator MBBIter = MBB->begin(); - // Check if DBG_VALUE at the end of PrevBB is identical to the + // Check if DBG_VALUE at the end of PrevBB is identical to the // DBG_VALUE at the beginning of MBB. while (PrevBBIter != PrevBB.begin() && MBBIter != MBB->end() && PrevBBIter->isDebugValue() && MBBIter->isDebugValue()) { Modified: llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp (original) +++ llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Wed Feb 8 15:22:43 2012 @@ -28,7 +28,7 @@ namespace { class DeadMachineInstructionElim : public MachineFunctionPass { virtual bool runOnMachineFunction(MachineFunction &MF); - + const TargetRegisterInfo *TRI; const MachineRegisterInfo *MRI; const TargetInstrInfo *TII; Modified: llvm/trunk/lib/CodeGen/GCStrategy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GCStrategy.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/GCStrategy.cpp (original) +++ llvm/trunk/lib/CodeGen/GCStrategy.cpp Wed Feb 8 15:22:43 2012 @@ -35,9 +35,9 @@ using namespace llvm; namespace { - + /// LowerIntrinsics - This pass rewrites calls to the llvm.gcread or - /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as + /// llvm.gcwrite intrinsics, replacing them with simple loads and stores as /// directed by the GCStrategy. It also performs automatic root initialization /// and custom intrinsic lowering. class LowerIntrinsics : public FunctionPass { @@ -47,20 +47,20 @@ bool PerformDefaultLowering(Function &F, GCStrategy &Coll); static bool InsertRootInitializers(Function &F, AllocaInst **Roots, unsigned Count); - + public: static char ID; - + LowerIntrinsics(); const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; - + bool doInitialization(Module &M); bool runOnFunction(Function &F); }; - - - /// MachineCodeAnalysis - This is a target-independent pass over the machine + + + /// MachineCodeAnalysis - This is a target-independent pass over the machine /// function representation to identify safe points for the garbage collector /// in the machine code. It inserts labels at safe points and populates a /// GCMetadata record for each function. @@ -69,25 +69,25 @@ GCFunctionInfo *FI; MachineModuleInfo *MMI; const TargetInstrInfo *TII; - + void FindSafePoints(MachineFunction &MF); void VisitCallPoint(MachineBasicBlock::iterator MI); - MCSymbol *InsertLabel(MachineBasicBlock &MBB, + MCSymbol *InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL) const; - + void FindStackOffsets(MachineFunction &MF); - + public: static char ID; - + MachineCodeAnalysis(); const char *getPassName() const; void getAnalysisUsage(AnalysisUsage &AU) const; - + bool runOnMachineFunction(MachineFunction &MF); }; - + } // ----------------------------------------------------------------------------- @@ -105,12 +105,12 @@ GCStrategy::~GCStrategy() { for (iterator I = begin(), E = end(); I != E; ++I) delete *I; - + Functions.clear(); } - + bool GCStrategy::initializeCustomLowering(Module &M) { return false; } - + bool GCStrategy::performCustomLowering(Function &F) { dbgs() << "gc " << getName() << " must override performCustomLowering.\n"; llvm_unreachable(0); @@ -139,7 +139,7 @@ FunctionPass *llvm::createGCLoweringPass() { return new LowerIntrinsics(); } - + char LowerIntrinsics::ID = 0; LowerIntrinsics::LowerIntrinsics() @@ -150,7 +150,7 @@ const char *LowerIntrinsics::getPassName() const { return "Lower Garbage Collection Instructions"; } - + void LowerIntrinsics::getAnalysisUsage(AnalysisUsage &AU) const { FunctionPass::getAnalysisUsage(AU); AU.addRequired(); @@ -168,22 +168,22 @@ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) if (!I->isDeclaration() && I->hasGC()) MI->getFunctionInfo(*I); // Instantiate the GC strategy. - + bool MadeChange = false; for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I) if (NeedsCustomLoweringPass(**I)) if ((*I)->initializeCustomLowering(M)) MadeChange = true; - + return MadeChange; } -bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots, +bool LowerIntrinsics::InsertRootInitializers(Function &F, AllocaInst **Roots, unsigned Count) { // Scroll past alloca instructions. BasicBlock::iterator IP = F.getEntryBlock().begin(); while (isa(IP)) ++IP; - + // Search for initializers in the initial BB. SmallPtrSet InitedRoots; for (; !CouldBecomeSafePoint(IP); ++IP) @@ -191,10 +191,10 @@ if (AllocaInst *AI = dyn_cast(SI->getOperand(1)->stripPointerCasts())) InitedRoots.insert(AI); - + // Add root initializers. bool MadeChange = false; - + for (AllocaInst **I = Roots, **E = Roots + Count; I != E; ++I) if (!InitedRoots.count(*I)) { StoreInst* SI = new StoreInst(ConstantPointerNull::get(cast( @@ -203,7 +203,7 @@ SI->insertAfter(*I); MadeChange = true; } - + return MadeChange; } @@ -227,26 +227,26 @@ bool LowerIntrinsics::CouldBecomeSafePoint(Instruction *I) { // The natural definition of instructions which could introduce safe points // are: - // + // // - call, invoke (AfterCall, BeforeCall) // - phis (Loops) // - invoke, ret, unwind (Exit) - // + // // However, instructions as seemingly inoccuous as arithmetic can become // libcalls upon lowering (e.g., div i64 on a 32-bit platform), so instead // it is necessary to take a conservative approach. - + if (isa(I) || isa(I) || isa(I) || isa(I)) return false; - + // llvm.gcroot is safe because it doesn't do anything at runtime. if (CallInst *CI = dyn_cast(I)) if (Function *F = CI->getCalledFunction()) if (unsigned IID = F->getIntrinsicID()) if (IID == Intrinsic::gcroot) return false; - + return true; } @@ -256,15 +256,15 @@ // Quick exit for functions that do not use GC. if (!F.hasGC()) return false; - + GCFunctionInfo &FI = getAnalysis().getFunctionInfo(F); GCStrategy &S = FI.getStrategy(); - + bool MadeChange = false; - + if (NeedsDefaultLoweringPass(S)) MadeChange |= PerformDefaultLowering(F, S); - + bool UseCustomLoweringPass = NeedsCustomLoweringPass(S); if (UseCustomLoweringPass) MadeChange |= S.performCustomLowering(F); @@ -282,9 +282,9 @@ bool LowerWr = !S.customWriteBarrier(); bool LowerRd = !S.customReadBarrier(); bool InitRoots = S.initializeRoots(); - + SmallVector Roots; - + bool MadeChange = false; for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { for (BasicBlock::iterator II = BB->begin(), E = BB->end(); II != E;) { @@ -320,15 +320,15 @@ default: continue; } - + MadeChange = true; } } } - + if (Roots.size()) MadeChange |= InsertRootInitializers(F, Roots.begin(), Roots.size()); - + return MadeChange; } @@ -354,7 +354,7 @@ AU.addRequired(); } -MCSymbol *MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, +MCSymbol *MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL) const { MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol(); @@ -365,14 +365,14 @@ void MachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) { // Find the return address (next instruction), too, so as to bracket the call // instruction. - MachineBasicBlock::iterator RAI = CI; - ++RAI; - + MachineBasicBlock::iterator RAI = CI; + ++RAI; + if (FI->getStrategy().needsSafePoint(GC::PreCall)) { MCSymbol* Label = InsertLabel(*CI->getParent(), CI, CI->getDebugLoc()); FI->addSafePoint(GC::PreCall, Label, CI->getDebugLoc()); } - + if (FI->getStrategy().needsSafePoint(GC::PostCall)) { MCSymbol* Label = InsertLabel(*CI->getParent(), RAI, CI->getDebugLoc()); FI->addSafePoint(GC::PostCall, Label, CI->getDebugLoc()); @@ -391,7 +391,7 @@ void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) { const TargetFrameLowering *TFI = TM->getFrameLowering(); assert(TFI && "TargetRegisterInfo not available!"); - + for (GCFunctionInfo::roots_iterator RI = FI->roots_begin(), RE = FI->roots_end(); RI != RE; ++RI) RI->StackOffset = TFI->getFrameIndexOffset(MF, RI->Num); @@ -401,15 +401,15 @@ // Quick exit for functions that do not use GC. if (!MF.getFunction()->hasGC()) return false; - + FI = &getAnalysis().getFunctionInfo(*MF.getFunction()); if (!FI->getStrategy().needsSafePoints()) return false; - + TM = &MF.getTarget(); MMI = &getAnalysis(); TII = TM->getInstrInfo(); - + // Find the size of the stack frame. FI->setFrameSize(MF.getFrameInfo()->getStackSize()); @@ -419,9 +419,9 @@ } else { FindSafePoints(MF); } - + // Find the stack offsets for all roots. FindStackOffsets(MF); - + return false; } Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Wed Feb 8 15:22:43 2012 @@ -50,7 +50,7 @@ } virtual bool runOnMachineFunction(MachineFunction &MF); - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); @@ -177,7 +177,7 @@ SeenDef = true; } if (SeenDef) - // See a def of Reg (or an alias) before encountering any use, it's + // See a def of Reg (or an alias) before encountering any use, it's // trivially dead. return true; Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Wed Feb 8 15:22:43 2012 @@ -33,7 +33,7 @@ class MachineCopyPropagation : public MachineFunctionPass { const TargetRegisterInfo *TRI; BitVector ReservedRegs; - + public: static char ID; // Pass identification, replacement for typeid MachineCopyPropagation() : MachineFunctionPass(ID) { Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSink.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSink.cpp Wed Feb 8 15:22:43 2012 @@ -32,7 +32,7 @@ #include "llvm/Support/raw_ostream.h" using namespace llvm; -static cl::opt +static cl::opt SplitEdges("machine-sink-split", cl::desc("Split critical edges during machine sinking"), cl::init(true), cl::Hidden); @@ -92,7 +92,7 @@ bool &BreakPHIEdge, bool &LocalUse) const; MachineBasicBlock *FindSuccToSinkTo(MachineInstr *MI, MachineBasicBlock *MBB, bool &BreakPHIEdge); - bool isProfitableToSinkTo(unsigned Reg, MachineInstr *MI, + bool isProfitableToSinkTo(unsigned Reg, MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *SuccToSinkTo); @@ -384,9 +384,9 @@ return MI->isInsertSubreg() || MI->isSubregToReg() || MI->isRegSequence(); } -/// collectDebgValues - Scan instructions following MI and collect any +/// collectDebgValues - Scan instructions following MI and collect any /// matching DBG_VALUEs. -static void collectDebugValues(MachineInstr *MI, +static void collectDebugValues(MachineInstr *MI, SmallVector & DbgValues) { DbgValues.clear(); if (!MI->getOperand(0).isReg()) @@ -421,7 +421,7 @@ } /// isProfitableToSinkTo - Return true if it is profitable to sink MI. -bool MachineSinking::isProfitableToSinkTo(unsigned Reg, MachineInstr *MI, +bool MachineSinking::isProfitableToSinkTo(unsigned Reg, MachineInstr *MI, MachineBasicBlock *MBB, MachineBasicBlock *SuccToSinkTo) { assert (MI && "Invalid MachineInstr!"); Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original) +++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Wed Feb 8 15:22:43 2012 @@ -39,7 +39,7 @@ // => // v1 = bitcast v0 // = v0 -// +// //===----------------------------------------------------------------------===// #define DEBUG_TYPE "peephole-opt" @@ -124,7 +124,7 @@ /// source, and if the source value is preserved as a sub-register of the /// result, then replace all reachable uses of the source with the subreg of the /// result. -/// +/// /// Do not generate an EXTRACT that is used only in a debug use, as this changes /// the code. Since this code does not currently share EXTRACTs, just ignore all /// debug uses. @@ -134,7 +134,7 @@ unsigned SrcReg, DstReg, SubIdx; if (!TII->isCoalescableExtInstr(*MI, SrcReg, DstReg, SubIdx)) return false; - + if (TargetRegisterInfo::isPhysicalRegister(DstReg) || TargetRegisterInfo::isPhysicalRegister(SrcReg)) return false; @@ -363,7 +363,7 @@ ImmDefRegs.insert(Reg); return true; } - + return false; } @@ -395,7 +395,7 @@ bool PeepholeOptimizer::runOnMachineFunction(MachineFunction &MF) { if (DisablePeephole) return false; - + TM = &MF.getTarget(); TII = TM->getInstrInfo(); MRI = &MF.getRegInfo(); @@ -408,7 +408,7 @@ DenseMap ImmDefMIs; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { MachineBasicBlock *MBB = &*I; - + bool SeenMoveImm = false; LocalMIs.clear(); ImmDefRegs.clear(); @@ -435,7 +435,7 @@ Changed = true; MII = First ? I->begin() : llvm::next(PMII); continue; - } + } } else if (MI->isCompare()) { if (OptimizeCmpInstr(MI, MBB)) { // MI is deleted. Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=150094&r1=150093&r2=150094&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed Feb 8 15:22:43 2012 @@ -90,14 +90,14 @@ MachineFunctionPass(ID), ColorWithRegs(RegColor), NextColor(-1) { initializeStackSlotColoringPass(*PassRegistry::getPassRegistry()); } - + virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); AU.addRequired(); - AU.addPreserved(); + AU.addPreserved(); AU.addRequired(); AU.addPreserved(); AU.addPreservedID(MachineDominatorsID); @@ -372,33 +372,33 @@ I != E; ++I) { if (DCELimit != -1 && (int)NumDead >= DCELimit) break; - + MachineBasicBlock::iterator NextMI = llvm::next(I); if (NextMI == MBB->end()) continue; - + int FirstSS, SecondSS; unsigned LoadReg = 0; unsigned StoreReg = 0; if (!(LoadReg = TII->isLoadFromStackSlot(I, FirstSS))) continue; if (!(StoreReg = TII->isStoreToStackSlot(NextMI, SecondSS))) continue; if (FirstSS != SecondSS || LoadReg != StoreReg || FirstSS == -1) continue; - + ++NumDead; changed = true; - + if (NextMI->findRegisterUseOperandIdx(LoadReg, true, 0) != -1) { ++NumDead; toErase.push_back(I); } - + toErase.push_back(NextMI); ++I; } - + for (SmallVector::iterator I = toErase.begin(), E = toErase.end(); I != E; ++I) (*I)->eraseFromParent(); - + return changed; } @@ -406,7 +406,7 @@ bool StackSlotColoring::runOnMachineFunction(MachineFunction &MF) { DEBUG({ dbgs() << "********** Stack Slot Coloring **********\n" - << "********** Function: " + << "********** Function: " << MF.getFunction()->getName() << '\n'; }); From atrick at apple.com Wed Feb 8 15:22:49 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:49 -0000 Subject: [llvm-commits] [llvm] r150095 - in /llvm/trunk: include/llvm/CodeGen/Passes.h include/llvm/InitializePasses.h lib/CodeGen/BranchFolding.cpp lib/CodeGen/CodeGen.cpp lib/CodeGen/Passes.cpp lib/Target/PTX/PTXTargetMachine.cpp lib/Target/PowerPC/PPCTargetMachine.cpp Message-ID: <20120208212249.1D5322A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:48 2012 New Revision: 150095 URL: http://llvm.org/viewvc/llvm-project?rev=150095&view=rev Log: Move pass configuration out of pass constructors: BranchFolderPass Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/lib/CodeGen/BranchFolding.cpp llvm/trunk/lib/CodeGen/CodeGen.cpp llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:48 2012 @@ -42,9 +42,13 @@ bool Initialized; // Flagged after all passes are configured. // Target Pass Options + // Targets provide a default setting, user flags override. // bool DisableVerify; + /// Default setting for -enable-tail-merge on this target. + bool EnableTailMerge; + public: TargetPassConfig(TargetMachine *tm, PassManagerBase &pm); // Dummy constructor. @@ -67,7 +71,10 @@ CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } - void setDisableVerify(bool disable) { DisableVerify = disable; } + void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } + + bool getEnableTailMerge() const { return EnableTailMerge; } + void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } /// Add common target configurable passes that perform LLVM IR to IR /// transforms following machine independent optimization. @@ -118,10 +125,6 @@ return false; } - /// getEnableTailMergeDefault - the default setting for -enable-tail-merge - /// on this target. User flag overrides. - virtual bool getEnableTailMergeDefault() const { return true; } - /// addPreSched2 - This method may be implemented by targets that want to /// run passes after prolog-epilog insertion and before the second instruction /// scheduling pass. This should return true if -print-machineinstrs should @@ -274,7 +277,7 @@ /// optimizations to delete branches to branches, eliminate branches to /// successor blocks (creating fall throughs), and eliminating branches over /// branches. - FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge); + extern char &BranchFolderPassID; /// TailDuplicate Pass - Duplicate blocks with unconditional branches /// into tails of their predecessors. Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Wed Feb 8 15:22:48 2012 @@ -71,6 +71,7 @@ void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockFrequencyInfoPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); +void initializeBranchFolderPassPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); void initializeCFGOnlyPrinterPass(PassRegistry&); Modified: llvm/trunk/lib/CodeGen/BranchFolding.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/BranchFolding.cpp?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/BranchFolding.cpp (original) +++ llvm/trunk/lib/CodeGen/BranchFolding.cpp Wed Feb 8 15:22:48 2012 @@ -61,29 +61,33 @@ namespace { /// BranchFolderPass - Wrap branch folder in a machine function pass. - class BranchFolderPass : public MachineFunctionPass, - public BranchFolder { + class BranchFolderPass : public MachineFunctionPass { public: static char ID; - explicit BranchFolderPass(bool defaultEnableTailMerge) - : MachineFunctionPass(ID), BranchFolder(defaultEnableTailMerge, true) {} + explicit BranchFolderPass(): MachineFunctionPass(ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Control Flow Optimizer"; } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } }; } char BranchFolderPass::ID = 0; +char &llvm::BranchFolderPassID = BranchFolderPass::ID; -FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { - return new BranchFolderPass(DefaultEnableTailMerge); -} +INITIALIZE_PASS(BranchFolderPass, "branch-folder", + "Control Flow Optimizer", false, false) bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { - return OptimizeFunction(MF, - MF.getTarget().getInstrInfo(), - MF.getTarget().getRegisterInfo(), - getAnalysisIfAvailable()); + TargetPassConfig *PassConfig = &getAnalysis(); + BranchFolder Folder(PassConfig->getEnableTailMerge(), /*CommonHoist=*/true); + return Folder.OptimizeFunction(MF, + MF.getTarget().getInstrInfo(), + MF.getTarget().getRegisterInfo(), + getAnalysisIfAvailable()); } Modified: llvm/trunk/lib/CodeGen/CodeGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodeGen.cpp (original) +++ llvm/trunk/lib/CodeGen/CodeGen.cpp Wed Feb 8 15:22:48 2012 @@ -19,6 +19,7 @@ /// initializeCodeGen - Initialize all passes linked into the CodeGen library. void llvm::initializeCodeGen(PassRegistry &Registry) { + initializeBranchFolderPassPass(Registry); initializeCalculateSpillWeightsPass(Registry); initializeDeadMachineInstructionElimPass(Registry); initializeGCModuleInfoPass(Registry); Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:48 2012 @@ -83,6 +83,8 @@ // Out of line virtual method. TargetPassConfig::~TargetPassConfig() {} +// Out of line constructor provides default values for pass options and +// registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) : ImmutablePass(ID), TM(tm), PM(pm), Initialized(false), DisableVerify(false), @@ -257,7 +259,7 @@ // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + addPass(BranchFolderPassID); printNoVerify("After BranchFolding"); } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:22:48 2012 @@ -359,7 +359,7 @@ // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + addPass(BranchFolderPassID); printNoVerify("After BranchFolding"); } Modified: llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp?rev=150095&r1=150094&r2=150095&view=diff ============================================================================== --- llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PowerPC/PPCTargetMachine.cpp Wed Feb 8 15:22:48 2012 @@ -78,13 +78,18 @@ } virtual bool addInstSelector(); - virtual bool getEnableTailMergeDefault() const; virtual bool addPreEmitPass(); }; } // namespace TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) { - return new PPCPassConfig(this, PM); + TargetPassConfig *PassConfig = new PPCPassConfig(this, PM); + + // Override this for PowerPC. Tail merging happily breaks up instruction issue + // groups, which typically degrades performance. + PassConfig->setEnableTailMerge(false); + + return PassConfig; } bool PPCPassConfig::addInstSelector() { @@ -93,10 +98,6 @@ return false; } -/// Override this for PowerPC. Tail merging happily breaks up instruction issue -/// groups, which typically degrades performance. -bool PPCPassConfig::getEnableTailMergeDefault() const { return false; } - bool PPCPassConfig::addPreEmitPass() { // Must run branch selection immediately preceding the asm printer. PM.add(createPPCBranchSelectionPass()); From atrick at apple.com Wed Feb 8 15:22:53 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:53 -0000 Subject: [llvm-commits] [llvm] r150096 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/Passes.cpp lib/CodeGen/PostRASchedulerList.cpp lib/Target/PTX/PTXTargetMachine.cpp Message-ID: <20120208212253.844372A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:53 2012 New Revision: 150096 URL: http://llvm.org/viewvc/llvm-project?rev=150096&view=rev Log: Move pass configuration out of pass constructors: PostRAScheduler. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150096&r1=150095&r2=150096&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:53 2012 @@ -271,7 +271,7 @@ /// createPostRAScheduler - This pass performs post register allocation /// scheduling. - FunctionPass *createPostRAScheduler(CodeGenOpt::Level OptLevel); + FunctionPass *createPostRAScheduler(); /// BranchFolding Pass - This pass performs machine code CFG based /// optimizations to delete branches to branches, eliminate branches to Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150096&r1=150095&r2=150096&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:53 2012 @@ -285,7 +285,7 @@ // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { - PM.add(createPostRAScheduler(getOptLevel())); + PM.add(createPostRAScheduler()); printNoVerify("After PostRAScheduler"); } Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=150096&r1=150095&r2=150096&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Feb 8 15:22:53 2012 @@ -82,16 +82,15 @@ AliasAnalysis *AA; const TargetInstrInfo *TII; RegisterClassInfo RegClassInfo; - CodeGenOpt::Level OptLevel; public: static char ID; - PostRAScheduler(CodeGenOpt::Level ol) : - MachineFunctionPass(ID), OptLevel(ol) {} + PostRAScheduler() : MachineFunctionPass(ID) {} void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addRequired(); + AU.addRequired(); AU.addRequired(); AU.addPreserved(); AU.addRequired(); @@ -209,6 +208,8 @@ MachineLoopInfo &MLI = getAnalysis(); MachineDominatorTree &MDT = getAnalysis(); AliasAnalysis *AA = &getAnalysis(); + TargetPassConfig *PassConfig = &getAnalysis(); + RegClassInfo.runOnMachineFunction(Fn); // Check for explicit enable/disable of post-ra scheduling. @@ -222,7 +223,8 @@ // Check that post-RA scheduling is enabled for this target. // This may upgrade the AntiDepMode. const TargetSubtargetInfo &ST = Fn.getTarget().getSubtarget(); - if (!ST.enablePostRAScheduler(OptLevel, AntiDepMode, CriticalPathRCs)) + if (!ST.enablePostRAScheduler(PassConfig->getOptLevel(), AntiDepMode, + CriticalPathRCs)) return false; } @@ -710,6 +712,6 @@ // Public Constructor Functions //===----------------------------------------------------------------------===// -FunctionPass *llvm::createPostRAScheduler(CodeGenOpt::Level OptLevel) { - return new PostRAScheduler(OptLevel); +FunctionPass *llvm::createPostRAScheduler() { + return new PostRAScheduler(); } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150096&r1=150095&r2=150096&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:22:53 2012 @@ -353,7 +353,7 @@ // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createPostRAScheduler(getOptLevel())); + PM.add(createPostRAScheduler()); printAndVerify("After PostRAScheduler"); } From atrick at apple.com Wed Feb 8 15:22:58 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:22:58 -0000 Subject: [llvm-commits] [llvm] r150097 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/Passes.cpp lib/CodeGen/StackSlotColoring.cpp lib/Target/PTX/PTXTargetMachine.cpp Message-ID: <20120208212258.171662A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:22:57 2012 New Revision: 150097 URL: http://llvm.org/viewvc/llvm-project?rev=150097&view=rev Log: Move pass configuration out of pass constructors: StackSlotColoring. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/CodeGen/StackSlotColoring.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150097&r1=150096&r2=150097&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:22:57 2012 @@ -342,7 +342,7 @@ FunctionPass *createOptimizePHIsPass(); /// createStackSlotColoringPass - This pass performs stack slot coloring. - FunctionPass *createStackSlotColoringPass(bool); + FunctionPass *createStackSlotColoringPass(); /// createStackProtectorPass - This pass adds stack protectors to functions. FunctionPass *createStackProtectorPass(const TargetLowering *tli); Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150097&r1=150096&r2=150097&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:22:57 2012 @@ -240,7 +240,7 @@ // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. if (!DisableSSC) - PM.add(createStackSlotColoringPass(false)); + PM.add(createStackSlotColoringPass()); // Run post-ra machine LICM to hoist reloads / remats. if (!DisablePostRAMachineLICM) Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=150097&r1=150096&r2=150097&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed Feb 8 15:22:57 2012 @@ -132,8 +132,8 @@ INITIALIZE_PASS_END(StackSlotColoring, "stack-slot-coloring", "Stack Slot Coloring", false, false) -FunctionPass *llvm::createStackSlotColoringPass(bool RegColor) { - return new StackSlotColoring(RegColor); +FunctionPass *llvm::createStackSlotColoringPass() { + return new StackSlotColoring(/*RegColor=*/false); } namespace { Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150097&r1=150096&r2=150097&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:22:57 2012 @@ -326,7 +326,7 @@ if (getOptLevel() != CodeGenOpt::None) { // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. - PM.add(createStackSlotColoringPass(false)); + PM.add(createStackSlotColoringPass()); // FIXME: Post-RA LICM has asserts that fire on virtual registers. // Run post-ra machine LICM to hoist reloads / remats. From atrick at apple.com Wed Feb 8 15:23:00 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:23:00 -0000 Subject: [llvm-commits] [llvm] r150098 - /llvm/trunk/lib/CodeGen/MachineLICM.cpp Message-ID: <20120208212300.988B22A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:23:00 2012 New Revision: 150098 URL: http://llvm.org/viewvc/llvm-project?rev=150098&view=rev Log: whitespace Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=150098&r1=150097&r2=150098&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Feb 8 15:23:00 2012 @@ -182,7 +182,7 @@ /// invariant. I.e., all virtual register operands are defined outside of /// the loop, physical registers aren't accessed (explicitly or implicitly), /// and the instruction is hoistable. - /// + /// bool IsLoopInvariantInst(MachineInstr &I); /// HasAnyPHIUse - Return true if the specified register is used by any @@ -586,7 +586,7 @@ MachineBasicBlock *MBB = MI->getParent(); Preheader->splice(Preheader->getFirstTerminator(), MBB, MI); - // Add register to livein list to all the BBs in the current loop since a + // Add register to livein list to all the BBs in the current loop since a // loop invariant must be kept live throughout the whole loop. This is // important to ensure later passes do not scavenge the def register. AddToLiveIns(Def); @@ -600,7 +600,7 @@ bool MachineLICM::IsGuaranteedToExecute(MachineBasicBlock *BB) { if (SpeculationState != SpeculateUnknown) return SpeculationState == SpeculateFalse; - + if (BB != CurLoop->getHeader()) { // Check loop exiting blocks. SmallVector CurrentLoopExitingBlocks; @@ -758,7 +758,7 @@ RCCost = TLI->getRepRegClassCostFor(VT); } } - + /// InitRegPressure - Find all virtual register references that are liveout of /// the preheader to initialize the starting "register pressure". Note this /// does not count live through (livein but not used) registers. @@ -842,16 +842,16 @@ } } -/// isLoadFromGOTOrConstantPool - Return true if this machine instruction +/// isLoadFromGOTOrConstantPool - Return true if this machine instruction /// loads from global offset table or constant pool. static bool isLoadFromGOTOrConstantPool(MachineInstr &MI) { assert (MI.mayLoad() && "Expected MI that loads!"); for (MachineInstr::mmo_iterator I = MI.memoperands_begin(), - E = MI.memoperands_end(); I != E; ++I) { + E = MI.memoperands_end(); I != E; ++I) { if (const Value *V = (*I)->getValue()) { if (const PseudoSourceValue *PSV = dyn_cast(V)) if (PSV == PSV->getGOT() || PSV == PSV->getConstantPool()) - return true; + return true; } } return false; @@ -872,7 +872,7 @@ // from constant memory are not safe to speculate all the time, for example // indexed load from a jump table. // Stores and side effects are already checked by isSafeToMove. - if (I.mayLoad() && !isLoadFromGOTOrConstantPool(I) && + if (I.mayLoad() && !isLoadFromGOTOrConstantPool(I) && !IsGuaranteedToExecute(I.getParent())) return false; @@ -883,7 +883,7 @@ /// invariant. I.e., all virtual register operands are defined outside of the /// loop, physical registers aren't accessed explicitly, and there are no side /// effects that aren't captured by the operands or other flags. -/// +/// bool MachineLICM::IsLoopInvariantInst(MachineInstr &I) { if (!IsLICMCandidate(I)) return false; @@ -1021,7 +1021,7 @@ bool MachineLICM::CanCauseHighRegPressure(DenseMap &Cost) { for (DenseMap::iterator CI = Cost.begin(), CE = Cost.end(); CI != CE; ++CI) { - if (CI->second <= 0) + if (CI->second <= 0) continue; unsigned RCId = CI->first; @@ -1102,7 +1102,7 @@ return false; } else { // Estimate register pressure to determine whether to LICM the instruction. - // In low register pressure situation, we can be more aggressive about + // In low register pressure situation, we can be more aggressive about // hoisting. Also, favors hoisting long latency instructions even in // moderately high pressure situation. // FIXME: If there are long latency loop-invariant instructions inside the From atrick at apple.com Wed Feb 8 15:23:04 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:23:04 -0000 Subject: [llvm-commits] [llvm] r150099 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/MachineLICM.cpp lib/CodeGen/Passes.cpp Message-ID: <20120208212304.3A0162A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:23:03 2012 New Revision: 150099 URL: http://llvm.org/viewvc/llvm-project?rev=150099&view=rev Log: Move pass configuration out of pass constructors: MachineLICM. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/CodeGen/Passes.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150099&r1=150098&r2=150099&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:23:03 2012 @@ -93,6 +93,7 @@ /// Add the complete, standard set of LLVM CodeGen passes. /// Fully developed targets will not generally override this. virtual void addMachinePasses(); + protected: // Helper to verify the analysis is really immutable. void setOpt(bool &Opt, bool Val); @@ -323,7 +324,7 @@ /// createMachineLICMPass - This pass performs LICM on machine instructions. /// - FunctionPass *createMachineLICMPass(bool PreRegAlloc = true); + FunctionPass *createMachineLICMPass(); /// createMachineSinkingPass - This pass performs sinking on machine /// instructions. Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=150099&r1=150098&r2=150099&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Feb 8 15:23:03 2012 @@ -60,8 +60,6 @@ namespace { class MachineLICM : public MachineFunctionPass { - bool PreRegAlloc; - const TargetMachine *TM; const TargetInstrInfo *TII; const TargetLowering *TLI; @@ -69,6 +67,7 @@ const MachineFrameInfo *MFI; MachineRegisterInfo *MRI; const InstrItineraryData *InstrItins; + bool PreRegAlloc; // Various analyses that we use... AliasAnalysis *AA; // Alias analysis info. @@ -298,8 +297,8 @@ INITIALIZE_PASS_END(MachineLICM, "machinelicm", "Machine Loop Invariant Code Motion", false, false) -FunctionPass *llvm::createMachineLICMPass(bool PreRegAlloc) { - return new MachineLICM(PreRegAlloc); +FunctionPass *llvm::createMachineLICMPass() { + return new MachineLICM(); } /// LoopIsOuterMostWithPredecessor - Test if the given loop is the outer-most @@ -332,6 +331,8 @@ MRI = &MF.getRegInfo(); InstrItins = TM->getInstrItineraryData(); + PreRegAlloc = MRI->isSSA(); + if (PreRegAlloc) { // Estimate register pressure during pre-regalloc pass. unsigned NumRC = TRI->getNumRegClasses(); Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150099&r1=150098&r2=150099&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:23:03 2012 @@ -244,7 +244,7 @@ // Run post-ra machine LICM to hoist reloads / remats. if (!DisablePostRAMachineLICM) - PM.add(createMachineLICMPass(false)); + PM.add(createMachineLICMPass()); printAndVerify("After StackSlotColoring and postra Machine LICM"); } From atrick at apple.com Wed Feb 8 15:23:13 2012 From: atrick at apple.com (Andrew Trick) Date: Wed, 08 Feb 2012 21:23:13 -0000 Subject: [llvm-commits] [llvm] r150100 - in /llvm/trunk: include/llvm/ include/llvm/CodeGen/ lib/CodeGen/ lib/Target/ARM/ lib/Target/Hexagon/ lib/Target/PTX/ Message-ID: <20120208212314.76BF72A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 15:23:13 2012 New Revision: 150100 URL: http://llvm.org/viewvc/llvm-project?rev=150100&view=rev Log: Codegen pass definition cleanup. No functionality. Moving toward a uniform style of pass definition to allow easier target configuration. Globally declare Pass ID. Globally declare pass initializer. Use INITIALIZE_PASS consistently. Add a call to the initializer from CodeGen.cpp. Remove redundant "createPass" functions and "getPassName" methods. While cleaning up declarations, cleaned up comments (sorry for large diff). Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/InitializePasses.h llvm/trunk/lib/CodeGen/CodeGen.cpp llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp llvm/trunk/lib/CodeGen/ExpandISelPseudos.cpp llvm/trunk/lib/CodeGen/ExpandPostRAPseudos.cpp llvm/trunk/lib/CodeGen/GCStrategy.cpp llvm/trunk/lib/CodeGen/IfConversion.cpp llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp llvm/trunk/lib/CodeGen/MachineCSE.cpp llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp llvm/trunk/lib/CodeGen/MachineInstrBundle.cpp llvm/trunk/lib/CodeGen/MachineLICM.cpp llvm/trunk/lib/CodeGen/MachineSink.cpp llvm/trunk/lib/CodeGen/OptimizePHIs.cpp llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp llvm/trunk/lib/CodeGen/PrologEpilogInserter.h llvm/trunk/lib/CodeGen/StackSlotColoring.cpp llvm/trunk/lib/CodeGen/TailDuplication.cpp llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Modified: llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h (original) +++ llvm/trunk/include/llvm/CodeGen/LinkAllCodegenComponents.h Wed Feb 8 15:23:13 2012 @@ -31,8 +31,6 @@ if (std::getenv("bar") != (char*) -1) return; - (void) llvm::createDeadMachineInstructionElimPass(); - (void) llvm::createFastRegisterAllocator(); (void) llvm::createBasicRegisterAllocator(); (void) llvm::createGreedyRegisterAllocator(); Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 15:23:13 2012 @@ -175,31 +175,25 @@ createMachineFunctionPrinterPass(raw_ostream &OS, const std::string &Banner =""); - /// MachineLoopInfo pass - This pass is a loop analysis pass. - /// + /// MachineLoopInfo - This pass is a loop analysis pass. extern char &MachineLoopInfoID; - /// MachineLoopRanges pass - This pass is an on-demand loop coverage - /// analysis pass. - /// + /// MachineLoopRanges - This pass is an on-demand loop coverage analysis. extern char &MachineLoopRangesID; - /// MachineDominators pass - This pass is a machine dominators analysis pass. - /// + /// MachineDominators - This pass is a machine dominators analysis pass. extern char &MachineDominatorsID; /// EdgeBundles analysis - Bundle machine CFG edges. - /// extern char &EdgeBundlesID; - /// PHIElimination pass - This pass eliminates machine instruction PHI nodes + /// PHIElimination - This pass eliminates machine instruction PHI nodes /// by inserting copy instructions. This destroys SSA information, but is the /// desired input for some register allocators. This pass is "required" by /// these register allocator like this: AU.addRequiredID(PHIEliminationID); - /// extern char &PHIEliminationID; - /// StrongPHIElimination pass - This pass eliminates machine instruction PHI + /// StrongPHIElimination - This pass eliminates machine instruction PHI /// nodes by inserting copy instructions. This destroys SSA information, but /// is the desired input for some register allocators. This pass is /// "required" by these register allocator like this: @@ -210,30 +204,27 @@ /// LiveStacks pass. An analysis keeping track of the liveness of stack slots. extern char &LiveStacksID; - /// TwoAddressInstruction pass - This pass reduces two-address instructions to + /// TwoAddressInstruction - This pass reduces two-address instructions to /// use two operands. This destroys SSA information but it is desired by /// register allocators. extern char &TwoAddressInstructionPassID; - /// RegisteCoalescer pass - This pass merges live ranges to eliminate copies. + /// RegisteCoalescer - This pass merges live ranges to eliminate copies. extern char &RegisterCoalescerPassID; - /// MachineScheduler pass - This pass schedules machine instructions. + /// MachineScheduler - This pass schedules machine instructions. extern char &MachineSchedulerID; /// SpillPlacement analysis. Suggest optimal placement of spill code between /// basic blocks. - /// extern char &SpillPlacementID; - /// UnreachableMachineBlockElimination pass - This pass removes unreachable + /// UnreachableMachineBlockElimination - This pass removes unreachable /// machine basic blocks. extern char &UnreachableMachineBlockElimID; - /// DeadMachineInstructionElim pass - This pass removes dead machine - /// instructions. - /// - FunctionPass *createDeadMachineInstructionElimPass(); + /// DeadMachineInstructionElim - This pass removes dead machine instructions. + extern char &DeadMachineInstructionElimID; /// Creates a register allocator as the user specified on the command line, or /// picks one that matches OptLevel. @@ -260,55 +251,54 @@ /// FunctionPass *createDefaultPBQPRegisterAllocator(); - /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code, + /// PrologEpilogCodeInserter - This pass inserts prolog and epilog code, /// and eliminates abstract frame references. - /// - FunctionPass *createPrologEpilogCodeInserter(); + extern char &PrologEpilogCodeInserterID; - /// ExpandPostRAPseudos Pass - This pass expands pseudo instructions after + /// ExpandPostRAPseudos - This pass expands pseudo instructions after /// register allocation. - /// - FunctionPass *createExpandPostRAPseudosPass(); + extern char &ExpandPostRAPseudosID; /// createPostRAScheduler - This pass performs post register allocation /// scheduling. - FunctionPass *createPostRAScheduler(); + extern char &PostRASchedulerID; - /// BranchFolding Pass - This pass performs machine code CFG based + /// BranchFolding - This pass performs machine code CFG based /// optimizations to delete branches to branches, eliminate branches to /// successor blocks (creating fall throughs), and eliminating branches over /// branches. extern char &BranchFolderPassID; - /// TailDuplicate Pass - Duplicate blocks with unconditional branches + /// TailDuplicate - Duplicate blocks with unconditional branches /// into tails of their predecessors. - FunctionPass *createTailDuplicatePass(); + extern char &TailDuplicateID; - /// IfConverter Pass - This pass performs machine code if conversion. - FunctionPass *createIfConverterPass(); + /// IfConverter - This pass performs machine code if conversion. + extern char &IfConverterID; - /// MachineBlockPlacement Pass - This pass places basic blocks based on branch + /// MachineBlockPlacement - This pass places basic blocks based on branch /// probabilities. - FunctionPass *createMachineBlockPlacementPass(); + extern char &MachineBlockPlacementID; - /// MachineBlockPlacementStats Pass - This pass collects statistics about the + /// MachineBlockPlacementStats - This pass collects statistics about the /// basic block placement using branch probabilities and block frequency /// information. - FunctionPass *createMachineBlockPlacementStatsPass(); + extern char &MachineBlockPlacementStatsID; - /// Code Placement Pass - This pass optimize code placement and aligns loop + /// Code Placement - This pass optimize code placement and aligns loop /// headers to target specific alignment boundary. - FunctionPass *createCodePlacementOptPass(); + extern char &CodePlacementOptID; - /// IntrinsicLowering Pass - Performs target-independent LLVM IR - /// transformations for highly portable strategies. + /// GCLowering Pass - Performs target-independent LLVM IR transformations for + /// highly portable strategies. + /// FunctionPass *createGCLoweringPass(); - /// MachineCodeAnalysis Pass - Target-independent pass to mark safe points in - /// machine code. Must be added very late during code generation, just prior - /// to output, and importantly after all CFG transformations (such as branch - /// folding). - FunctionPass *createGCMachineCodeAnalysisPass(); + /// GCMachineCodeAnalysis - Target-independent pass to mark safe points + /// in machine code. Must be added very late during code generation, just + /// prior to output, and importantly after all CFG transformations (such as + /// branch folding). + extern char &GCMachineCodeAnalysisID; /// Deleter Pass - Releases GC metadata. /// @@ -318,38 +308,37 @@ /// FunctionPass *createGCInfoPrinter(raw_ostream &OS); - /// createMachineCSEPass - This pass performs global CSE on machine - /// instructions. - FunctionPass *createMachineCSEPass(); + /// MachineCSE - This pass performs global CSE on machine instructions. + extern char &MachineCSEID; - /// createMachineLICMPass - This pass performs LICM on machine instructions. - /// - FunctionPass *createMachineLICMPass(); + /// MachineLICM - This pass performs LICM on machine instructions. + extern char &MachineLICMID; - /// createMachineSinkingPass - This pass performs sinking on machine - /// instructions. - FunctionPass *createMachineSinkingPass(); + /// MachineSinking - This pass performs sinking on machine instructions. + extern char &MachineSinkingID; - /// createMachineCopyPropagationPass - This pass performs copy propagation on + /// MachineCopyPropagation - This pass performs copy propagation on /// machine instructions. - FunctionPass *createMachineCopyPropagationPass(); + extern char &MachineCopyPropagationID; - /// createPeepholeOptimizerPass - This pass performs peephole optimizations - + /// PeepholeOptimizer - This pass performs peephole optimizations - /// like extension and comparison eliminations. - FunctionPass *createPeepholeOptimizerPass(); + extern char &PeepholeOptimizerID; - /// createOptimizePHIsPass - This pass optimizes machine instruction PHIs + /// OptimizePHIs - This pass optimizes machine instruction PHIs /// to take advantage of opportunities created during DAG legalization. - FunctionPass *createOptimizePHIsPass(); + extern char &OptimizePHIsID; - /// createStackSlotColoringPass - This pass performs stack slot coloring. - FunctionPass *createStackSlotColoringPass(); + /// StackSlotColoring - This pass performs stack slot coloring. + extern char &StackSlotColoringID; /// createStackProtectorPass - This pass adds stack protectors to functions. + /// FunctionPass *createStackProtectorPass(const TargetLowering *tli); /// createMachineVerifierPass - This pass verifies cenerated machine code /// instructions for correctness. + /// FunctionPass *createMachineVerifierPass(const char *Banner = 0); /// createDwarfEHPass - This pass mulches exception handling code into a form @@ -358,18 +347,17 @@ /// createSjLjEHPass - This pass adapts exception handling code to use /// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow. + /// FunctionPass *createSjLjEHPass(const TargetLowering *tli); - /// createLocalStackSlotAllocationPass - This pass assigns local frame - /// indices to stack slots relative to one another and allocates - /// base registers to access them when it is estimated by the target to - /// be out of range of normal frame pointer or stack pointer index - /// addressing. - FunctionPass *createLocalStackSlotAllocationPass(); + /// LocalStackSlotAllocation - This pass assigns local frame indices to stack + /// slots relative to one another and allocates base registers to access them + /// when it is estimated by the target to be out of range of normal frame + /// pointer or stack pointer index addressing. + extern char &LocalStackSlotAllocationID; - /// createExpandISelPseudosPass - This pass expands pseudo-instructions. - /// - FunctionPass *createExpandISelPseudosPass(); + /// ExpandISelPseudos - This pass expands pseudo-instructions. + extern char &ExpandISelPseudosID; /// createExecutionDependencyFixPass - This pass fixes execution time /// problems with dependent instructions, such as switching execution @@ -379,14 +367,12 @@ /// FunctionPass *createExecutionDependencyFixPass(const TargetRegisterClass *RC); - /// createUnpackMachineBundles - This pass unpack machine instruction bundles. - /// - FunctionPass *createUnpackMachineBundlesPass(); + /// UnpackMachineBundles - This pass unpack machine instruction bundles. + extern char &UnpackMachineBundlesID; - /// createFinalizeMachineBundles - This pass finalize machine instruction + /// FinalizeMachineBundles - This pass finalize machine instruction /// bundles (created earlier, e.g. during pre-RA scheduling). - /// - FunctionPass *createFinalizeMachineBundlesPass(); + extern char &FinalizeMachineBundlesID; } // End llvm namespace Modified: llvm/trunk/include/llvm/InitializePasses.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/include/llvm/InitializePasses.h (original) +++ llvm/trunk/include/llvm/InitializePasses.h Wed Feb 8 15:23:13 2012 @@ -82,6 +82,7 @@ void initializeCalculateSpillWeightsPass(PassRegistry&); void initializeCallGraphAnalysisGroup(PassRegistry&); void initializeCodeGenPreparePass(PassRegistry&); +void initializeCodePlacementOptPass(PassRegistry&); void initializeConstantMergePass(PassRegistry&); void initializeConstantPropagationPass(PassRegistry&); void initializeMachineCopyPropagationPass(PassRegistry&); @@ -100,6 +101,7 @@ void initializeDominatorTreePass(PassRegistry&); void initializeEdgeBundlesPass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&); +void initializeExpandPostRAPass(PassRegistry&); void initializePathProfilerPass(PassRegistry&); void initializeGCOVProfilerPass(PassRegistry&); void initializeAddressSanitizerPass(PassRegistry&); @@ -107,6 +109,8 @@ void initializeExpandISelPseudosPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); +void initializeGCInfoDeleterPass(PassRegistry&); +void initializeGCMachineCodeAnalysisPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&); void initializeGVNPass(PassRegistry&); void initializeGlobalDCEPass(PassRegistry&); @@ -134,6 +138,7 @@ void initializeLiveVariablesPass(PassRegistry&); void initializeLoaderPassPass(PassRegistry&); void initializePathProfileLoaderPassPass(PassRegistry&); +void initializeLocalStackSlotPassPass(PassRegistry&); void initializeLoopDeletionPass(PassRegistry&); void initializeLoopDependenceAnalysisPass(PassRegistry&); void initializeLoopExtractorPass(PassRegistry&); @@ -188,6 +193,7 @@ void initializePostDomPrinterPass(PassRegistry&); void initializePostDomViewerPass(PassRegistry&); void initializePostDominatorTreePass(PassRegistry&); +void initializePostRASchedulerPass(PassRegistry&); void initializePreVerifierPass(PassRegistry&); void initializePrintDbgInfoPass(PassRegistry&); void initializePrintFunctionPassPass(PassRegistry&); @@ -229,6 +235,7 @@ void initializeStripSymbolsPass(PassRegistry&); void initializeStrongPHIEliminationPass(PassRegistry&); void initializeTailCallElimPass(PassRegistry&); +void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); void initializeTargetDataPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); Modified: llvm/trunk/lib/CodeGen/CodeGen.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodeGen.cpp (original) +++ llvm/trunk/lib/CodeGen/CodeGen.cpp Wed Feb 8 15:23:13 2012 @@ -21,37 +21,47 @@ void llvm::initializeCodeGen(PassRegistry &Registry) { initializeBranchFolderPassPass(Registry); initializeCalculateSpillWeightsPass(Registry); + initializeCodePlacementOptPass(Registry); initializeDeadMachineInstructionElimPass(Registry); + initializeExpandPostRAPass(Registry); + initializeExpandISelPseudosPass(Registry); + initializeFinalizeMachineBundlesPass(Registry); + initializeGCMachineCodeAnalysisPass(Registry); initializeGCModuleInfoPass(Registry); initializeIfConverterPass(Registry); initializeLiveDebugVariablesPass(Registry); initializeLiveIntervalsPass(Registry); initializeLiveStacksPass(Registry); initializeLiveVariablesPass(Registry); + initializeLocalStackSlotPassPass(Registry); initializeMachineBlockFrequencyInfoPass(Registry); initializeMachineBlockPlacementPass(Registry); initializeMachineBlockPlacementStatsPass(Registry); + initializeMachineCopyPropagationPass(Registry); initializeMachineCSEPass(Registry); initializeMachineDominatorTreePass(Registry); initializeMachineLICMPass(Registry); initializeMachineLoopInfoPass(Registry); initializeMachineModuleInfoPass(Registry); + initializeMachineSchedulerPass(Registry); initializeMachineSinkingPass(Registry); initializeMachineVerifierPassPass(Registry); initializeOptimizePHIsPass(Registry); initializePHIEliminationPass(Registry); initializePeepholeOptimizerPass(Registry); + initializePostRASchedulerPass(Registry); initializeProcessImplicitDefsPass(Registry); initializePEIPass(Registry); initializeRegisterCoalescerPass(Registry); - initializeMachineSchedulerPass(Registry); initializeRenderMachineFunctionPass(Registry); initializeSlotIndexesPass(Registry); initializeStackProtectorPass(Registry); initializeStackSlotColoringPass(Registry); initializeStrongPHIEliminationPass(Registry); + initializeTailDuplicatePassPass(Registry); initializeTargetPassConfigPass(Registry); initializeTwoAddressInstructionPassPass(Registry); + initializeUnpackMachineBundlesPass(Registry); initializeUnreachableBlockElimPass(Registry); initializeUnreachableMachineBlockElimPass(Registry); initializeVirtRegMapPass(Registry); Modified: llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp (original) +++ llvm/trunk/lib/CodeGen/CodePlacementOpt.cpp Wed Feb 8 15:23:13 2012 @@ -39,9 +39,6 @@ CodePlacementOpt() : MachineFunctionPass(ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { - return "Code Placement Optimizer"; - } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); @@ -69,9 +66,9 @@ char CodePlacementOpt::ID = 0; } // end anonymous namespace -FunctionPass *llvm::createCodePlacementOptPass() { - return new CodePlacementOpt(); -} +char &llvm::CodePlacementOptID = CodePlacementOpt::ID; +INITIALIZE_PASS(CodePlacementOpt, "code-placement", + "Code Placement Optimizer", false, false) /// HasFallthrough - Test whether the given branch has a fallthrough, either as /// a plain fallthrough or as a fallthrough case of a conditional branch. Modified: llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp (original) +++ llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Wed Feb 8 15:23:13 2012 @@ -45,14 +45,11 @@ }; } char DeadMachineInstructionElim::ID = 0; +char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID; INITIALIZE_PASS(DeadMachineInstructionElim, "dead-mi-elimination", "Remove dead machine instructions", false, false) -FunctionPass *llvm::createDeadMachineInstructionElimPass() { - return new DeadMachineInstructionElim(); -} - bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const { // Technically speaking inline asm without side effects and no defs can still // be deleted. But there is so much bad inline asm code out there, we should Modified: llvm/trunk/lib/CodeGen/ExpandISelPseudos.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExpandISelPseudos.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ExpandISelPseudos.cpp (original) +++ llvm/trunk/lib/CodeGen/ExpandISelPseudos.cpp Wed Feb 8 15:23:13 2012 @@ -32,10 +32,6 @@ private: virtual bool runOnMachineFunction(MachineFunction &MF); - const char *getPassName() const { - return "Expand ISel Pseudo-instructions"; - } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); } @@ -43,12 +39,9 @@ } // end anonymous namespace char ExpandISelPseudos::ID = 0; +char &llvm::ExpandISelPseudosID = ExpandISelPseudos::ID; INITIALIZE_PASS(ExpandISelPseudos, "expand-isel-pseudos", - "Expand CodeGen Pseudo-instructions", false, false) - -FunctionPass *llvm::createExpandISelPseudosPass() { - return new ExpandISelPseudos(); -} + "Expand ISel Pseudo-instructions", false, false) bool ExpandISelPseudos::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; Modified: llvm/trunk/lib/CodeGen/ExpandPostRAPseudos.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/ExpandPostRAPseudos.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/ExpandPostRAPseudos.cpp (original) +++ llvm/trunk/lib/CodeGen/ExpandPostRAPseudos.cpp Wed Feb 8 15:23:13 2012 @@ -36,10 +36,6 @@ static char ID; // Pass identification, replacement for typeid ExpandPostRA() : MachineFunctionPass(ID) {} - const char *getPassName() const { - return "Post-RA pseudo instruction expansion pass"; - } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); AU.addPreservedID(MachineLoopInfoID); @@ -61,10 +57,10 @@ } // end anonymous namespace char ExpandPostRA::ID = 0; +char &llvm::ExpandPostRAPseudosID = ExpandPostRA::ID; -FunctionPass *llvm::createExpandPostRAPseudosPass() { - return new ExpandPostRA(); -} +INITIALIZE_PASS(ExpandPostRA, "postrapseudos", + "Post-RA pseudo instruction expansion pass", false, false) /// TransferDeadFlag - MI is a pseudo-instruction with DstReg dead, /// and the lowered replacement instructions immediately precede it. Modified: llvm/trunk/lib/CodeGen/GCStrategy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GCStrategy.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/GCStrategy.cpp (original) +++ llvm/trunk/lib/CodeGen/GCStrategy.cpp Wed Feb 8 15:23:13 2012 @@ -10,8 +10,8 @@ // This file implements target- and collector-independent garbage collection // infrastructure. // -// MachineCodeAnalysis identifies the GC safe points in the machine code. Roots -// are identified in SelectionDAGISel. +// GCMachineCodeAnalysis identifies the GC safe points in the machine code. +// Roots are identified in SelectionDAGISel. // //===----------------------------------------------------------------------===// @@ -60,11 +60,11 @@ }; - /// MachineCodeAnalysis - This is a target-independent pass over the machine + /// GCMachineCodeAnalysis - This is a target-independent pass over the machine /// function representation to identify safe points for the garbage collector /// in the machine code. It inserts labels at safe points and populates a /// GCMetadata record for each function. - class MachineCodeAnalysis : public MachineFunctionPass { + class GCMachineCodeAnalysis : public MachineFunctionPass { const TargetMachine *TM; GCFunctionInfo *FI; MachineModuleInfo *MMI; @@ -81,8 +81,7 @@ public: static char ID; - MachineCodeAnalysis(); - const char *getPassName() const; + GCMachineCodeAnalysis(); void getAnalysisUsage(AnalysisUsage &AU) const; bool runOnMachineFunction(MachineFunction &MF); @@ -334,35 +333,31 @@ // ----------------------------------------------------------------------------- -FunctionPass *llvm::createGCMachineCodeAnalysisPass() { - return new MachineCodeAnalysis(); -} +char GCMachineCodeAnalysis::ID = 0; +char &llvm::GCMachineCodeAnalysisID = GCMachineCodeAnalysis::ID; -char MachineCodeAnalysis::ID = 0; +INITIALIZE_PASS(GCMachineCodeAnalysis, "gc-analysis", + "Analyze Machine Code For Garbage Collection", false, false) -MachineCodeAnalysis::MachineCodeAnalysis() +GCMachineCodeAnalysis::GCMachineCodeAnalysis() : MachineFunctionPass(ID) {} -const char *MachineCodeAnalysis::getPassName() const { - return "Analyze Machine Code For Garbage Collection"; -} - -void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { +void GCMachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { MachineFunctionPass::getAnalysisUsage(AU); AU.setPreservesAll(); AU.addRequired(); AU.addRequired(); } -MCSymbol *MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, - MachineBasicBlock::iterator MI, - DebugLoc DL) const { +MCSymbol *GCMachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, + MachineBasicBlock::iterator MI, + DebugLoc DL) const { MCSymbol *Label = MBB.getParent()->getContext().CreateTempSymbol(); BuildMI(MBB, MI, DL, TII->get(TargetOpcode::GC_LABEL)).addSym(Label); return Label; } -void MachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) { +void GCMachineCodeAnalysis::VisitCallPoint(MachineBasicBlock::iterator CI) { // Find the return address (next instruction), too, so as to bracket the call // instruction. MachineBasicBlock::iterator RAI = CI; @@ -379,7 +374,7 @@ } } -void MachineCodeAnalysis::FindSafePoints(MachineFunction &MF) { +void GCMachineCodeAnalysis::FindSafePoints(MachineFunction &MF) { for (MachineFunction::iterator BBI = MF.begin(), BBE = MF.end(); BBI != BBE; ++BBI) for (MachineBasicBlock::iterator MI = BBI->begin(), @@ -388,7 +383,7 @@ VisitCallPoint(MI); } -void MachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) { +void GCMachineCodeAnalysis::FindStackOffsets(MachineFunction &MF) { const TargetFrameLowering *TFI = TM->getFrameLowering(); assert(TFI && "TargetRegisterInfo not available!"); @@ -397,7 +392,7 @@ RI->StackOffset = TFI->getFrameIndexOffset(MF, RI->Num); } -bool MachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) { +bool GCMachineCodeAnalysis::runOnMachineFunction(MachineFunction &MF) { // Quick exit for functions that do not use GC. if (!MF.getFunction()->hasGC()) return false; Modified: llvm/trunk/lib/CodeGen/IfConversion.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/IfConversion.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/IfConversion.cpp (original) +++ llvm/trunk/lib/CodeGen/IfConversion.cpp Wed Feb 8 15:23:13 2012 @@ -170,7 +170,6 @@ } virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "If Converter"; } private: bool ReverseBranchCondition(BBInfo &BBI); @@ -253,12 +252,12 @@ char IfConverter::ID = 0; } +char &llvm::IfConverterID = IfConverter::ID; + INITIALIZE_PASS_BEGIN(IfConverter, "if-converter", "If Converter", false, false) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) INITIALIZE_PASS_END(IfConverter, "if-converter", "If Converter", false, false) -FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); } - bool IfConverter::runOnMachineFunction(MachineFunction &MF) { TLI = MF.getTarget().getTargetLowering(); TII = MF.getTarget().getInstrInfo(); Modified: llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp (original) +++ llvm/trunk/lib/CodeGen/LocalStackSlotAllocation.cpp Wed Feb 8 15:23:13 2012 @@ -71,19 +71,15 @@ AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); } - const char *getPassName() const { - return "Local Stack Slot Allocation"; - } private: }; } // end anonymous namespace char LocalStackSlotPass::ID = 0; - -FunctionPass *llvm::createLocalStackSlotAllocationPass() { - return new LocalStackSlotPass(); -} +char &llvm::LocalStackSlotAllocationID = LocalStackSlotPass::ID; +INITIALIZE_PASS(LocalStackSlotPass, "localstackalloc", + "Local Stack Slot Allocation", false, false) bool LocalStackSlotPass::runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo *MFI = MF.getFrameInfo(); Modified: llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBlockPlacement.cpp Wed Feb 8 15:23:13 2012 @@ -224,12 +224,11 @@ AU.addRequired(); MachineFunctionPass::getAnalysisUsage(AU); } - - const char *getPassName() const { return "Block Placement"; } }; } char MachineBlockPlacement::ID = 0; +char &llvm::MachineBlockPlacementID = MachineBlockPlacement::ID; INITIALIZE_PASS_BEGIN(MachineBlockPlacement, "block-placement2", "Branch Probability Basic Block Placement", false, false) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) @@ -238,10 +237,6 @@ INITIALIZE_PASS_END(MachineBlockPlacement, "block-placement2", "Branch Probability Basic Block Placement", false, false) -FunctionPass *llvm::createMachineBlockPlacementPass() { - return new MachineBlockPlacement(); -} - #ifndef NDEBUG /// \brief Helper to print the name of a MBB. /// @@ -943,12 +938,11 @@ AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } - - const char *getPassName() const { return "Block Placement Stats"; } }; } char MachineBlockPlacementStats::ID = 0; +char &llvm::MachineBlockPlacementStatsID = MachineBlockPlacementStats::ID; INITIALIZE_PASS_BEGIN(MachineBlockPlacementStats, "block-placement-stats", "Basic Block Placement Stats", false, false) INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo) @@ -956,10 +950,6 @@ INITIALIZE_PASS_END(MachineBlockPlacementStats, "block-placement-stats", "Basic Block Placement Stats", false, false) -FunctionPass *llvm::createMachineBlockPlacementStatsPass() { - return new MachineBlockPlacementStats(); -} - bool MachineBlockPlacementStats::runOnMachineFunction(MachineFunction &F) { // Check for single-block functions and skip them. if (llvm::next(F.begin()) == F.end()) Modified: llvm/trunk/lib/CodeGen/MachineCSE.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCSE.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCSE.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCSE.cpp Wed Feb 8 15:23:13 2012 @@ -103,6 +103,7 @@ } // end anonymous namespace char MachineCSE::ID = 0; +char &llvm::MachineCSEID = MachineCSE::ID; INITIALIZE_PASS_BEGIN(MachineCSE, "machine-cse", "Machine Common Subexpression Elimination", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) @@ -110,8 +111,6 @@ INITIALIZE_PASS_END(MachineCSE, "machine-cse", "Machine Common Subexpression Elimination", false, false) -FunctionPass *llvm::createMachineCSEPass() { return new MachineCSE(); } - bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI, MachineBasicBlock *MBB) { bool Changed = false; Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Wed Feb 8 15:23:13 2012 @@ -50,14 +50,11 @@ }; } char MachineCopyPropagation::ID = 0; +char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; INITIALIZE_PASS(MachineCopyPropagation, "machine-cp", "Machine Copy Propagation Pass", false, false) -FunctionPass *llvm::createMachineCopyPropagationPass() { - return new MachineCopyPropagation(); -} - void MachineCopyPropagation::SourceNoLongerAvailable(unsigned Reg, DenseMap &SrcMap, Modified: llvm/trunk/lib/CodeGen/MachineInstrBundle.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineInstrBundle.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineInstrBundle.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineInstrBundle.cpp Wed Feb 8 15:23:13 2012 @@ -31,13 +31,10 @@ } // end anonymous namespace char UnpackMachineBundles::ID = 0; +char &llvm::UnpackMachineBundlesID = UnpackMachineBundles::ID; INITIALIZE_PASS(UnpackMachineBundles, "unpack-mi-bundles", "Unpack machine instruction bundles", false, false) -FunctionPass *llvm::createUnpackMachineBundlesPass() { - return new UnpackMachineBundles(); -} - bool UnpackMachineBundles::runOnMachineFunction(MachineFunction &MF) { bool Changed = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { @@ -85,13 +82,10 @@ } // end anonymous namespace char FinalizeMachineBundles::ID = 0; +char &llvm::FinalizeMachineBundlesID = FinalizeMachineBundles::ID; INITIALIZE_PASS(FinalizeMachineBundles, "finalize-mi-bundles", "Finalize machine instruction bundles", false, false) -FunctionPass *llvm::createFinalizeMachineBundlesPass() { - return new FinalizeMachineBundles(); -} - bool FinalizeMachineBundles::runOnMachineFunction(MachineFunction &MF) { return llvm::finalizeBundles(MF); } Modified: llvm/trunk/lib/CodeGen/MachineLICM.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineLICM.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineLICM.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineLICM.cpp Wed Feb 8 15:23:13 2012 @@ -119,8 +119,6 @@ virtual bool runOnMachineFunction(MachineFunction &MF); - const char *getPassName() const { return "Machine Instruction LICM"; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); AU.addRequired(); @@ -289,6 +287,7 @@ } // end anonymous namespace char MachineLICM::ID = 0; +char &llvm::MachineLICMID = MachineLICM::ID; INITIALIZE_PASS_BEGIN(MachineLICM, "machinelicm", "Machine Loop Invariant Code Motion", false, false) INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo) @@ -297,10 +296,6 @@ INITIALIZE_PASS_END(MachineLICM, "machinelicm", "Machine Loop Invariant Code Motion", false, false) -FunctionPass *llvm::createMachineLICMPass() { - return new MachineLICM(); -} - /// LoopIsOuterMostWithPredecessor - Test if the given loop is the outer-most /// loop that has a unique predecessor. static bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop) { Modified: llvm/trunk/lib/CodeGen/MachineSink.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineSink.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineSink.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineSink.cpp Wed Feb 8 15:23:13 2012 @@ -102,6 +102,7 @@ } // end anonymous namespace char MachineSinking::ID = 0; +char &llvm::MachineSinkingID = MachineSinking::ID; INITIALIZE_PASS_BEGIN(MachineSinking, "machine-sink", "Machine code sinking", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) @@ -110,8 +111,6 @@ INITIALIZE_PASS_END(MachineSinking, "machine-sink", "Machine code sinking", false, false) -FunctionPass *llvm::createMachineSinkingPass() { return new MachineSinking(); } - bool MachineSinking::PerformTrivialForwardCoalescing(MachineInstr *MI, MachineBasicBlock *MBB) { if (!MI->isCopy()) Modified: llvm/trunk/lib/CodeGen/OptimizePHIs.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/OptimizePHIs.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/OptimizePHIs.cpp (original) +++ llvm/trunk/lib/CodeGen/OptimizePHIs.cpp Wed Feb 8 15:23:13 2012 @@ -56,11 +56,10 @@ } char OptimizePHIs::ID = 0; +char &llvm::OptimizePHIsID = OptimizePHIs::ID; INITIALIZE_PASS(OptimizePHIs, "opt-phis", "Optimize machine instruction PHIs", false, false) -FunctionPass *llvm::createOptimizePHIsPass() { return new OptimizePHIs(); } - bool OptimizePHIs::runOnMachineFunction(MachineFunction &Fn) { MRI = &Fn.getRegInfo(); TII = Fn.getTarget().getInstrInfo(); Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 15:23:13 2012 @@ -189,22 +189,22 @@ printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. - PM.add(createExpandISelPseudosPass()); + addPass(ExpandISelPseudosID); // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { - PM.add(createTailDuplicatePass()); + addPass(TailDuplicateID); printAndVerify("After Pre-RegAlloc TailDuplicate"); } // Optimize PHIs before DCE: removing dead PHI cycles may make more // instructions dead. if (getOptLevel() != CodeGenOpt::None) - PM.add(createOptimizePHIsPass()); + addPass(OptimizePHIsID); // If the target requests it, assign local variables to stack slots relative // to one another and simplify frame index references where possible. - PM.add(createLocalStackSlotAllocationPass()); + addPass(LocalStackSlotAllocationID); if (getOptLevel() != CodeGenOpt::None) { // With optimization, dead code should already be eliminated. However @@ -212,18 +212,18 @@ // used by tail calls, where the tail calls reuse the incoming stack // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). if (!DisableMachineDCE) - PM.add(createDeadMachineInstructionElimPass()); + addPass(DeadMachineInstructionElimID); printAndVerify("After codegen DCE pass"); if (!DisableMachineLICM) - PM.add(createMachineLICMPass()); + addPass(MachineLICMID); if (!DisableMachineCSE) - PM.add(createMachineCSEPass()); + addPass(MachineCSEID); if (!DisableMachineSink) - PM.add(createMachineSinkingPass()); + addPass(MachineSinkingID); printAndVerify("After Machine LICM, CSE and Sinking passes"); - PM.add(createPeepholeOptimizerPass()); + addPass(PeepholeOptimizerID); printAndVerify("After codegen peephole optimization pass"); } @@ -240,11 +240,11 @@ // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. if (!DisableSSC) - PM.add(createStackSlotColoringPass()); + addPass(StackSlotColoringID); // Run post-ra machine LICM to hoist reloads / remats. if (!DisablePostRAMachineLICM) - PM.add(createMachineLICMPass()); + addPass(MachineLICMID); printAndVerify("After StackSlotColoring and postra Machine LICM"); } @@ -254,7 +254,7 @@ printAndVerify("After PostRegAlloc passes"); // Insert prolog/epilog code. Eliminate abstract frame index references... - PM.add(createPrologEpilogCodeInserter()); + addPass(PrologEpilogCodeInserterID); printAndVerify("After PrologEpilogCodeInserter"); // Branch folding must be run after regalloc and prolog/epilog insertion. @@ -265,18 +265,18 @@ // Tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { - PM.add(createTailDuplicatePass()); + addPass(TailDuplicateID); printNoVerify("After TailDuplicate"); } // Copy propagation. if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { - PM.add(createMachineCopyPropagationPass()); + addPass(MachineCopyPropagationID); printNoVerify("After copy propagation pass"); } // Expand pseudo instructions before second scheduling pass. - PM.add(createExpandPostRAPseudosPass()); + addPass(ExpandPostRAPseudosID); printNoVerify("After ExpandPostRAPseudos"); // Run pre-sched2 passes. @@ -285,11 +285,11 @@ // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { - PM.add(createPostRAScheduler()); + addPass(PostRASchedulerID); printNoVerify("After PostRAScheduler"); } - PM.add(createGCMachineCodeAnalysisPass()); + addPass(GCMachineCodeAnalysisID); if (PrintGCInfo) PM.add(createGCInfoPrinter(dbgs())); @@ -299,16 +299,16 @@ // MachineBlockPlacement is an experimental pass which is disabled by // default currently. Eventually it should subsume CodePlacementOpt, so // when enabled, the other is disabled. - PM.add(createMachineBlockPlacementPass()); + addPass(MachineBlockPlacementID); printNoVerify("After MachineBlockPlacement"); } else { - PM.add(createCodePlacementOptPass()); + addPass(CodePlacementOptID); printNoVerify("After CodePlacementOpt"); } // Run a separate pass to collect block placement statistics. if (EnableBlockPlacementStats) { - PM.add(createMachineBlockPlacementStatsPass()); + addPass(MachineBlockPlacementStatsID); printNoVerify("After MachineBlockPlacementStats"); } } Modified: llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp (original) +++ llvm/trunk/lib/CodeGen/PeepholeOptimizer.cpp Wed Feb 8 15:23:13 2012 @@ -109,16 +109,13 @@ } char PeepholeOptimizer::ID = 0; +char &llvm::PeepholeOptimizerID = PeepholeOptimizer::ID; INITIALIZE_PASS_BEGIN(PeepholeOptimizer, "peephole-opts", "Peephole Optimizations", false, false) INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_END(PeepholeOptimizer, "peephole-opts", "Peephole Optimizations", false, false) -FunctionPass *llvm::createPeepholeOptimizerPass() { - return new PeepholeOptimizer(); -} - /// OptimizeExtInstr - If instruction is a copy-like instruction, i.e. it reads /// a single register and writes a single register and it does not modify the /// source, and if the source value is preserved as a sub-register of the Modified: llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp (original) +++ llvm/trunk/lib/CodeGen/PostRASchedulerList.cpp Wed Feb 8 15:23:13 2012 @@ -98,10 +98,6 @@ MachineFunctionPass::getAnalysisUsage(AU); } - const char *getPassName() const { - return "Post RA top-down list latency scheduler"; - } - bool runOnMachineFunction(MachineFunction &Fn); }; char PostRAScheduler::ID = 0; @@ -179,6 +175,11 @@ }; } +char &llvm::PostRASchedulerID = PostRAScheduler::ID; + +INITIALIZE_PASS(PostRAScheduler, "post-RA-sched", + "Post RA top-down list latency scheduler", false, false) + SchedulePostRATDList::SchedulePostRATDList( MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT, AliasAnalysis *AA, const RegisterClassInfo &RCI, @@ -707,11 +708,3 @@ VerifySchedule(/*isBottomUp=*/false); #endif } - -//===----------------------------------------------------------------------===// -// Public Constructor Functions -//===----------------------------------------------------------------------===// - -FunctionPass *llvm::createPostRAScheduler() { - return new PostRAScheduler(); -} Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Wed Feb 8 15:23:13 2012 @@ -45,6 +45,7 @@ using namespace llvm; char PEI::ID = 0; +char &llvm::PrologEpilogCodeInserterID = PEI::ID; INITIALIZE_PASS_BEGIN(PEI, "prologepilog", "Prologue/Epilogue Insertion", false, false) @@ -52,18 +53,14 @@ INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree) INITIALIZE_PASS_DEPENDENCY(TargetPassConfig) INITIALIZE_PASS_END(PEI, "prologepilog", - "Prologue/Epilogue Insertion", false, false) + "Prologue/Epilogue Insertion & Frame Finalization", + false, false) STATISTIC(NumVirtualFrameRegs, "Number of virtual frame regs encountered"); STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged"); STATISTIC(NumBytesStackSpace, "Number of bytes used for stack in all functions"); -/// createPrologEpilogCodeInserter - This function returns a pass that inserts -/// prolog and epilog code, and eliminates abstract frame references. -/// -FunctionPass *llvm::createPrologEpilogCodeInserter() { return new PEI(); } - /// runOnMachineFunction - Insert prolog/epilog code and replace abstract /// frame indexes with appropriate references. /// Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.h?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/PrologEpilogInserter.h (original) +++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.h Wed Feb 8 15:23:13 2012 @@ -40,10 +40,6 @@ initializePEIPass(*PassRegistry::getPassRegistry()); } - const char *getPassName() const { - return "Prolog/Epilog Insertion & Frame Finalization"; - } - virtual void getAnalysisUsage(AnalysisUsage &AU) const; /// runOnMachineFunction - Insert prolog/epilog code and replace abstract Modified: llvm/trunk/lib/CodeGen/StackSlotColoring.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StackSlotColoring.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/StackSlotColoring.cpp (original) +++ llvm/trunk/lib/CodeGen/StackSlotColoring.cpp Wed Feb 8 15:23:13 2012 @@ -86,10 +86,6 @@ MachineFunctionPass(ID), ColorWithRegs(false), NextColor(-1) { initializeStackSlotColoringPass(*PassRegistry::getPassRegistry()); } - StackSlotColoring(bool RegColor) : - MachineFunctionPass(ID), ColorWithRegs(RegColor), NextColor(-1) { - initializeStackSlotColoringPass(*PassRegistry::getPassRegistry()); - } virtual void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesCFG(); @@ -105,9 +101,6 @@ } virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char* getPassName() const { - return "Stack Slot Coloring"; - } private: void InitializeSlots(); @@ -122,6 +115,7 @@ } // end anonymous namespace char StackSlotColoring::ID = 0; +char &llvm::StackSlotColoringID = StackSlotColoring::ID; INITIALIZE_PASS_BEGIN(StackSlotColoring, "stack-slot-coloring", "Stack Slot Coloring", false, false) @@ -132,10 +126,6 @@ INITIALIZE_PASS_END(StackSlotColoring, "stack-slot-coloring", "Stack Slot Coloring", false, false) -FunctionPass *llvm::createStackSlotColoringPass() { - return new StackSlotColoring(/*RegColor=*/false); -} - namespace { // IntervalSorter - Comparison predicate that sort live intervals by // their weight. Modified: llvm/trunk/lib/CodeGen/TailDuplication.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TailDuplication.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/TailDuplication.cpp (original) +++ llvm/trunk/lib/CodeGen/TailDuplication.cpp Wed Feb 8 15:23:13 2012 @@ -74,7 +74,6 @@ MachineFunctionPass(ID), PreRegAlloc(false) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Tail Duplication"; } private: void AddSSAUpdateEntry(unsigned OrigReg, unsigned NewReg, @@ -118,9 +117,10 @@ char TailDuplicatePass::ID = 0; } -FunctionPass *llvm::createTailDuplicatePass() { - return new TailDuplicatePass(); -} +char &llvm::TailDuplicateID = TailDuplicatePass::ID; + +INITIALIZE_PASS(TailDuplicatePass, "tailduplication", "Tail Duplication", + false, false) bool TailDuplicatePass::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); Modified: llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/ARM/ARMTargetMachine.cpp Wed Feb 8 15:23:13 2012 @@ -170,7 +170,7 @@ if (getOptLevel() != CodeGenOpt::None) { if (!getARMSubtarget().isThumb1Only()) - PM.add(createIfConverterPass()); + addPass(IfConverterID); } if (getARMSubtarget().isThumb2()) PM.add(createThumb2ITBlockPass()); @@ -184,7 +184,7 @@ PM.add(createThumb2SizeReductionPass()); // Constant island pass work on unbundled instructions. - PM.add(createUnpackMachineBundlesPass()); + addPass(UnpackMachineBundlesID); } PM.add(createARMConstantIslandPass()); Modified: llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/Hexagon/HexagonTargetMachine.cpp Wed Feb 8 15:23:13 2012 @@ -120,7 +120,7 @@ bool HexagonPassConfig::addPreSched2() { - PM.add(createIfConverterPass()); + addPass(IfConverterID); return true; } Modified: llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp?rev=150100&r1=150099&r2=150100&view=diff ============================================================================== --- llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp (original) +++ llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp Wed Feb 8 15:23:13 2012 @@ -280,37 +280,37 @@ printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. - PM.add(createExpandISelPseudosPass()); + addPass(ExpandISelPseudosID); // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createTailDuplicatePass()); + addPass(TailDuplicateID); printAndVerify("After Pre-RegAlloc TailDuplicate"); } // Optimize PHIs before DCE: removing dead PHI cycles may make more // instructions dead. if (getOptLevel() != CodeGenOpt::None) - PM.add(createOptimizePHIsPass()); + addPass(OptimizePHIsID); // If the target requests it, assign local variables to stack slots relative // to one another and simplify frame index references where possible. - PM.add(createLocalStackSlotAllocationPass()); + addPass(LocalStackSlotAllocationID); if (getOptLevel() != CodeGenOpt::None) { // With optimization, dead code should already be eliminated. However // there is one known exception: lowered code for arguments that are only // used by tail calls, where the tail calls reuse the incoming stack // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). - PM.add(createDeadMachineInstructionElimPass()); + addPass(DeadMachineInstructionElimID); printAndVerify("After codegen DCE pass"); - PM.add(createMachineLICMPass()); - PM.add(createMachineCSEPass()); - PM.add(createMachineSinkingPass()); + addPass(MachineLICMID); + addPass(MachineCSEID); + addPass(MachineSinkingID); printAndVerify("After Machine LICM, CSE and Sinking passes"); - PM.add(createPeepholeOptimizerPass()); + addPass(PeepholeOptimizerID); printAndVerify("After codegen peephole optimization pass"); } @@ -326,12 +326,12 @@ if (getOptLevel() != CodeGenOpt::None) { // FIXME: Re-enable coloring with register when it's capable of adding // kill markers. - PM.add(createStackSlotColoringPass()); + addPass(StackSlotColoringID); // FIXME: Post-RA LICM has asserts that fire on virtual registers. // Run post-ra machine LICM to hoist reloads / remats. //if (!DisablePostRAMachineLICM) - // PM.add(createMachineLICMPass(false)); + // addPass(MachineLICMPass(false)); printAndVerify("After StackSlotColoring and postra Machine LICM"); } @@ -340,11 +340,11 @@ if (addPostRegAlloc()) printAndVerify("After PostRegAlloc passes"); - PM.add(createExpandPostRAPseudosPass()); + addPass(ExpandPostRAPseudosID); printAndVerify("After ExpandPostRAPseudos"); // Insert prolog/epilog code. Eliminate abstract frame index references... - PM.add(createPrologEpilogCodeInserter()); + addPass(PrologEpilogCodeInserterID); printAndVerify("After PrologEpilogCodeInserter"); // Run pre-sched2 passes. @@ -353,7 +353,7 @@ // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createPostRAScheduler()); + addPass(PostRASchedulerID); printAndVerify("After PostRAScheduler"); } @@ -365,17 +365,17 @@ // Tail duplication. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createTailDuplicatePass()); + addPass(TailDuplicateID); printNoVerify("After TailDuplicate"); } - PM.add(createGCMachineCodeAnalysisPass()); + addPass(GCMachineCodeAnalysisID); //if (PrintGCInfo) // PM.add(createGCInfoPrinter(dbgs())); if (getOptLevel() != CodeGenOpt::None) { - PM.add(createCodePlacementOptPass()); + addPass(CodePlacementOptID); printNoVerify("After CodePlacementOpt"); } From kcc at google.com Wed Feb 8 15:33:27 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 08 Feb 2012 21:33:27 -0000 Subject: [llvm-commits] [compiler-rt] r150101 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_interface.h asan_rtl.cc tests/clone_test.cc tests/clone_test.tmpl Message-ID: <20120208213327.950B72A6C12C@llvm.org> Author: kcc Date: Wed Feb 8 15:33:27 2012 New Revision: 150101 URL: http://llvm.org/viewvc/llvm-project?rev=150101&view=rev Log: [asan] unpoison the stack before every noreturn call. Fixes asan issue 37. rt part Added: compiler-rt/trunk/lib/asan/tests/clone_test.cc compiler-rt/trunk/lib/asan/tests/clone_test.tmpl Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc compiler-rt/trunk/lib/asan/asan_interface.h compiler-rt/trunk/lib/asan/asan_rtl.cc Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=150101&r1=150100&r2=150101&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original) +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Feb 8 15:33:27 2012 @@ -231,28 +231,18 @@ } #endif // _WIN32 - -static void UnpoisonStackFromHereToTop() { - int local_stack; - AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); - CHECK(curr_thread); - uintptr_t top = curr_thread->stack_top(); - uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1); - PoisonShadow(bottom, top - bottom, 0); -} - INTERCEPTOR(void, longjmp, void *env, int val) { - UnpoisonStackFromHereToTop(); + __asan_handle_no_return(); REAL(longjmp)(env, val); } INTERCEPTOR(void, _longjmp, void *env, int val) { - UnpoisonStackFromHereToTop(); + __asan_handle_no_return(); REAL(_longjmp)(env, val); } INTERCEPTOR(void, siglongjmp, void *env, int val) { - UnpoisonStackFromHereToTop(); + __asan_handle_no_return(); REAL(siglongjmp)(env, val); } @@ -263,7 +253,7 @@ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { CHECK(REAL(__cxa_throw)); - UnpoisonStackFromHereToTop(); + __asan_handle_no_return(); REAL(__cxa_throw)(a, b, c); } #endif Modified: compiler-rt/trunk/lib/asan/asan_interface.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface.h?rev=150101&r1=150100&r2=150101&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interface.h (original) +++ compiler-rt/trunk/lib/asan/asan_interface.h Wed Feb 8 15:33:27 2012 @@ -79,6 +79,10 @@ // (un)poison memory in the same memory region simultaneously. void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + // Performs cleanup before a NoReturn function. Must be called before things + // like _exit and execl to avoid false positives on stack. + void __asan_handle_no_return(); + // User code should use macro instead of functions. #if defined(__has_feature) && __has_feature(address_sanitizer) #define ASAN_POISON_MEMORY_REGION(addr, size) \ Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=150101&r1=150100&r2=150101&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_rtl.cc (original) +++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed Feb 8 15:33:27 2012 @@ -283,6 +283,15 @@ return old; } +void __asan_handle_no_return() { + int local_stack; + AsanThread *curr_thread = asanThreadRegistry().GetCurrent(); + CHECK(curr_thread); + uintptr_t top = curr_thread->stack_top(); + uintptr_t bottom = ((uintptr_t)&local_stack - kPageSize) & ~(kPageSize-1); + PoisonShadow(bottom, top - bottom, 0); +} + void __asan_report_error(uintptr_t pc, uintptr_t bp, uintptr_t sp, uintptr_t addr, bool is_write, size_t access_size) { // Do not print more than one report, otherwise they will mix up. Added: compiler-rt/trunk/lib/asan/tests/clone_test.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/clone_test.cc?rev=150101&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/tests/clone_test.cc (added) +++ compiler-rt/trunk/lib/asan/tests/clone_test.cc Wed Feb 8 15:33:27 2012 @@ -0,0 +1,33 @@ +#ifdef __linux__ +#include +#include +#include +#include +#include +#include + +int Child(void *arg) { + char x[32] = {0}; // Stack gets poisoned. + printf("Child: %p\n", x); + _exit(1); // NoReturn, stack will remain unpoisoned unless we do something. +} + +int main(int argc, char **argv) { + const int kStackSize = 1 << 20; + char child_stack[kStackSize + 1]; + char *sp = child_stack + kStackSize; // Stack grows down. + printf("Parent: %p\n", sp); + pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0); + waitpid(clone_pid, NULL, 0); + for (int i = 0; i < kStackSize; i++) + child_stack[i] = i; + int ret = child_stack[argc - 1]; + printf("PASSED\n"); + return ret; +} +#else // not __linux__ +#include +int main() { + printf("PASSED\n"); +} +#endif Added: compiler-rt/trunk/lib/asan/tests/clone_test.tmpl URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/clone_test.tmpl?rev=150101&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/tests/clone_test.tmpl (added) +++ compiler-rt/trunk/lib/asan/tests/clone_test.tmpl Wed Feb 8 15:33:27 2012 @@ -0,0 +1 @@ +PASSED From kcc at google.com Wed Feb 8 15:36:17 2012 From: kcc at google.com (Kostya Serebryany) Date: Wed, 08 Feb 2012 21:36:17 -0000 Subject: [llvm-commits] [llvm] r150102 - in /llvm/trunk: lib/Transforms/Instrumentation/AddressSanitizer.cpp test/Instrumentation/AddressSanitizer/instrument-no-return.ll Message-ID: <20120208213617.F29772A6C12C@llvm.org> Author: kcc Date: Wed Feb 8 15:36:17 2012 New Revision: 150102 URL: http://llvm.org/viewvc/llvm-project?rev=150102&view=rev Log: [asan] unpoison the stack before every noreturn call. Fixes asan issue 37. llvm part Added: llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=150102&r1=150101&r2=150102&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original) +++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Wed Feb 8 15:36:17 2012 @@ -60,6 +60,7 @@ static const char *kAsanRegisterGlobalsName = "__asan_register_globals"; static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals"; static const char *kAsanInitName = "__asan_init"; +static const char *kAsanHandleNoReturnName = "__asan_handle_no_return"; static const char *kAsanMappingOffsetName = "__asan_mapping_offset"; static const char *kAsanMappingScaleName = "__asan_mapping_scale"; static const char *kAsanStackMallocName = "__asan_stack_malloc"; @@ -649,6 +650,7 @@ // (unless there are calls between uses). SmallSet TempsToInstrument; SmallVector ToInstrument; + SmallVector NoReturnCalls; // Fill the set of memory operations to instrument. for (Function::iterator FI = F.begin(), FE = F.end(); @@ -667,9 +669,12 @@ } else if (isa(BI) && ClMemIntrin) { // ok, take it. } else { - if (isa(BI)) { + if (CallInst *CI = dyn_cast(BI)) { // A call inside BB. TempsToInstrument.clear(); + if (CI->doesNotReturn()) { + NoReturnCalls.push_back(CI); + } } continue; } @@ -694,7 +699,17 @@ DEBUG(dbgs() << F); bool ChangedStack = poisonStackInFunction(M, F); - return NumInstrumented > 0 || ChangedStack; + + // We must unpoison the stack before every NoReturn call (throw, _exit, etc). + // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37 + for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) { + Instruction *CI = NoReturnCalls[i]; + IRBuilder<> IRB(CI); + IRB.CreateCall(M.getOrInsertFunction(kAsanHandleNoReturnName, + IRB.getVoidTy(), NULL)); + } + + return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty(); } static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) { Added: llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll?rev=150102&view=auto ============================================================================== --- llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll (added) +++ llvm/trunk/test/Instrumentation/AddressSanitizer/instrument-no-return.ll Wed Feb 8 15:36:17 2012 @@ -0,0 +1,17 @@ +; RUN: opt < %s -asan -S | FileCheck %s +; AddressSanitizer must insert __asan_handle_no_return +; before every noreturn call. + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" +target triple = "x86_64-unknown-linux-gnu" + +declare void @MyNoReturnFunc(i32) noreturn + +define i32 @_Z5ChildPv(i8* nocapture %arg) uwtable address_safety { +entry: + call void @MyNoReturnFunc(i32 1) noreturn + unreachable +} + +; CHECK: call void @__asan_handle_no_return +; CHECK-NEXT: call void @MyNoReturnFunc From echristo at apple.com Wed Feb 8 15:50:31 2012 From: echristo at apple.com (Eric Christopher) Date: Wed, 08 Feb 2012 13:50:31 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <91C216B9-0938-45CB-B077-10361711CADC@apple.com> Message-ID: <922F6886-937E-4F96-B1BC-B9CD3D1CD6BC@apple.com> On Feb 8, 2012, at 12:48 PM, David A. Greene wrote: > Eric Christopher writes: > >>> Whether generic IR is a "win" isn't the primary issue here. The issue >>> is that the user wrote code using intrinsics and expects that exact code >>> to be in the asm. Whether or not that is the best performing code >>> possible doesn't matter. It's what they want and we have to respect it. >>> Our customers demand it. >> >> Then make the generic IR match what you think should happen. I see no win >> for anyone with this. > > There is no way to do that. It's generic. By definition passes can > change it. > Yes. > You see no benefit even though I have directly stated that their > existance and use is critically important to us? > I disagree with it. "My customers expect a particular sequence of code generated for _mm_XXX_ZZZ" isn't a compiler problem, it's a frontend problem if you don't want the backend to optimize it. -eric From dag at cray.com Wed Feb 8 16:09:30 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 16:09:30 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <922F6886-937E-4F96-B1BC-B9CD3D1CD6BC@apple.com> (Eric Christopher's message of "Wed, 08 Feb 2012 13:50:31 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <91C216B9-0938-45CB-B077-10361711CADC@apple.com> <922F6886-937E-4F96-B1BC-B9CD3D1CD6BC@apple.com> Message-ID: Eric Christopher writes: >> You see no benefit even though I have directly stated that their >> existance and use is critically important to us? >> > > I disagree with it. "My customers expect a particular sequence of code > generated for _mm_XXX_ZZZ" isn't a compiler problem, it's a frontend > problem if you don't want the backend to optimize it. How do you propose solving the problem without intrinsics? Remember that other code in the same Module should be optimized right up to and before/after each intrinsic. This is not an uncommon requirement for compilers. -Dave From dag at cray.com Wed Feb 8 16:10:32 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 16:10:32 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Anton Korobeynikov's message of "Thu, 9 Feb 2012 00:55:55 +0400") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: Anton Korobeynikov writes: >> That's part of the reason I started to write a new C backend. ?Though >> that's stalled at the moment, it's still on my TODO list. > Maybe you can share what you have at the moment? Then someone else can > continue work in this area? I'll have to update it to the latest trunk. It doesn't build at all right now so I can't check it in. I was working on getting it building but got interrupted by work stuff. Believe me, I want to check it in ASAP. -Dave From dag at cray.com Wed Feb 8 16:13:42 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 16:13:42 -0600 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: <114101cce6a4$9ecaaf10$dc600d30$@org> (Sergei Larin's message of "Wed, 8 Feb 2012 14:59:59 -0600") References: <114101cce6a4$9ecaaf10$dc600d30$@org> Message-ID: "Sergei Larin" writes: > Not that I do not like to read about every single commit going in to > the tree, but I would like to see if there is any support to > separation of llvm-commits into several project centric mailing lists > ? something along the line of llvm-commits-rt, llvm-commits-polly, > llvm-commits etc. ?? I would find that very inconvenient. I like the ability to see what's happening at a glance. I'm not unsympathetic to your concerns about volume. Perhaps we can adopt some kind of tagging system in the subjects so people can filter into separate folders if they want. > I do see some ?lost patches?/review requests being blamed on high > message volume, and deeply empathize? This is an entirely different issue, I think. I have always thought (and stated numerous times) that proposed patches should be sent to llvmdev. It's the development list, after all. They'll stand out and more eyes will be looking at them. I don't think all that many people read -commits. -Dave From daniel at zuster.org Wed Feb 8 16:15:38 2012 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 08 Feb 2012 22:15:38 -0000 Subject: [llvm-commits] [zorg] r150104 - /zorg/trunk/lnt/lnt/tests/compile.py Message-ID: <20120208221538.DC0262A6C12C@llvm.org> Author: ddunbar Date: Wed Feb 8 16:15:38 2012 New Revision: 150104 URL: http://llvm.org/viewvc/llvm-project?rev=150104&view=rev Log: [lnt] lnt runtest compile: Fix up a refacto. Modified: zorg/trunk/lnt/lnt/tests/compile.py Modified: zorg/trunk/lnt/lnt/tests/compile.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/tests/compile.py?rev=150104&r1=150103&r2=150104&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/tests/compile.py (original) +++ zorg/trunk/lnt/lnt/tests/compile.py Wed Feb 8 16:15:38 2012 @@ -442,7 +442,8 @@ def run_test(self, name, args): global opts parser = OptionParser( - ("%%prog %(name)s [options] tester-name\n" + usage_info) % locals()) + ("%%prog %(name)s [options] []\n" + + usage_info) % locals()) parser.add_option("-v", "--verbose", dest="verbose", help="Show more test output", action="store_true", default=False) @@ -478,7 +479,7 @@ help="Individual test to run", action="append", default=[], choices=[k for k,v in all_tests]) - opts,args = parser.parse_args() + opts,args = parser.parse_args(args) if len(args) == 0: output = '-' From craig.topper at gmail.com Wed Feb 8 16:22:44 2012 From: craig.topper at gmail.com (Craig Topper) Date: Wed, 8 Feb 2012 14:22:44 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <91C216B9-0938-45CB-B077-10361711CADC@apple.com> <922F6886-937E-4F96-B1BC-B9CD3D1CD6BC@apple.com> Message-ID: On Wed, Feb 8, 2012 at 2:09 PM, David A. Greene wrote: > Eric Christopher writes: > > >> You see no benefit even though I have directly stated that their > >> existance and use is critically important to us? > >> > > > > I disagree with it. "My customers expect a particular sequence of code > > generated for _mm_XXX_ZZZ" isn't a compiler problem, it's a frontend > > problem if you don't want the backend to optimize it. > > How do you propose solving the problem without intrinsics? > > Remember that other code in the same Module should be optimized right up > to and before/after each intrinsic. > > This is not an uncommon requirement for compilers.a > There are already numerous instructions in llvm that have no intrinsics covering them. For instance, most shufffles (pshud, shufps, shufpd, vector unpacks, pshuflw, pshufhw), basic vector addition and subtraction and I'm sure many more. How was this "problem" not notice before now if its so important? > > -Dave > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/f708a099/attachment.html From sabre at nondot.org Wed Feb 8 16:20:00 2012 From: sabre at nondot.org (Chris Lattner) Date: Wed, 08 Feb 2012 22:20:00 -0000 Subject: [llvm-commits] [llvm] r150105 - /llvm/trunk/docs/DeveloperPolicy.html Message-ID: <20120208222000.B08352A6C12C@llvm.org> Author: lattner Date: Wed Feb 8 16:20:00 2012 New Revision: 150105 URL: http://llvm.org/viewvc/llvm-project?rev=150105&view=rev Log: fix broken link Modified: llvm/trunk/docs/DeveloperPolicy.html Modified: llvm/trunk/docs/DeveloperPolicy.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/DeveloperPolicy.html?rev=150105&r1=150104&r2=150105&view=diff ============================================================================== --- llvm/trunk/docs/DeveloperPolicy.html (original) +++ llvm/trunk/docs/DeveloperPolicy.html Wed Feb 8 16:20:00 2012 @@ -54,7 +54,7 @@

    • Keep the top of Subversion trees as stable as possible.
    • Establish awareness of the project's copyright, - license, and patent policies with contributors to the project.
    • + license, and patent policies with contributors to the project.

      This policy is aimed at frequent contributors to LLVM. People interested in From evan.cheng at apple.com Wed Feb 8 16:33:17 2012 From: evan.cheng at apple.com (Evan Cheng) Date: Wed, 08 Feb 2012 22:33:17 -0000 Subject: [llvm-commits] [llvm] r150107 - /llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Message-ID: <20120208223317.E28922A6C12C@llvm.org> Author: evancheng Date: Wed Feb 8 16:33:17 2012 New Revision: 150107 URL: http://llvm.org/viewvc/llvm-project?rev=150107&view=rev Log: Commit Andy Zhang's test for the lea patch. Added: llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Added: llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll?rev=150107&view=auto ============================================================================== --- llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll (added) +++ llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Wed Feb 8 16:33:17 2012 @@ -0,0 +1,48 @@ +; RUN: llc < %s -mcpu=atom -march=x86 | FileCheck -check-prefix=atom %s +; RUN: llc < %s -mcpu=core2 -march=x86 | FileCheck %s + +declare void @use_arr(i8*) +declare void @many_params(i32, i32, i32, i32, i32, i32) + +define void @test1() nounwind { +; atom: test1: +; atom: leal -1052(%esp), %esp +; atom-NOT: sub +; atom: call +; atom: leal 1052(%esp), %esp + +; CHECK: test1: +; CHECK: subl +; CHECK: call +; CHECK-NOT: lea + %arr = alloca [1024 x i8], align 16 + %arr_ptr = getelementptr inbounds [1024 x i8]* %arr, i8 0, i8 0 + call void @use_arr(i8* %arr_ptr) + ret void +} + +define void @test2() nounwind { +; atom: test2: +; atom: leal -28(%esp), %esp +; atom: call +; atom: leal 28(%esp), %esp + +; CHECK: test2: +; CHECK-NOT: lea + call void @many_params(i32 1, i32 2, i32 3, i32 4, i32 5, i32 6) + ret void +} + +define void @test3() nounwind { +; atom: test3: +; atom: leal -8(%esp), %esp +; atom: leal 8(%esp), %esp + +; CHECK: test3: +; CHECK-NOT: lea + %x = alloca i32, align 4 + %y = alloca i32, align 4 + store i32 0, i32* %x, align 4 + ret void +} + From stoklund at 2pi.dk Wed Feb 8 16:37:35 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Wed, 08 Feb 2012 22:37:35 -0000 Subject: [llvm-commits] [llvm] r150108 - /llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Message-ID: <20120208223735.772B22A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 16:37:35 2012 New Revision: 150108 URL: http://llvm.org/viewvc/llvm-project?rev=150108&view=rev Log: Handle register masks in MachineCopyPropagation. For simplicity, treat calls with register masks as basic block boundaries. This means we can't copy propagate callee-saved registers across calls, but I don't think that is a big deal. Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=150108&r1=150107&r2=150108&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Wed Feb 8 16:37:35 2012 @@ -191,8 +191,11 @@ // Not a copy. SmallVector Defs; + bool HasRegMask = false; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); + if (MO.isRegMask()) + HasRegMask = true; if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -220,6 +223,20 @@ } } + // The instruction has a register mask operand which means that it clobbers + // a large set of registers. It is possible to use the register mask to + // prune the available copies, but treat it like a basic block boundary for + // now. + if (HasRegMask) { + // FIXME: We could possibly erase some MaybeDeadCopies if their registers + // are clobbered by the mask. + MaybeDeadCopies.clear(); + AvailCopyMap.clear(); + CopyMap.clear(); + SrcMap.clear(); + continue; + } + for (unsigned i = 0, e = Defs.size(); i != e; ++i) { unsigned Reg = Defs[i]; From hfinkel at anl.gov Wed Feb 8 16:56:23 2012 From: hfinkel at anl.gov (Hal Finkel) Date: Wed, 08 Feb 2012 16:56:23 -0600 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: References: <114101cce6a4$9ecaaf10$dc600d30$@org> Message-ID: <1328741783.2463.129.camel@sapling> On Wed, 2012-02-08 at 16:13 -0600, David A. Greene wrote: > "Sergei Larin" writes: > > > Not that I do not like to read about every single commit going in to > > the tree, but I would like to see if there is any support to > > separation of llvm-commits into several project centric mailing lists > > ? something along the line of llvm-commits-rt, llvm-commits-polly, > > llvm-commits etc. ?? > > I would find that very inconvenient. I like the ability to see what's > happening at a glance. > > I'm not unsympathetic to your concerns about volume. Perhaps we can > adopt some kind of tagging system in the subjects so people can filter > into separate folders if they want. > > > I do see some ?lost patches?/review requests being blamed on high > > message volume, and deeply empathize? > > This is an entirely different issue, I think. I have always thought > (and stated numerous times) that proposed patches should be sent to > llvmdev. It's the development list, after all. They'll stand out and > more eyes will be looking at them. I don't think all that many people > read -commits. It might be worthwhile to have some kind of actual tracking system for patches. I think this can be done without much overhead by using a simple script that watches the mailing list. To be specific, how about the following: - When submitting a patch, the e-mail must contain the keywords: 'PATCH: NEW'. - When the script sees replies to that e-mail it will assume that the patch is being reviewed. It will warn (by sending a mail to the list) if the mail stops (excluding from the original author) for some extended period of time without some further state change. - The script will change the state recorded for a patch when it sees a reply mail with the keywords, 'PATCH: REVISE' [the system is to wait for a revised patch from the author], 'PATCH: APPLIED r[0-9]+' or 'PATCH: REJECTED' or 'PATCH: WITHDRAWN'. - The script will maintain a database of some kind used by a simple web app that can be used to view the current state of patches. I think that using some system like this we can essentially keep the current review protocol but also add some useful tracking so that things don't slip through the cracks. -Hal > > -Dave > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory From dreynaud at apple.com Wed Feb 8 16:56:41 2012 From: dreynaud at apple.com (Daniel Reynaud) Date: Wed, 08 Feb 2012 14:56:41 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers In-Reply-To: References: Message-ID: <14C08D85-E7F7-44DE-8260-706F4C9489D4@apple.com> On Feb 7, 2012, at 5:44 PM, Eli Friedman wrote: > On Tue, Feb 7, 2012 at 5:21 PM, Daniel Reynaud wrote: >> Even better with the actual patch. >> >> >> >> On Feb 7, 2012, at 5:20 PM, Daniel Reynaud wrote: >> >> This is a patch for http://llvm.org/bugs/show_bug.cgi?id=11919 >> >> It seems to do the trick for me. When this particular configuration (a >> global initializer references a blockaddress from a function that has been >> sent to a different module) is not encountered, it should produce the same >> initializer pattern as usual (i.e., everything in the safe module). >> >> thanks, >> daniel > > + bool globalInitUsesExternalBA(GlobalVariable* GV) { > + if (!GV->hasInitializer()) > + return false; > + > + Constant *I = GV->getInitializer(); > + > + // walk the values used by the initializer > + // (and recurse into things like ConstantExpr) > + std::vector Worklist; > + Worklist.push_back(I); > + while(!Worklist.empty()) { > + Constant* V = Worklist.back(); > + Worklist.pop_back(); > + > + if (BlockAddress *BA = dyn_cast(V)) { > + Function *F = BA->getFunction(); > + if (F->isDeclaration()) > + return true; > + } > + > + for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) > + if (Constant *C = dyn_cast(*i)) > + Worklist.push_back(C); > + } > + > + return false; > + } > > You need to make sure not to recurse into GlobalValues. ok > You also > probably want a hashtable so you don't run into bad performance > characteristics with ConstantExprs. ok. I tried putting various things in the cache (everything, nothing, just ConstantExpr), and it did not have any noticeable impact on my test case (76s to reduce 459 functions). > > Also, weird indentation. > > > + // Try to split the global initializers evenly > + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); > + I != E; ++I) { > + GlobalVariable *GV = cast(NewVMap[I]); > + if (globalInitUsesExternalBA(I)) { > + assert(!globalInitUsesExternalBA(GV) && "A global initializer references" > + "functions in both the safe and the test module"); > > I don't see what prevents this assertion from triggering? nothing indeed. If a global initializer references blockaddresses across modules, I don't think we can split. Updated patch attached. -------------- next part -------------- A non-text attachment was scrubbed... Name: bugpoint.patch Type: application/octet-stream Size: 2910 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/4ad0332e/attachment.obj -------------- next part -------------- -- daniel From eli.friedman at gmail.com Wed Feb 8 17:05:37 2012 From: eli.friedman at gmail.com (Eli Friedman) Date: Wed, 8 Feb 2012 15:05:37 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers In-Reply-To: <14C08D85-E7F7-44DE-8260-706F4C9489D4@apple.com> References: <14C08D85-E7F7-44DE-8260-706F4C9489D4@apple.com> Message-ID: On Wed, Feb 8, 2012 at 2:56 PM, Daniel Reynaud wrote: > > On Feb 7, 2012, at 5:44 PM, Eli Friedman wrote: > >> On Tue, Feb 7, 2012 at 5:21 PM, Daniel Reynaud wrote: >>> Even better with the actual patch. >>> >>> >>> >>> On Feb 7, 2012, at 5:20 PM, Daniel Reynaud wrote: >>> >>> This is a patch for http://llvm.org/bugs/show_bug.cgi?id=11919 >>> >>> It seems to do the trick for me. When this particular configuration (a >>> global initializer references a blockaddress from a function that has been >>> sent to a different module) is not encountered, it should produce the same >>> initializer pattern as usual (i.e., everything in the safe module). >>> >>> thanks, >>> daniel >> >> + ?bool globalInitUsesExternalBA(GlobalVariable* GV) { >> + ? ? ?if (!GV->hasInitializer()) >> + ? ? ? ? ?return false; >> + >> + ? ? ?Constant *I = GV->getInitializer(); >> + >> + ? ? ?// walk the values used by the initializer >> + ? ? ?// (and recurse into things like ConstantExpr) >> + ? ? ?std::vector Worklist; >> + ? ? ?Worklist.push_back(I); >> + ? ? ?while(!Worklist.empty()) { >> + ? ? ? ?Constant* V = Worklist.back(); >> + ? ? ? ?Worklist.pop_back(); >> + >> + ? ? ? ?if (BlockAddress *BA = dyn_cast(V)) { >> + ? ? ? ? ?Function *F = BA->getFunction(); >> + ? ? ? ? ?if (F->isDeclaration()) >> + ? ? ? ? ? ?return true; >> + ? ? ? ?} >> + >> + ? ? ? ?for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) >> + ? ? ? ? ?if (Constant *C = dyn_cast(*i)) >> + ? ? ? ? ? ?Worklist.push_back(C); >> + ? ? ?} >> + >> + ? ?return false; >> + ?} >> >> You need to make sure not to recurse into GlobalValues. > > ok > >> ?You also >> probably want a hashtable so you don't run into bad performance >> characteristics with ConstantExprs. > > ok. I tried putting various things in the cache (everything, nothing, just ConstantExpr), and it did not have any noticeable impact on my test case (76s to reduce 459 functions). I'm not really worried about the performance of normal cases; the issue is that there are some pathological cases which can cause the naive approach to to take exponential time. >> >> Also, weird indentation. >> >> >> + ?// Try to split the global initializers evenly >> + ?for (Module::global_iterator I = M->global_begin(), E = M->global_end(); >> + ? ? ? I != E; ++I) { >> + ? ?GlobalVariable *GV = cast(NewVMap[I]); >> + ? ?if (globalInitUsesExternalBA(I)) { >> + ? ? ?assert(!globalInitUsesExternalBA(GV) && "A global initializer references" >> + ? ? ? ? ?"functions in both the safe and the test module"); >> >> I don't see what prevents this assertion from triggering? > > nothing indeed. If a global initializer references blockaddresses across modules, I don't think we can split. True; we should at least give a proper error message, though. -Eli From clattner at apple.com Wed Feb 8 17:07:06 2012 From: clattner at apple.com (Chris Lattner) Date: Wed, 08 Feb 2012 15:07:06 -0800 Subject: [llvm-commits] [PATCH] LIT cleanup phase #1 - replacing dg.exp with lit.local.cfg In-Reply-To: <9BBE4537D1BAAB479E9E8F9D4234619D33B0DC@HASMSX103.ger.corp.intel.com> References: <9BBE4537D1BAAB479E9E8F9D4234619D33B0DC@HASMSX103.ger.corp.intel.com> Message-ID: <467697EB-B800-4CB9-8DC1-432A397F76FB@apple.com> Sounds great to me. -Chris On Feb 8, 2012, at 4:42 AM, Bendersky, Eli wrote: > Hello, > > I've started working on cleaning up LIT a bit. The overall cleanup plan was approved by Daniel Dunbar. The first patch (attached) is ready for review. > > The LIT global configuration currently relies on "dg.exp" files to find out which file extensions have tests, and which targets are supported for these tests. This is a relic from old times and is no longer required for LIT runs. LIT already has good infrastructure for specifying these things via lit.local.cfg - in fact it's already being used in Clang tests instead of dg.exp. > > The attached patch translates all existing dg.exp files into respective lit.local.cfg files. Also, the configuration-specific information was moved from site.exp to lit.site.cfg, as appropriate. > > To keep the first patch minimal (it's rather large even now, because a lot of files were modified), some things are left for next patches: > > * I've made lit.cfg just ignore the fact that it can't find dg.exp, meaning that dg.exp is in theory still supported. This code in lit.cfg will be cleaned up, as well as removing the generation, reading and parsing of site.exp - which is also no longer needed. > * There's a bit of duplication in some of the lit.local.cfg files for reaching the root configuration. This duplication is "borrowed" from the Clang lit.local.cfg files, where it also exists. In a future patch I plan to clean it up (including the Clang lit files), probably by adding a new configuration attribute exposed from the LIT library itself that will allow local configs to easily access the root. > > Eli > > > > --------------------------------------------------------------------- > Intel Israel (74) Limited > > This e-mail and any attachments may contain confidential material for > the sole use of the intended recipient(s). Any review or distribution > by others is strictly prohibited. If you are not the intended > recipient, please contact the sender and delete all copies. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From nlewycky at google.com Wed Feb 8 17:06:59 2012 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 8 Feb 2012 15:06:59 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: On 8 February 2012 08:43, David A. Greene wrote: > Duncan Sands writes: > > >> My experience with the C backend says otherwise. I've run across lots > >> of cases where shuffles could not be handled. > > > > then fix the C backend? > > Not possible with the current C backend. It uses illegal types, for > one. > > >> I don't know of any way to generate generic IR and guarantee that the > >> instruction the user selected through an intrinsic will be the > >> instruction selected by LLVM's isel. There are too many transformation > >> steps in-between. > > > > Of course there is no such guarantee. The question is whether doing > things > > using generic IR is mostly a win or not. Maybe today it's often not a > win, > > but since that's fixable it seems to me that the "use generic IR if not > too > > crazy" path is on the whole the right way to go. > > Whether generic IR is a "win" isn't the primary issue here. The issue > is that the user wrote code using intrinsics and expects that exact code > to be in the asm. Whether or not that is the best performing code > possible doesn't matter. It's what they want and we have to respect it. > Our customers demand it. > Okay. This is a different issue then, and isn't even solved by using intrinsics; the optimization passes are absolutely allowed to modify uses of intrinsics. We do this in obvious cases for things like memset or ctz, but there is no reason the optimization passes won't optimize the llvm.x86 intrinsics too. It's rare, but you can see code in ValueTracking.cpp that will analyze Intrinsic::x86_sse42_crc32_64_8 for one example, ConstantFolding.cpp will fold through x86_sse_cvtss2si for another. Suppose you emit code like this: create your own functions with definitions that use the IR implementations, and mark them noinline. At the very end, you inline them with a pass that calls InlineFunction() directly. Does this preserve the order, or do you still have trouble with the backend doing too much reordering? Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/c2f9cec5/attachment.html From anton at korobeynikov.info Wed Feb 8 17:21:57 2012 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Thu, 9 Feb 2012 03:21:57 +0400 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: > I'll have to update it to the latest trunk. It doesn't build at all > right now so I can't check it in. Well, this does not matter I think. Just post the patch saying approx LLVM revision / version it should build and maybe there will be some brave soul which will update all the stuff for you. -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From daniel at zuster.org Wed Feb 8 17:33:40 2012 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 08 Feb 2012 23:33:40 -0000 Subject: [llvm-commits] [zorg] r150113 - in /zorg/trunk/lnt/lnt/server/ui: templates/v4_run.html templates/v4_utils.html views.py Message-ID: <20120208233340.71F4B2A6C12C@llvm.org> Author: ddunbar Date: Wed Feb 8 17:33:40 2012 New Revision: 150113 URL: http://llvm.org/viewvc/llvm-project?rev=150113&view=rev Log: [lnt/v0.4] lnt.server.ui: Add trivial UI for selecting a different run to compare to. Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html zorg/trunk/lnt/lnt/server/ui/templates/v4_utils.html zorg/trunk/lnt/lnt/server/ui/views.py Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html?rev=150113&r1=150112&r2=150113&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html (original) +++ zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html Wed Feb 8 17:33:40 2012 @@ -72,7 +72,8 @@ {% endmacro %} -{% call v4_utils.v4_run_page(ts, machine, run, compare_to, neighboring_runs) %} +{% call v4_utils.v4_run_page(ts, machine, run, compare_to, neighboring_runs, + comparison_neighboring_runs) %} {{ utils.render_popup_begin('view_options', 'View Options', true) }}

      @@ -124,6 +125,10 @@
      +{% if compare_to %} + +{% endif %} +
      Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_utils.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/templates/v4_utils.html?rev=150113&r1=150112&r2=150113&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/templates/v4_utils.html (original) +++ zorg/trunk/lnt/lnt/server/ui/templates/v4_utils.html Wed Feb 8 17:33:40 2012 @@ -1,6 +1,7 @@ {% import "utils.html" as utils %} -{% macro v4_run_page(ts, machine, run, compare_to, neighboring_runs) %} +{% macro v4_run_page(ts, machine, run, compare_to, neighboring_runs, + comparison_neighboring_runs=none) %}
      @@ -43,6 +44,19 @@ ""|safe if r.id == run.id }} {% endfor %} + +{# Show a small number of runs in the neighborhood of the comparison run. #} +{% if comparison_neighboring_runs %} +

      Compare To:

      +
        +{% for r in comparison_neighboring_runs %} +
      • {{ "

        "|safe if r.id == compare_to.id }} + {{ + r.start_time}}{{ + "

        "|safe if r.id == compare_to.id }} +{% endfor %} +
      +{% endif %}
      Modified: zorg/trunk/lnt/lnt/server/ui/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/views.py?rev=150113&r1=150112&r2=150113&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/views.py (original) +++ zorg/trunk/lnt/lnt/server/ui/views.py Wed Feb 8 17:33:40 2012 @@ -790,12 +790,29 @@ # Find the neighboring runs, by order. prev_runs = list(ts.get_previous_runs_on_machine(run, N = 3)) next_runs = list(ts.get_next_runs_on_machine(run, N = 3)) - if prev_runs: - compare_to = prev_runs[0] - else: - compare_to = None neighboring_runs = next_runs[::-1] + [run] + prev_runs + # Select the comparison run as either the previous run, or a user specified + # comparison run. + compare_to_str = request.args.get('compare_to') + if compare_to_str: + compare_to_id = int(compare_to_str) + compare_to = ts.query(ts.Run).filter_by(id = compare_to_id).first() + if compare_to is None: + return render_template("error.html", message="""\ +Invalid compare_to ID %r""" % compare_to_str) + + comparison_neighboring_runs = ( + list(ts.get_next_runs_on_machine(compare_to, N=3))[::-1] + + [compare_to] + + list(ts.get_previous_runs_on_machine(compare_to, N=3))) + else: + if prev_runs: + compare_to = prev_runs[0] + else: + compare_to = None + comparison_neighboring_runs = neighboring_runs + # Parse the view options. options = {} options['show_delta'] = bool(request.args.get('show_delta')) @@ -851,6 +868,7 @@ return render_template( "v4_run.html", ts=ts, run=run, compare_to=compare_to, options=options, neighboring_runs=neighboring_runs, + comparison_neighboring_runs=comparison_neighboring_runs, text_report=text_report, html_report=html_report, primary_fields=list(ts.Sample.get_primary_fields()), comparison_window=comparison_window, From daniel at zuster.org Wed Feb 8 17:33:43 2012 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 08 Feb 2012 23:33:43 -0000 Subject: [llvm-commits] [zorg] r150114 - in /zorg/trunk/lnt/lnt/server/ui: templates/v4_run.html views.py Message-ID: <20120208233343.B79442A6C12C@llvm.org> Author: ddunbar Date: Wed Feb 8 17:33:43 2012 New Revision: 150114 URL: http://llvm.org/viewvc/llvm-project?rev=150114&view=rev Log: [lnt/v0.4] lnt.server.ui: Add an option to filter out tests with a current value below some minimum. Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html zorg/trunk/lnt/lnt/server/ui/views.py Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html?rev=150114&r1=150113&r2=150114&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html (original) +++ zorg/trunk/lnt/lnt/server/ui/templates/v4_run.html Wed Feb 8 17:33:43 2012 @@ -125,6 +125,10 @@
      +Test Min. Value Filter: +
      + {% if compare_to %} {% endif %} @@ -185,6 +189,7 @@ {% set cr = sri.get_run_comparison_result( run, compare_to, test_id, field, comparison_window) %} {% if cr.previous is not none or cr.current is not none %} +{% if cr.current is none or cr.current >= test_min_value_filter %} @@ -192,6 +197,7 @@ test_name}} {{ get_cell_value(cr) }} +{% endif %} {% endif %} {% endfor %}
      Modified: zorg/trunk/lnt/lnt/server/ui/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/views.py?rev=150114&r1=150113&r2=150114&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/views.py (original) +++ zorg/trunk/lnt/lnt/server/ui/views.py Wed Feb 8 17:33:43 2012 @@ -838,6 +838,13 @@ else: test_filter_re = None + options['test_min_value_filter'] = test_min_value_filter_str = \ + request.args.get('test_min_value_filter', '') + if test_min_value_filter_str is not '': + test_min_value_filter = float(test_min_value_filter_str) + else: + test_min_value_filter = 0.0 + # Generate the report for inclusion in the run page. # # FIXME: This is a crummy implementation of the concept that we want the @@ -865,6 +872,12 @@ sri = lnt.server.reporting.analysis.RunInfo(ts) + # Filter the list of tests by name, if requested. + if test_filter_re: + test_names = [test + for test in test_names + if test_filter_re.search(test)] + return render_template( "v4_run.html", ts=ts, run=run, compare_to=compare_to, options=options, neighboring_runs=neighboring_runs, @@ -872,7 +885,8 @@ text_report=text_report, html_report=html_report, primary_fields=list(ts.Sample.get_primary_fields()), comparison_window=comparison_window, - sri=sri, test_info=test_info, runinfo=runinfo) + sri=sri, test_info=test_info, runinfo=runinfo, + test_min_value_filter=test_min_value_filter) @v4_route("/order/") def v4_order(id): From daniel at zuster.org Wed Feb 8 17:33:46 2012 From: daniel at zuster.org (Daniel Dunbar) Date: Wed, 08 Feb 2012 23:33:46 -0000 Subject: [llvm-commits] [zorg] r150115 - in /zorg/trunk/lnt/lnt/server/ui: templates/v4_graph.html views.py Message-ID: <20120208233346.E65A52A6C12C@llvm.org> Author: ddunbar Date: Wed Feb 8 17:33:46 2012 New Revision: 150115 URL: http://llvm.org/viewvc/llvm-project?rev=150115&view=rev Log: [lnt/v0.4] lnt.server.ui: Add an option to normalize graph by median. Useful for plotting different tests side by side. Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_graph.html zorg/trunk/lnt/lnt/server/ui/views.py Modified: zorg/trunk/lnt/lnt/server/ui/templates/v4_graph.html URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/templates/v4_graph.html?rev=150115&r1=150114&r2=150115&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/templates/v4_graph.html (original) +++ zorg/trunk/lnt/lnt/server/ui/templates/v4_graph.html Wed Feb 8 17:33:46 2012 @@ -65,6 +65,10 @@
      +Normalize By Median: +
      + {# Add all the hidden fields. #} {% for name,value in request.args.items() %} {% if name.startswith('test.') %} Modified: zorg/trunk/lnt/lnt/server/ui/views.py URL: http://llvm.org/viewvc/llvm-project/zorg/trunk/lnt/lnt/server/ui/views.py?rev=150115&r1=150114&r2=150115&view=diff ============================================================================== --- zorg/trunk/lnt/lnt/server/ui/views.py (original) +++ zorg/trunk/lnt/lnt/server/ui/views.py Wed Feb 8 17:33:46 2012 @@ -945,6 +945,8 @@ request.args.get('show_linear_regression')) options['show_failures'] = show_failures = bool( request.args.get('show_failures')) + options['normalize_by_median'] = normalize_by_median = bool( + request.args.get('normalize_by_median')) # Load the graph parameters. graph_tests = [] @@ -1033,7 +1035,13 @@ errorbar_data = [] points_data = [] pts = [] - for x,values in data: + if normalize_by_median: + normalize_by = 1.0/stats.median([min(values) + for _,values in data]) + else: + normalize_by = 1.0 + for x,orig_values in data: + values = [v*normalize_by for v in orig_values] min_value = min(values) pts.append((x, min_value)) From dag at cray.com Wed Feb 8 17:50:44 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 17:50:44 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Craig Topper's message of "Wed, 8 Feb 2012 14:22:44 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <91C216B9-0938-45CB-B077-10361711CADC@apple.com> <922F6886-937E-4F96-B1BC-B9CD3D1CD6BC@apple.com> Message-ID: Craig Topper writes: > How do you propose solving the problem without intrinsics? > > Remember that other code in the same Module should be optimized right up > to and before/after each intrinsic. > > This is not an uncommon requirement for compilers.a > > There are already numerous instructions in llvm that have no > intrinsics covering them. For instance, most shufffles (pshud, shufps, > shufpd, vector unpacks, pshuflw, pshufhw), basic vector addition and > subtraction and I'm sure many more. How was this "problem" not notice > before now if its so important? This is why I said I would like *more* intrinsics. In fact I have added quite a few in our local copy. -Dave From dag at cray.com Wed Feb 8 17:54:23 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 17:54:23 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Nick Lewycky's message of "Wed, 8 Feb 2012 15:06:59 -0800") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: Nick Lewycky writes: > Whether generic IR is a "win" isn't the primary issue here. ?The issue > is that the user wrote code using intrinsics and expects that exact code > to be in the asm. ?Whether or not that is the best performing code > possible doesn't matter. ?It's what they want and we have to respect it. > Our customers demand it. > > Okay. This is a different issue then, and isn't even solved by using > intrinsics; the optimization passes are absolutely allowed to modify > uses of intrinsics. We do this in obvious cases for things like memset > or ctz, but there is no reason the optimization passes won't optimize > the llvm.x86 intrinsics too. It's rare, but you can see code in > ValueTracking.cpp that will?analyze?Intrinsic::x86_sse42_crc32_64_8 > for one example, ConstantFolding.cpp will fold > through?x86_sse_cvtss2si for another. That seems like a mistake and is not what I would expect to happen with intrinsics. I can understand why compiler developers might want to do that but some users will be surprised. We need some way to provide the kind of guarantee I'm talking about. > Suppose you emit code like this: create your own functions with > definitions that use the IR implementations, and mark them > noinline. At the very end, you inline them with a pass that calls > InlineFunction() directly. Does this preserve the order, or do you > still have trouble with the backend doing too much reordering? It's not just reordering. Instcombine, dagcombine, etc. do a lot of massaging. Again, what is the trouble with keeping intrinsics? Why rip them out if people find them useful and necessary? If the behavior of the optimizer changes wrt the intrinsics, we can deal with that when it happens. -Dave From dag at cray.com Wed Feb 8 17:55:34 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 17:55:34 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Anton Korobeynikov's message of "Thu, 9 Feb 2012 03:21:57 +0400") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> Message-ID: Anton Korobeynikov writes: >> I'll have to update it to the latest trunk. It doesn't build at all >> right now so I can't check it in. > Well, this does not matter I think. Just post the patch saying approx > LLVM revision / version it should build and maybe there will be some > brave soul which will update all the stuff for you. It shouldn't build against anything right now. I certainly wouldn't want to work on a patch that doesn't even build. I could maybe provide a publicly-accessible git branch. I'll look into that. -Dave From dag at cray.com Wed Feb 8 17:58:05 2012 From: dag at cray.com (David A. Greene) Date: Wed, 08 Feb 2012 17:58:05 -0600 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: <1328741783.2463.129.camel@sapling> (Hal Finkel's message of "Wed, 08 Feb 2012 16:56:23 -0600") References: <114101cce6a4$9ecaaf10$dc600d30$@org> <1328741783.2463.129.camel@sapling> Message-ID: Hal Finkel writes: > It might be worthwhile to have some kind of actual tracking system for > patches. I think this can be done without much overhead by using a > simple script that watches the mailing list. To be specific, how about > the following: > > - When submitting a patch, the e-mail must contain the keywords: > 'PATCH: NEW'. > > - When the script sees replies to that e-mail it will assume that the > patch is being reviewed. It will warn (by sending a mail to the list) if > the mail stops (excluding from the original author) for some extended > period of time without some further state change. Or never starts. That's usually the bigger problem. > - The script will change the state recorded for a patch when it sees a > reply mail with the keywords, 'PATCH: REVISE' [the system is to wait for > a revised patch from the author], 'PATCH: APPLIED r[0-9]+' or 'PATCH: > REJECTED' or 'PATCH: WITHDRAWN'. > > - The script will maintain a database of some kind used by a simple web > app that can be used to view the current state of patches. > > I think that using some system like this we can essentially keep the > current review protocol but also add some useful tracking so that things > don't slip through the cracks. That would be highly useful. It seems pretty complicated, however, and reinventing the wheel/NIH. How about something like gerrit? -Dave From dblaikie at gmail.com Wed Feb 8 18:17:58 2012 From: dblaikie at gmail.com (David Blaikie) Date: Wed, 8 Feb 2012 16:17:58 -0800 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: References: <114101cce6a4$9ecaaf10$dc600d30$@org> <1328741783.2463.129.camel@sapling> Message-ID: On Wed, Feb 8, 2012 at 3:58 PM, David A. Greene wrote: > Hal Finkel writes: > >> It might be worthwhile to have some kind of actual tracking system for >> patches. I think this can be done without much overhead by using a >> simple script that watches the mailing list. To be specific, how about >> the following: >> >> ?- When submitting a patch, the e-mail must contain the keywords: >> 'PATCH: NEW'. >> >> ?- When the script sees replies to that e-mail it will assume that the >> patch is being reviewed. It will warn (by sending a mail to the list) if >> the mail stops (excluding from the original author) for some extended >> period of time without some further state change. > > Or never starts. ?That's usually the bigger problem. > >> ?- The script will change the state recorded for a patch when it sees a >> reply mail with the keywords, 'PATCH: REVISE' [the system is to wait for >> a revised patch from the author], 'PATCH: APPLIED r[0-9]+' or 'PATCH: >> REJECTED' or 'PATCH: WITHDRAWN'. >> >> ?- The script will maintain a database of some kind used by a simple web >> app that can be used to view the current state of patches. >> >> I think that using some system like this we can essentially keep the >> current review protocol but also add some useful tracking so that things >> don't slip through the cracks. > > That would be highly useful. ?It seems pretty complicated, however, and > reinventing the wheel/NIH. ?How about something like gerrit? I believe some people have already been experimenting with a patchwerk variant for the LLVM lists: https://github.com/asl/llvm-patchwork From stoklund at 2pi.dk Wed Feb 8 18:15:39 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 09 Feb 2012 00:15:39 -0000 Subject: [llvm-commits] [llvm] r150116 - /llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Message-ID: <20120209001539.576AC2A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 18:15:39 2012 New Revision: 150116 URL: http://llvm.org/viewvc/llvm-project?rev=150116&view=rev Log: Never delete instructions that define reserved registers. I think this was already the intention, but DeadMachineInstructionElim was accidentally tracking the liveness of reserved registers. Now, instructions with reserved defs are never deleted. This prevents the call stack adjustment instructions from getting deleted when enabling register masks. Modified: llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Modified: llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp?rev=150116&r1=150115&r2=150116&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp (original) +++ llvm/trunk/lib/CodeGen/DeadMachineInstructionElim.cpp Wed Feb 8 18:15:39 2012 @@ -33,6 +33,7 @@ const MachineRegisterInfo *MRI; const TargetInstrInfo *TII; BitVector LivePhysRegs; + BitVector ReservedRegs; public: static char ID; // Pass identification, replacement for typeid @@ -67,10 +68,14 @@ const MachineOperand &MO = MI->getOperand(i); if (MO.isReg() && MO.isDef()) { unsigned Reg = MO.getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg) ? - LivePhysRegs[Reg] : !MRI->use_nodbg_empty(Reg)) { - // This def has a non-debug use. Don't delete the instruction! - return false; + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { + // Don't delete live physreg defs, or any reserved register defs. + if (LivePhysRegs.test(Reg) || ReservedRegs.test(Reg)) + return false; + } else { + if (!MRI->use_nodbg_empty(Reg)) + // This def has a non-debug use. Don't delete the instruction! + return false; } } } @@ -86,7 +91,7 @@ TII = MF.getTarget().getInstrInfo(); // Treat reserved registers as always live. - BitVector ReservedRegs = TRI->getReservedRegs(MF); + ReservedRegs = TRI->getReservedRegs(MF); // Loop over all instructions in all blocks, from bottom to top, so that it's // more likely that chains of dependent but ultimately dead instructions will @@ -173,7 +178,6 @@ } else if (MO.isRegMask()) { // Register mask of preserved registers. All clobbers are dead. LivePhysRegs.clearBitsNotInMask(MO.getRegMask()); - LivePhysRegs |= ReservedRegs; } } // Record the physreg uses, after the defs, in case a physreg is From stoklund at 2pi.dk Wed Feb 8 18:17:22 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 09 Feb 2012 00:17:22 -0000 Subject: [llvm-commits] [llvm] r150117 - /llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Message-ID: <20120209001722.DA2202A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 18:17:22 2012 New Revision: 150117 URL: http://llvm.org/viewvc/llvm-project?rev=150117&view=rev Log: Handle register masks when searching for EFLAGS clobbers. Calls clobber the flags, but when using register masks there is no EFLAGS operand. Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=150117&r1=150116&r2=150117&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original) +++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Wed Feb 8 18:17:22 2012 @@ -1419,6 +1419,8 @@ bool SeenDef = false; for (unsigned j = 0, e = Iter->getNumOperands(); j != e; ++j) { MachineOperand &MO = Iter->getOperand(j); + if (MO.isRegMask() && MO.clobbersPhysReg(X86::EFLAGS)) + SeenDef = true; if (!MO.isReg()) continue; if (MO.getReg() == X86::EFLAGS) { @@ -1463,6 +1465,10 @@ bool SawKill = false; for (unsigned j = 0, e = Iter->getNumOperands(); j != e; ++j) { MachineOperand &MO = Iter->getOperand(j); + // A register mask may clobber EFLAGS, but we should still look for a + // live EFLAGS def. + if (MO.isRegMask() && MO.clobbersPhysReg(X86::EFLAGS)) + SawKill = true; if (MO.isReg() && MO.getReg() == X86::EFLAGS) { if (MO.isDef()) return MO.isDead(); if (MO.isKill()) SawKill = true; From stoklund at 2pi.dk Wed Feb 8 18:19:08 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 09 Feb 2012 00:19:08 -0000 Subject: [llvm-commits] [llvm] r150118 - /llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Message-ID: <20120209001908.753E12A6C12C@llvm.org> Author: stoklund Date: Wed Feb 8 18:19:08 2012 New Revision: 150118 URL: http://llvm.org/viewvc/llvm-project?rev=150118&view=rev Log: Erase dead copies that are clobbered by a call. This does make a difference, at least when using RABasic. Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Modified: llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=150118&r1=150117&r2=150118&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp Wed Feb 8 18:19:08 2012 @@ -191,11 +191,11 @@ // Not a copy. SmallVector Defs; - bool HasRegMask = false; + int RegMaskOpNum = -1; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { MachineOperand &MO = MI->getOperand(i); if (MO.isRegMask()) - HasRegMask = true; + RegMaskOpNum = i; if (!MO.isReg()) continue; unsigned Reg = MO.getReg(); @@ -227,9 +227,21 @@ // a large set of registers. It is possible to use the register mask to // prune the available copies, but treat it like a basic block boundary for // now. - if (HasRegMask) { - // FIXME: We could possibly erase some MaybeDeadCopies if their registers - // are clobbered by the mask. + if (RegMaskOpNum >= 0) { + // Erase any MaybeDeadCopies whose destination register is clobbered. + const MachineOperand &MaskMO = MI->getOperand(RegMaskOpNum); + for (SmallSetVector::iterator + DI = MaybeDeadCopies.begin(), DE = MaybeDeadCopies.end(); + DI != DE; ++DI) { + unsigned Reg = (*DI)->getOperand(0).getReg(); + if (ReservedRegs.test(Reg) || !MaskMO.clobbersPhysReg(Reg)) + continue; + (*DI)->eraseFromParent(); + Changed = true; + ++NumDeletes; + } + + // Clear all data structures as if we were beginning a new basic block. MaybeDeadCopies.clear(); AvailCopyMap.clear(); CopyMap.clear(); From dblaikie at gmail.com Wed Feb 8 18:29:19 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 09 Feb 2012 00:29:19 -0000 Subject: [llvm-commits] [llvm] r150120 - /llvm/trunk/lib/Support/DataStream.cpp Message-ID: <20120209002919.34FC92A6C12C@llvm.org> Author: dblaikie Date: Wed Feb 8 18:29:19 2012 New Revision: 150120 URL: http://llvm.org/viewvc/llvm-project?rev=150120&view=rev Log: Remove static initializer from DataStream.cpp If someone would prefer a clear name for the 'success' error_value we could come up with one - potentially just a 'named constructor' style 'error_value::success()' to make this expression more self-documenting. If I see this come up in other cases I'll certainly consider it. One step along the way to resolving PR11944. Modified: llvm/trunk/lib/Support/DataStream.cpp Modified: llvm/trunk/lib/Support/DataStream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=150120&r1=150119&r2=150120&view=diff ============================================================================== --- llvm/trunk/lib/Support/DataStream.cpp (original) +++ llvm/trunk/lib/Support/DataStream.cpp Wed Feb 8 18:29:19 2012 @@ -49,8 +49,6 @@ namespace { -const static error_code success; - // Very simple stream backed by a file. Mostly useful for stdin and debugging; // actual file access is probably still best done with mmap. class DataFileStreamer : public DataStreamer { @@ -66,18 +64,20 @@ } error_code OpenFile(const std::string &Filename) { - int OpenFlags = O_RDONLY; -#ifdef O_BINARY - OpenFlags |= O_BINARY; // Open input file in binary mode on win32. -#endif if (Filename == "-") { Fd = 0; sys::Program::ChangeStdinToBinary(); + return error_code(); } - else - Fd = ::open(Filename.c_str(), OpenFlags); - if (Fd == -1) return error_code(errno, posix_category()); - return success; + + int OpenFlags = O_RDONLY; +#ifdef O_BINARY + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. +#endif + Fd = ::open(Filename.c_str(), OpenFlags); + if (Fd == -1) + return error_code(errno, posix_category()); + return error_code(); } }; @@ -87,8 +87,7 @@ DataStreamer *getDataFileStreamer(const std::string &Filename, std::string *StrError) { DataFileStreamer *s = new DataFileStreamer(); - error_code e = s->OpenFile(Filename); - if (e != success) { + if (error_code e = s->OpenFile(Filename)) { *StrError = std::string("Could not open ") + Filename + ": " + e.message() + "\n"; return NULL; From nlewycky at google.com Wed Feb 8 18:33:54 2012 From: nlewycky at google.com (Nick Lewycky) Date: Wed, 8 Feb 2012 16:33:54 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: On 8 February 2012 15:54, David A. Greene wrote: > Nick Lewycky writes: > > > Whether generic IR is a "win" isn't the primary issue here. The > issue > > is that the user wrote code using intrinsics and expects that exact > code > > to be in the asm. Whether or not that is the best performing code > > possible doesn't matter. It's what they want and we have to respect > it. > > Our customers demand it. > > > > Okay. This is a different issue then, and isn't even solved by using > > intrinsics; the optimization passes are absolutely allowed to modify > > uses of intrinsics. We do this in obvious cases for things like memset > > or ctz, but there is no reason the optimization passes won't optimize > > the llvm.x86 intrinsics too. It's rare, but you can see code in > > ValueTracking.cpp that will analyze Intrinsic::x86_sse42_crc32_64_8 > > for one example, ConstantFolding.cpp will fold > > through x86_sse_cvtss2si for another. > > That seems like a mistake and is not what I would expect to happen with > intrinsics. I can understand why compiler developers might want to do > that but some users will be surprised. > No, it's not the compiler developers. Our programmers expect the compiler to be capable of comprehending what the builtins mean and perform constant folding, licm, etc., and will file bugs when we don't emit optimal code. We need some way to provide the kind of guarantee I'm talking about. > Yep. > Suppose you emit code like this: create your own functions with > > definitions that use the IR implementations, and mark them > > noinline. At the very end, you inline them with a pass that calls > > InlineFunction() directly. Does this preserve the order, or do you > > still have trouble with the backend doing too much reordering? > > It's not just reordering. Instcombine, dagcombine, etc. do a lot of > massaging. > Sure, but with what I proposed instcombine can't touch them (technically it *can*, but it won't do anything since each little intrinsic definition is already locally optimal). If you really have problems with the IR-level optimizers messing with them, you can make the functions declarations until you reach your IR-level pass, filling in their function bodies just before you run InlineFunction. However, DAGCombine might fold them. If this is a problem in practice, my next idea is to wrap the functions in compiler barriers. Would that sufficient to prevent the problems you'd have? Again, what is the trouble with keeping intrinsics? Why rip them out if > people find them useful and necessary? If the behavior of the optimizer > changes wrt the intrinsics, we can deal with that when it happens. > Your argument that the intrinsics are useful is falling flat because the use-case you've given is not one that would be solved by the presence of intrinsics. Just having intrinsics doesn't guarantee that they won't be "massaged" by the compiler. Also, waiting until you encounter a problem with the optimizer is only deferring the problem; when you bring up that issue the response will be "working as intended" and we'll be right back here. It's entirely possible that the solution to your problem will involve intrinsics, but we have to work out exactly what. We could try adding an i1 flag to the intrinsics that indicate whether it should be treated as volatile. We could add a volatile bit to the IntrinsicInst/CallInst, maybe. We could add a new bit to some immutable spot (similar to TargetLibraryInfo) to indicate whether intrinsics are sacred or not. We could turn it around and say that the compiler may not optimize intrinsics except in a single pass, much like how only SimplifyLibCalls was only place allowed to assume that C functions had the behaviour their names implied (before we had TargetLibraryInfo). I'm trying to start with approaches that serve your use-case with the minimal change to LLVM first. Nick -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/a9674cf8/attachment.html From atrick at apple.com Wed Feb 8 18:40:52 2012 From: atrick at apple.com (Andrew Trick) Date: Thu, 09 Feb 2012 00:40:52 -0000 Subject: [llvm-commits] [llvm] r150121 - /llvm/trunk/lib/CodeGen/MachineScheduler.cpp Message-ID: <20120209004052.563092A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 18:40:52 2012 New Revision: 150121 URL: http://llvm.org/viewvc/llvm-project?rev=150121&view=rev Log: comment Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp Modified: llvm/trunk/lib/CodeGen/MachineScheduler.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineScheduler.cpp?rev=150121&r1=150120&r2=150121&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineScheduler.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineScheduler.cpp Wed Feb 8 18:40:52 2012 @@ -154,7 +154,7 @@ //===----------------------------------------------------------------------===// namespace { -/// MachineScheduler is an implementation of ScheduleDAGInstrs that schedules +/// ScheduleTopDownLive is an implementation of ScheduleDAGInstrs that schedules /// machine instructions while updating LiveIntervals. class ScheduleTopDownLive : public ScheduleDAGInstrs { protected: From atrick at apple.com Wed Feb 8 18:40:55 2012 From: atrick at apple.com (Andrew Trick) Date: Thu, 09 Feb 2012 00:40:55 -0000 Subject: [llvm-commits] [llvm] r150122 - in /llvm/trunk: include/llvm/CodeGen/Passes.h lib/CodeGen/Passes.cpp Message-ID: <20120209004055.BDAD42A6C12C@llvm.org> Author: atrick Date: Wed Feb 8 18:40:55 2012 New Revision: 150122 URL: http://llvm.org/viewvc/llvm-project?rev=150122&view=rev Log: Improve TargetPassConfig. No intended functionality. Split CodeGen into stages. Distinguish between optimization and correctness. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/lib/CodeGen/Passes.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150122&r1=150121&r2=150122&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Feb 8 18:40:55 2012 @@ -111,6 +111,10 @@ return true; } + /// addMachineSSAOptimization - Add standard passes that optimize machine + /// instructions in SSA form. + virtual void addMachineSSAOptimization(); + /// addPreRegAlloc - This method may be implemented by targets that want to /// run passes immediately before register allocation. This should return /// true if -print-machineinstrs should print after these passes. @@ -118,6 +122,9 @@ return false; } + // addRegAlloc - Add standard passes related to register allocation. + virtual void addRegAlloc(); + /// addPostRegAlloc - This method may be implemented by targets that want /// to run passes after register allocation but before prolog-epilog /// insertion. This should return true if -print-machineinstrs should print @@ -126,6 +133,9 @@ return false; } + /// Add passes that optimize machine instructions after register allocation. + virtual void addMachineLateOptimization(); + /// addPreSched2 - This method may be implemented by targets that want to /// run passes after prolog-epilog insertion and before the second instruction /// scheduling pass. This should return true if -print-machineinstrs should @@ -134,6 +144,9 @@ return false; } + /// Add standard basic block placement passes. + virtual void addBlockPlacement(); + /// addPreEmitPass - This pass may be implemented by targets that want to run /// passes immediately before machine code is emitted. This should return /// true if -print-machineinstrs should print out the code after the passes. Modified: llvm/trunk/lib/CodeGen/Passes.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/Passes.cpp?rev=150122&r1=150121&r2=150122&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/Passes.cpp (original) +++ llvm/trunk/lib/CodeGen/Passes.cpp Wed Feb 8 18:40:55 2012 @@ -184,6 +184,24 @@ PM.add(createVerifierPass()); } +/// Add the complete set of target-independent postISel code generator passes. +/// +/// This can be read as the standard order of major LLVM CodeGen stages. Stages +/// with nontrivial configuration or multiple passes are broken out below in +/// add%Stage routines. +/// +/// Any TargetPassConfig::addXX routine may be overriden by the Target. The +/// addPre/Post methods with empty header implementations allow injecting +/// target-specific fixups just before or after major stages. Additionally, +/// targets have the flexibility to change pass order within a stage by +/// overriding default implementation of add%Stage routines below. Each +/// technique has maintainability tradeoffs because alternate pass orders are +/// not well supported. addPre/Post works better if the target pass is easily +/// tied to a common pass. But if it has subtle dependencies on multiple passes, +/// overriding the stage instead. +/// +/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection +/// before/after any target-independent pass. But it's currently overkill. void TargetPassConfig::addMachinePasses() { // Print the instruction selected machine code... printAndVerify("After Instruction Selection"); @@ -191,63 +209,23 @@ // Expand pseudo-instructions emitted by ISel. addPass(ExpandISelPseudosID); - // Pre-ra tail duplication. - if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { - addPass(TailDuplicateID); - printAndVerify("After Pre-RegAlloc TailDuplicate"); - } - - // Optimize PHIs before DCE: removing dead PHI cycles may make more - // instructions dead. - if (getOptLevel() != CodeGenOpt::None) - addPass(OptimizePHIsID); - - // If the target requests it, assign local variables to stack slots relative - // to one another and simplify frame index references where possible. - addPass(LocalStackSlotAllocationID); - + // Add passes that optimize machine instructions in SSA form. if (getOptLevel() != CodeGenOpt::None) { - // With optimization, dead code should already be eliminated. However - // there is one known exception: lowered code for arguments that are only - // used by tail calls, where the tail calls reuse the incoming stack - // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). - if (!DisableMachineDCE) - addPass(DeadMachineInstructionElimID); - printAndVerify("After codegen DCE pass"); - - if (!DisableMachineLICM) - addPass(MachineLICMID); - if (!DisableMachineCSE) - addPass(MachineCSEID); - if (!DisableMachineSink) - addPass(MachineSinkingID); - printAndVerify("After Machine LICM, CSE and Sinking passes"); - - addPass(PeepholeOptimizerID); - printAndVerify("After codegen peephole optimization pass"); + addMachineSSAOptimization(); + } + else { + // If the target requests it, assign local variables to stack slots relative + // to one another and simplify frame index references where possible. + addPass(LocalStackSlotAllocationID); } // Run pre-ra passes. if (addPreRegAlloc()) printAndVerify("After PreRegAlloc passes"); - // Perform register allocation. - PM.add(createRegisterAllocator(getOptLevel())); - printAndVerify("After Register Allocation"); - - // Perform stack slot coloring and post-ra machine LICM. - if (getOptLevel() != CodeGenOpt::None) { - // FIXME: Re-enable coloring with register when it's capable of adding - // kill markers. - if (!DisableSSC) - addPass(StackSlotColoringID); - - // Run post-ra machine LICM to hoist reloads / remats. - if (!DisablePostRAMachineLICM) - addPass(MachineLICMID); - - printAndVerify("After StackSlotColoring and postra Machine LICM"); - } + // Run register allocation and passes that are tightly coupled with it, + // including phi elimination and scheduling. + addRegAlloc(); // Run post-ra passes. if (addPostRegAlloc()) @@ -257,23 +235,9 @@ addPass(PrologEpilogCodeInserterID); printAndVerify("After PrologEpilogCodeInserter"); - // Branch folding must be run after regalloc and prolog/epilog insertion. - if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { - addPass(BranchFolderPassID); - printNoVerify("After BranchFolding"); - } - - // Tail duplication. - if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { - addPass(TailDuplicateID); - printNoVerify("After TailDuplicate"); - } - - // Copy propagation. - if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { - addPass(MachineCopyPropagationID); - printNoVerify("After copy propagation pass"); - } + /// Add passes that optimize machine instructions after register allocation. + if (getOptLevel() != CodeGenOpt::None) + addMachineLateOptimization(); // Expand pseudo instructions before second scheduling pass. addPass(ExpandPostRAPseudosID); @@ -289,52 +253,71 @@ printNoVerify("After PostRAScheduler"); } + // GC addPass(GCMachineCodeAnalysisID); - if (PrintGCInfo) PM.add(createGCInfoPrinter(dbgs())); - if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) { - if (EnableBlockPlacement) { - // MachineBlockPlacement is an experimental pass which is disabled by - // default currently. Eventually it should subsume CodePlacementOpt, so - // when enabled, the other is disabled. - addPass(MachineBlockPlacementID); - printNoVerify("After MachineBlockPlacement"); - } else { - addPass(CodePlacementOptID); - printNoVerify("After CodePlacementOpt"); - } - - // Run a separate pass to collect block placement statistics. - if (EnableBlockPlacementStats) { - addPass(MachineBlockPlacementStatsID); - printNoVerify("After MachineBlockPlacementStats"); - } - } + // Basic block placement. + if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) + addBlockPlacement(); if (addPreEmitPass()) printNoVerify("After PreEmit passes"); } +/// Add passes that optimize machine instructions in SSA form. +void TargetPassConfig::addMachineSSAOptimization() { + // Pre-ra tail duplication. + if (!DisableEarlyTailDup) { + addPass(TailDuplicateID); + printAndVerify("After Pre-RegAlloc TailDuplicate"); + } + + // Optimize PHIs before DCE: removing dead PHI cycles may make more + // instructions dead. + addPass(OptimizePHIsID); + + // If the target requests it, assign local variables to stack slots relative + // to one another and simplify frame index references where possible. + addPass(LocalStackSlotAllocationID); + + // With optimization, dead code should already be eliminated. However + // there is one known exception: lowered code for arguments that are only + // used by tail calls, where the tail calls reuse the incoming stack + // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). + if (!DisableMachineDCE) + addPass(DeadMachineInstructionElimID); + printAndVerify("After codegen DCE pass"); + + if (!DisableMachineLICM) + addPass(MachineLICMID); + if (!DisableMachineCSE) + addPass(MachineCSEID); + if (!DisableMachineSink) + addPass(MachineSinkingID); + printAndVerify("After Machine LICM, CSE and Sinking passes"); + + addPass(PeepholeOptimizerID); + printAndVerify("After codegen peephole optimization pass"); +} + //===---------------------------------------------------------------------===// -/// -/// RegisterRegAlloc class - Track the registration of register allocators. -/// +/// Register Allocation Pass Configuration //===---------------------------------------------------------------------===// + +/// RegisterRegAlloc's global Registry tracks allocator registration. MachinePassRegistry RegisterRegAlloc::Registry; +/// A dummy default pass factory indicates whether the register allocator is +/// overridden on the command line. static FunctionPass *createDefaultRegisterAllocator() { return 0; } static RegisterRegAlloc defaultRegAlloc("default", "pick register allocator based on -O option", createDefaultRegisterAllocator); -//===---------------------------------------------------------------------===// -/// -/// RegAlloc command line options. -/// -//===---------------------------------------------------------------------===// +/// -regalloc=... command line option. static cl::opt > RegAlloc("regalloc", @@ -342,11 +325,7 @@ cl::desc("Register allocator to use")); -//===---------------------------------------------------------------------===// -/// /// createRegisterAllocator - choose the appropriate register allocator. -/// -//===---------------------------------------------------------------------===// FunctionPass *llvm::createRegisterAllocator(CodeGenOpt::Level OptLevel) { RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault(); @@ -366,3 +345,75 @@ return createGreedyRegisterAllocator(); } } + +/// Add standard target-independent passes that are tightly coupled with +/// register allocation, including coalescing, machine instruction scheduling, +/// and register allocation itself. +/// +/// FIXME: This will become the register allocation "super pass" pipeline. +void TargetPassConfig::addRegAlloc() { + // Perform register allocation. + PM.add(createRegisterAllocator(getOptLevel())); + printAndVerify("After Register Allocation"); + + // Perform stack slot coloring and post-ra machine LICM. + if (getOptLevel() != CodeGenOpt::None) { + // FIXME: Re-enable coloring with register when it's capable of adding + // kill markers. + if (!DisableSSC) + addPass(StackSlotColoringID); + + // Run post-ra machine LICM to hoist reloads / remats. + // + // FIXME: can this move into MachineLateOptimization? + if (!DisablePostRAMachineLICM) + addPass(MachineLICMID); + + printAndVerify("After StackSlotColoring and postra Machine LICM"); + } +} + +//===---------------------------------------------------------------------===// +/// Post RegAlloc Pass Configuration +//===---------------------------------------------------------------------===// + +/// Add passes that optimize machine instructions after register allocation. +void TargetPassConfig::addMachineLateOptimization() { + // Branch folding must be run after regalloc and prolog/epilog insertion. + if (!DisableBranchFold) { + addPass(BranchFolderPassID); + printNoVerify("After BranchFolding"); + } + + // Tail duplication. + if (!DisableTailDuplicate) { + addPass(TailDuplicateID); + printNoVerify("After TailDuplicate"); + } + + // Copy propagation. + if (!DisableCopyProp) { + addPass(MachineCopyPropagationID); + printNoVerify("After copy propagation pass"); + } +} + +/// Add standard basic block placement passes. +void TargetPassConfig::addBlockPlacement() { + if (EnableBlockPlacement) { + // MachineBlockPlacement is an experimental pass which is disabled by + // default currently. Eventually it should subsume CodePlacementOpt, so + // when enabled, the other is disabled. + addPass(MachineBlockPlacementID); + printNoVerify("After MachineBlockPlacement"); + } else { + addPass(CodePlacementOptID); + printNoVerify("After CodePlacementOpt"); + } + + // Run a separate pass to collect block placement statistics. + if (EnableBlockPlacementStats) { + addPass(MachineBlockPlacementStatsID); + printNoVerify("After MachineBlockPlacementStats"); + } +} From andrew.kaylor at intel.com Wed Feb 8 18:55:43 2012 From: andrew.kaylor at intel.com (Kaylor, Andrew) Date: Thu, 9 Feb 2012 00:55:43 +0000 Subject: [llvm-commits] RuntimeDyLd new features In-Reply-To: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> References: <6AE1604EE3EC5F4296C096518C6B77EE1AA5238F8A@mail.accesssoftek.com> Message-ID: <0983E6C011D2DC4188F8761B533492DE04EA17@ORSMSX105.amr.corp.intel.com> Hi Danil, Thanks for your efforts in this area. As Eli Bendersky mentioned, we have a patch out for review in this area also. I'm hopeful that we can find a convergence between our code, your code and the code that Jim Grosbach has put in place. Unfortunately, we have been submitting our code in small chunks for ease of review and to keep things stable, and it may not be obvious from what we've put out for review what our intentions were or our intended solutions to the problems that were left open. I'd like to take this opportunity to discuss the direction we we're heading and see how it might align with what you and Jim have done. Let me first explain what we have done, and then I'll offer specific comments on your code and possible next steps. We have had two primary goals: (1) to get MCJIT generated code to work correctly on Intel architecture and help pave the way for other implementations and (2) enable source-level debugging of JITed code with GDB. This second goal seems to be dropping from view, but it places a few constraints on the eventual implementation. We've had GDB integration working, BTW. In order to get GDB to handle JITed code, we need to register an ELF object image through an interface GDB defines. As you might expect, GDB has some peculiar expectations for what this ELF object image should look like. In particular, we need to set a flag in the ELF header and update the sh_addr members in the section headers to reflect the address where the section contents reside in memory. Our most recent patch (http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120130/135997.html, not yet committed) begins by copying the entire ELF image emitted by the MC code generator into an executable buffer. This was intended as a temporary step toward our eventual solution. It enabled us to perform relocations in-place on the object and execute functions in place (thus eliminating an extra copy that was previously being done). We were in the process of implementing a smarter section-based approach, but Jim Grosbach was implementing a similar approach in parallel and our submission ended up appearing out of step in this regard. So that's our background. Now, returning to your patch.... I like the idea of combining as much common code as possible into the RuntimeDyldImpl class. I'm interested to hear from users of the MachO loader if your implementation has lost any of the specialization that they need. I think it's a promising approach. There are some ELF-specific details that we will need to have incorporated to re-enable GDB integration, but I expect that we'll be able to find a way to work that in with a few well-placed overloaded function calls. I have some reservations about the use of the basic ObjectFile interface, which has some serious limitations. We've been working toward exposing the ELFObjectFile template for use in the runtime loading process (as well as other unrelated uses). It may be that this is something that can be generalized enough to fit with your approach. My main concern in this regard is that we need to be able to update specific entries in the ELF image, as described above. A related issue is that section loading can be refined with some ELF-specific details. Some sections need to have memory allocated for their contents. Other sections can be left in place in the originally generated image. There is a good bit of unnecessary copying going on in the existing implementation, and I'm not clear to what extent your patch addresses that. Before the object is loaded, it is copied into a new buffer and then the contents of each section are copied again as we go. What I'd like is for the runtime loaders to use the buffer into which the object is originally generated and only make copies where it is strictly necessary. This isn't necessarily something you need to do for your work to be acceptable, but I mention it as a likely next step. Over the next few days I intend to apply your patch locally and try to merge our work into it. I'll provide additional feedback as I get a better feel for what you've done. -Andy From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-bounces at cs.uiuc.edu] On Behalf Of Danil Malyshev Sent: Tuesday, February 07, 2012 12:24 PM To: llvm-commits at cs.uiuc.edu Subject: [llvm-commits] RuntimeDyLd new features Hello everyone, Please review the RuntimeDyLd-01.patch. This patch makes the following changes: 1. The main works will made in the RuntimeDyLdImpl with uses the ObjectFile class. RuntimeDyLdMachO and RuntimeDyLdELF now only parses relocations and resolve it. This is allows to make improvements of the RuntimeDyLd more easily. In addition the support for COFF can be easily added. 2. Added ARM relocations to RuntimeDyLdELF. 3. Added support for stub functions for the ARM, allowing to do a long branch. 4. Added support for external functions that are not loaded from the object files, but can be loaded from external libraries. Now MCJIT can correctly execute the code containing the printf, putc, and etc. 5. The sections emitted instead functions, thanks Jim Grosbach. MemoryManager.startFunctionBody() and MemoryManager.endFunctionBody() have been removed. 6. MCJITMemoryManager.allocateDataSection() and MCJITMemoryManager. allocateCodeSection() used JMM->allocateSpace() instead of JMM->allocateCodeSection() and JMM->allocateDataSection(), because I got an error: "Cannot allocate an allocated block!" with object file contains more than one code or data sections. 7. Fixed ELF::R_X86_64_PC32 relocation for the case when RealOffset is negative value. 8. Added new testing folder: ExecutionEngine/MCJIT because mcjit tests can be running only for x86 and arm and it's can be filtered with dg.exp. Tested in Ubuntu x86_64, Ubuntu armv7 and MacOS 64. Thank you, Danil -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/ee6aad2e/attachment-0001.html From dreynaud at apple.com Wed Feb 8 19:18:34 2012 From: dreynaud at apple.com (Daniel Reynaud) Date: Wed, 08 Feb 2012 17:18:34 -0800 Subject: [llvm-commits] Please review: make bugpoint aware of blockaddress constant in global initializers In-Reply-To: References: <14C08D85-E7F7-44DE-8260-706F4C9489D4@apple.com> Message-ID: On Feb 8, 2012, at 3:05 PM, Eli Friedman wrote: > On Wed, Feb 8, 2012 at 2:56 PM, Daniel Reynaud wrote: >> >> On Feb 7, 2012, at 5:44 PM, Eli Friedman wrote: >> >>> On Tue, Feb 7, 2012 at 5:21 PM, Daniel Reynaud wrote: >>>> Even better with the actual patch. >>>> >>>> >>>> >>>> On Feb 7, 2012, at 5:20 PM, Daniel Reynaud wrote: >>>> >>>> This is a patch for http://llvm.org/bugs/show_bug.cgi?id=11919 >>>> >>>> It seems to do the trick for me. When this particular configuration (a >>>> global initializer references a blockaddress from a function that has been >>>> sent to a different module) is not encountered, it should produce the same >>>> initializer pattern as usual (i.e., everything in the safe module). >>>> >>>> thanks, >>>> daniel >>> >>> + bool globalInitUsesExternalBA(GlobalVariable* GV) { >>> + if (!GV->hasInitializer()) >>> + return false; >>> + >>> + Constant *I = GV->getInitializer(); >>> + >>> + // walk the values used by the initializer >>> + // (and recurse into things like ConstantExpr) >>> + std::vector Worklist; >>> + Worklist.push_back(I); >>> + while(!Worklist.empty()) { >>> + Constant* V = Worklist.back(); >>> + Worklist.pop_back(); >>> + >>> + if (BlockAddress *BA = dyn_cast(V)) { >>> + Function *F = BA->getFunction(); >>> + if (F->isDeclaration()) >>> + return true; >>> + } >>> + >>> + for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) >>> + if (Constant *C = dyn_cast(*i)) >>> + Worklist.push_back(C); >>> + } >>> + >>> + return false; >>> + } >>> >>> You need to make sure not to recurse into GlobalValues. >> >> ok >> >>> You also >>> probably want a hashtable so you don't run into bad performance >>> characteristics with ConstantExprs. >> >> ok. I tried putting various things in the cache (everything, nothing, just ConstantExpr), and it did not have any noticeable impact on my test case (76s to reduce 459 functions). > > I'm not really worried about the performance of normal cases; the > issue is that there are some pathological cases which can cause the > naive approach to to take exponential time. > >>> >>> Also, weird indentation. >>> >>> >>> + // Try to split the global initializers evenly >>> + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); >>> + I != E; ++I) { >>> + GlobalVariable *GV = cast(NewVMap[I]); >>> + if (globalInitUsesExternalBA(I)) { >>> + assert(!globalInitUsesExternalBA(GV) && "A global initializer references" >>> + "functions in both the safe and the test module"); >>> >>> I don't see what prevents this assertion from triggering? >> >> nothing indeed. If a global initializer references blockaddresses across modules, I don't think we can split. > > True; we should at least give a proper error message, though. Now with a proper error message then. -------------- next part -------------- A non-text attachment was scrubbed... Name: bugpoint.patch Type: application/octet-stream Size: 3236 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120208/ea803133/attachment.obj From lhames at gmail.com Wed Feb 8 22:39:48 2012 From: lhames at gmail.com (Lang Hames) Date: Thu, 09 Feb 2012 04:39:48 -0000 Subject: [llvm-commits] [llvm] r150149 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120209043948.4B0C12A6C12C@llvm.org> Author: lhames Date: Wed Feb 8 22:39:48 2012 New Revision: 150149 URL: http://llvm.org/viewvc/llvm-project?rev=150149&view=rev Log: Remove assertion. Not all use operands are reads. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150149&r1=150148&r2=150149&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Feb 8 22:39:48 2012 @@ -940,9 +940,6 @@ if (!mop.isReg() || mop.getReg() == 0) continue; unsigned reg = mop.getReg(); - if (mop.isUse()) { - assert(mop.readsReg()); - } if (mop.readsReg() && !ecs.count(reg)) { uses.insert(reg); From lhames at gmail.com Wed Feb 8 22:45:38 2012 From: lhames at gmail.com (Lang Hames) Date: Thu, 09 Feb 2012 04:45:38 -0000 Subject: [llvm-commits] [llvm] r150150 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120209044538.93EBD2A6C12C@llvm.org> Author: lhames Date: Wed Feb 8 22:45:38 2012 New Revision: 150150 URL: http://llvm.org/viewvc/llvm-project?rev=150150&view=rev Log: Fix kill flags when moving instructions using LiveIntervals::moveInstr(...). Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150150&r1=150149&r2=150150&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Wed Feb 8 22:45:38 2012 @@ -854,9 +854,21 @@ } } +static void moveKillFlags(unsigned reg, SlotIndex oldIdx, SlotIndex newIdx, + LiveIntervals& lis, + const TargetRegisterInfo& tri) { + MachineInstr* oldKillMI = lis.getInstructionFromIndex(oldIdx); + MachineInstr* newKillMI = lis.getInstructionFromIndex(newIdx); + assert(oldKillMI->killsRegister(reg) && "Old 'kill' instr isn't a kill."); + assert(!newKillMI->killsRegister(reg) && "New kill instr is already a kill."); + oldKillMI->clearRegisterKills(reg, &tri); + newKillMI->addRegisterKilled(reg, &tri); +} + template static void handleMoveUses(const MachineBasicBlock *mbb, const MachineRegisterInfo& mri, + const TargetRegisterInfo& tri, const BitVector& reservedRegs, LiveIntervals &lis, SlotIndex origIdx, SlotIndex miIdx, const UseSetT &uses) { @@ -887,10 +899,15 @@ const MachineOperand& mop = useI.getOperand(); SlotIndex instSlot = lis.getSlotIndexes()->getInstructionIndex(mopI); SlotIndex opSlot = instSlot.getRegSlot(mop.isEarlyClobber()); - if (opSlot >= lastUseInRange && opSlot < origIdx) { + if (opSlot > lastUseInRange && opSlot < origIdx) lastUseInRange = opSlot; - } } + + // If we found a new instr endpoint update the kill flags. + if (lastUseInRange != miIdx.getRegSlot()) + moveKillFlags(use, miIdx, lastUseInRange, lis, tri); + + // Fix up the range end. lr->end = lastUseInRange; } } else { @@ -902,6 +919,7 @@ } else { bool liveOut = lr->end >= lis.getSlotIndexes()->getMBBEndIdx(mbb); if (!liveOut && miIdx.getRegSlot() > lr->end) { + moveKillFlags(use, lr->end, miIdx, lis, tri); lr->end = miIdx.getRegSlot(); } } @@ -923,8 +941,7 @@ // Move the machine instr and obtain its new index. indexes_->removeMachineInstrFromMaps(mi); - mbb->remove(mi); - mbb->insert(insertPt, mi); + mbb->splice(insertPt, mbb, mi); SlotIndex miIdx = indexes_->insertMachineInstrInMaps(mi); // Pick the direction. @@ -961,7 +978,7 @@ BitVector reservedRegs(tri_->getReservedRegs(*mbb->getParent())); if (movingUp) { - handleMoveUses(mbb, *mri_, reservedRegs, *this, origIdx, miIdx, uses); + handleMoveUses(mbb, *mri_, *tri_, reservedRegs, *this, origIdx, miIdx, uses); handleMoveECs(*this, origIdx, miIdx, ecs); handleMoveDeadDefs(*this, origIdx, miIdx, deadDefs); handleMoveDefs(*this, origIdx, miIdx, defs); @@ -969,7 +986,7 @@ handleMoveDefs(*this, origIdx, miIdx, defs); handleMoveDeadDefs(*this, origIdx, miIdx, deadDefs); handleMoveECs(*this, origIdx, miIdx, ecs); - handleMoveUses(mbb, *mri_, reservedRegs, *this, origIdx, miIdx, uses); + handleMoveUses(mbb, *mri_, *tri_, reservedRegs, *this, origIdx, miIdx, uses); } } From geek4civic at gmail.com Wed Feb 8 23:12:58 2012 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 09 Feb 2012 05:12:58 -0000 Subject: [llvm-commits] [llvm] r150151 - /llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Message-ID: <20120209051258.E14BE2A6C12C@llvm.org> Author: chapuni Date: Wed Feb 8 23:12:58 2012 New Revision: 150151 URL: http://llvm.org/viewvc/llvm-project?rev=150151&view=rev Log: test/CodeGen/X86/atom-lea-sp.ll: Add explicit -mtriple=i686-linux. Modified: llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Modified: llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll?rev=150151&r1=150150&r2=150151&view=diff ============================================================================== --- llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll (original) +++ llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll Wed Feb 8 23:12:58 2012 @@ -1,5 +1,5 @@ -; RUN: llc < %s -mcpu=atom -march=x86 | FileCheck -check-prefix=atom %s -; RUN: llc < %s -mcpu=core2 -march=x86 | FileCheck %s +; RUN: llc < %s -mcpu=atom -mtriple=i686-linux | FileCheck -check-prefix=atom %s +; RUN: llc < %s -mcpu=core2 -mtriple=i686-linux | FileCheck %s declare void @use_arr(i8*) declare void @many_params(i32, i32, i32, i32, i32, i32) From geek4civic at gmail.com Wed Feb 8 23:22:50 2012 From: geek4civic at gmail.com (NAKAMURA Takumi) Date: Thu, 9 Feb 2012 14:22:50 +0900 Subject: [llvm-commits] [llvm] r150107 - /llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll In-Reply-To: <20120208223317.E28922A6C12C@llvm.org> References: <20120208223317.E28922A6C12C@llvm.org> Message-ID: 2012/2/9 Evan Cheng : > Author: evancheng > Date: Wed Feb ?8 16:33:17 2012 > New Revision: 150107 > > URL: http://llvm.org/viewvc/llvm-project?rev=150107&view=rev > Log: > Commit Andy Zhang's test for the lea patch. > > Added: > ? ?llvm/trunk/test/CodeGen/X86/atom-lea-sp.ll It is incompatible to Win32. Tweaked in r150151. Shall we add patterns for win32 here? ...Takumi From lhames at gmail.com Wed Feb 8 23:59:37 2012 From: lhames at gmail.com (Lang Hames) Date: Thu, 09 Feb 2012 05:59:37 -0000 Subject: [llvm-commits] [llvm] r150152 - /llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Message-ID: <20120209055937.357FF2A6C12C@llvm.org> Author: lhames Date: Wed Feb 8 23:59:36 2012 New Revision: 150152 URL: http://llvm.org/viewvc/llvm-project?rev=150152&view=rev Log: Preserve physreg kills in MachineBasicBlock::SplitCriticalEdge. Failure to preserve kills was causing LiveIntervals to miss some EFLAGS live ranges. Unfortunately I've been unable to reduce a good test case yet. Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=150152&r1=150151&r2=150152&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Wed Feb 8 23:59:36 2012 @@ -602,10 +602,11 @@ MachineInstr *MI = I; for (MachineInstr::mop_iterator OI = MI->operands_begin(), OE = MI->operands_end(); OI != OE; ++OI) { - if (!OI->isReg() || !OI->isUse() || !OI->isKill() || OI->isUndef()) + if (!OI->isReg() || OI->getReg() == 0 || + !OI->isUse() || !OI->isKill() || OI->isUndef()) continue; unsigned Reg = OI->getReg(); - if (TargetRegisterInfo::isVirtualRegister(Reg) && + if (TargetRegisterInfo::isPhysicalRegister(Reg) || LV->getVarInfo(Reg).removeKill(MI)) { KilledRegs.push_back(Reg); DEBUG(dbgs() << "Removing terminator kill: " << *MI); @@ -638,14 +639,16 @@ NMBB->addLiveIn(*I); // Update LiveVariables. + const TargetRegisterInfo *TRI = MF->getTarget().getRegisterInfo(); if (LV) { // Restore kills of virtual registers that were killed by the terminators. while (!KilledRegs.empty()) { unsigned Reg = KilledRegs.pop_back_val(); for (instr_iterator I = instr_end(), E = instr_begin(); I != E;) { - if (!(--I)->addRegisterKilled(Reg, NULL, /* addIfNotFound= */ false)) + if (!(--I)->addRegisterKilled(Reg, TRI, /* addIfNotFound= */ false)) continue; - LV->getVarInfo(Reg).Kills.push_back(I); + if (TargetRegisterInfo::isVirtualRegister(Reg)) + LV->getVarInfo(Reg).Kills.push_back(I); DEBUG(dbgs() << "Restored terminator kill: " << *I); break; } From spop at codeaurora.org Thu Feb 9 00:17:05 2012 From: spop at codeaurora.org (Sebastian Pop) Date: Thu, 9 Feb 2012 00:17:05 -0600 Subject: [llvm-commits] [llvm] r149468 - in /llvm/trunk: docs/ include/llvm-c/ include/llvm-c/Transforms/ include/llvm/ include/llvm/Transforms/ include/llvm/Transforms/IPO/ lib/Transforms/ lib/Transforms/IPO/ lib/Transforms/Vectorize/ test/Transforms/BBV Message-ID: On Tue, Jan 31, 2012 at 9:51 PM, Hal Finkel wrote: > +namespace { > + ?struct BBVectorize : public BasicBlockPass { > + ? ?static char ID; // Pass identification, replacement for typeid > + ? ?BBVectorize() : BasicBlockPass(ID) { > + ? ? ?initializeBBVectorizePass(*PassRegistry::getPassRegistry()); > + ? ?} > + > + ? ?typedef std::pair ValuePair; > + ? ?typedef std::pair ValuePairWithDepth; > + ? ?typedef std::pair VPPair; // A ValuePair pair > + ? ?typedef std::pair::iterator, > + ? ? ? ? ? ? ?std::multimap::iterator> VPIteratorPair; > + ? ?typedef std::pair::iterator, > + ? ? ? ? ? ? ?std::multimap::iterator> > + ? ? ? ? ? ? ? ?VPPIteratorPair; > + > + ? ?AliasAnalysis *AA; > + ? ?ScalarEvolution *SE; > + ? ?TargetData *TD; > + > + ? ?// FIXME: const correct? > + > + ? ?bool vectorizePairs(BasicBlock &BB); > + > + ? ?void getCandidatePairs(BasicBlock &BB, > + ? ? ? ? ? ? ? ? ? ? ? std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ? std::vector &PairableInsts); > + > + ? ?void computeConnectedPairs(std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ? std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ? std::multimap &ConnectedPairs); > + > + ? ?void buildDepMap(BasicBlock &BB, > + ? ? ? ? ? ? ? ? ? ? ? std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ? std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ? DenseSet &PairableInstUsers); > + > + ? ?void choosePairs(std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ? ?std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ? ?std::multimap &ConnectedPairs, > + ? ? ? ? ? ? ? ? ? ? ? ?DenseSet &PairableInstUsers, > + ? ? ? ? ? ? ? ? ? ? ? ?DenseMap& ChosenPairs); > + > + ? ?void fuseChosenPairs(BasicBlock &BB, > + ? ? ? ? ? ? ? ? ? ? std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? DenseMap& ChosenPairs); > + > + ? ?bool isInstVectorizable(Instruction *I, bool &IsSimpleLoadStore); > + > + ? ?bool areInstsCompatible(Instruction *I, Instruction *J, > + ? ? ? ? ? ? ? ? ? ? ? bool IsSimpleLoadStore); > + > + ? ?bool trackUsesOfI(DenseSet &Users, > + ? ? ? ? ? ? ? ? ? ? ?AliasSetTracker &WriteSet, Instruction *I, > + ? ? ? ? ? ? ? ? ? ? ?Instruction *J, bool UpdateUsers = true, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap *LoadMoveSet = 0); > + > + ? ?void computePairsConnectedTo( > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ?std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &ConnectedPairs, > + ? ? ? ? ? ? ? ? ? ? ?ValuePair P); > + > + ? ?bool pairsConflict(ValuePair P, ValuePair Q, > + ? ? ? ? ? ? ? ? DenseSet &PairableInstUsers, > + ? ? ? ? ? ? ? ? std::multimap *PairableInstUserMap = 0); > + > + ? ?bool pairWillFormCycle(ValuePair P, > + ? ? ? ? ? ? ? ? ? ? ? std::multimap &PairableInstUsers, > + ? ? ? ? ? ? ? ? ? ? ? DenseSet &CurrentPairs); > + > + ? ?void pruneTreeFor( > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ?std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &ConnectedPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseSet &PairableInstUsers, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &PairableInstUserMap, > + ? ? ? ? ? ? ? ? ? ? ?DenseMap &ChosenPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseMap &Tree, > + ? ? ? ? ? ? ? ? ? ? ?DenseSet &PrunedTree, ValuePair J, > + ? ? ? ? ? ? ? ? ? ? ?bool UseCycleCheck); > + > + ? ?void buildInitialTreeFor( > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ?std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &ConnectedPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseSet &PairableInstUsers, > + ? ? ? ? ? ? ? ? ? ? ?DenseMap &ChosenPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseMap &Tree, ValuePair J); > + > + ? ?void findBestTreeFor( > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &CandidatePairs, > + ? ? ? ? ? ? ? ? ? ? ?std::vector &PairableInsts, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &ConnectedPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseSet &PairableInstUsers, > + ? ? ? ? ? ? ? ? ? ? ?std::multimap &PairableInstUserMap, > + ? ? ? ? ? ? ? ? ? ? ?DenseMap &ChosenPairs, > + ? ? ? ? ? ? ? ? ? ? ?DenseSet &BestTree, size_t &BestMaxDepth, > + ? ? ? ? ? ? ? ? ? ? ?size_t &BestEffSize, VPIteratorPair ChoiceRange, > + ? ? ? ? ? ? ? ? ? ? ?bool UseCycleCheck); Having so many parameters to this and other methods above seems wrong: you could try to refactor this by better structuring the data. I could see at least the pair of vectorizable instructions and the tree of pairs split out as separate classes. You can also add some of these parameters to BBVectorize to avoid to pass them from method to method. Sebastian -- Qualcomm Innovation Center, Inc is a member of Code Aurora Forum From craig.topper at gmail.com Thu Feb 9 01:45:30 2012 From: craig.topper at gmail.com (Craig Topper) Date: Thu, 09 Feb 2012 07:45:30 -0000 Subject: [llvm-commits] [llvm] r150161 - in /llvm/trunk: lib/Target/X86/Disassembler/X86Disassembler.h lib/Target/X86/Disassembler/X86DisassemblerDecoder.c lib/Target/X86/Disassembler/X86DisassemblerDecoder.h utils/TableGen/X86DisassemblerTables.cpp Message-ID: <20120209074530.8BBA72A6C12C@llvm.org> Author: ctopper Date: Thu Feb 9 01:45:30 2012 New Revision: 150161 URL: http://llvm.org/viewvc/llvm-project?rev=150161&view=rev Log: Flatten some of the arrays in the X86 disassembler tables to reduce space needed to store pointers on 64-bit hosts and reduce relocations needed at startup. Part of PR11953. Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Modified: llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h?rev=150161&r1=150160&r2=150161&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86Disassembler.h Thu Feb 9 01:45:30 2012 @@ -78,7 +78,7 @@ const char* name; #define INSTRUCTION_IDS \ - const InstrUID *instructionIDs; + unsigned instructionIDs; #include "X86DisassemblerDecoderCommon.h" Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=150161&r1=150160&r2=150161&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Thu Feb 9 01:45:30 2012 @@ -131,14 +131,13 @@ debug("Corrupt table! Unknown modrm_type"); return 0; case MODRM_ONEENTRY: - return dec->instructionIDs[0]; + return modRMTable[dec->instructionIDs]; case MODRM_SPLITRM: if (modFromModRM(modRM) == 0x3) - return dec->instructionIDs[1]; - else - return dec->instructionIDs[0]; + return modRMTable[dec->instructionIDs+1]; + return modRMTable[dec->instructionIDs]; case MODRM_FULL: - return dec->instructionIDs[modRM]; + return modRMTable[dec->instructionIDs+modRM]; } } Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h?rev=150161&r1=150160&r2=150161&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.h Thu Feb 9 01:45:30 2012 @@ -24,7 +24,7 @@ const char* name; #define INSTRUCTION_IDS \ - const InstrUID *instructionIDs; + unsigned instructionIDs; #include "X86DisassemblerDecoderCommon.h" Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp?rev=150161&r1=150160&r2=150161&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp (original) +++ llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Thu Feb 9 01:45:30 2012 @@ -196,8 +196,7 @@ /// @param i - The indentation level for that output stream. static void emitEmptyTable(raw_ostream &o, uint32_t &i) { - o.indent(i * 2) << "static const InstrUID modRMEmptyTable[1] = { 0 };\n"; - o << "\n"; + o.indent(i * 2) << "0x0, /* EmptyTable */\n"; } /// getDecisionType - Determines whether a ModRM decision with 255 entries can @@ -293,71 +292,67 @@ ModRMDecision &decision) const { static uint64_t sTableNumber = 0; - uint64_t thisTableNumber = sTableNumber; + static uint64_t sEntryNumber = 1; ModRMDecisionType dt = getDecisionType(decision); uint16_t index; - + if (dt == MODRM_ONEENTRY && decision.instructionIDs[0] == 0) { o2.indent(i2) << "{ /* ModRMDecision */" << "\n"; i2++; - + o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; - o2.indent(i2) << "modRMEmptyTable"; - + o2.indent(i2) << 0 << " /* EmptyTable */\n"; + i2--; o2.indent(i2) << "}"; return; } - - o1.indent(i1) << "static const InstrUID modRMTable" << thisTableNumber; - - switch (dt) { - default: - llvm_unreachable("Unknown decision type"); - case MODRM_ONEENTRY: - o1 << "[1]"; - break; - case MODRM_SPLITRM: - o1 << "[2]"; - break; - case MODRM_FULL: - o1 << "[256]"; - break; - } - o1 << " = {" << "\n"; + o1 << "/* Table" << sTableNumber << " */\n"; i1++; - + switch (dt) { default: llvm_unreachable("Unknown decision type"); case MODRM_ONEENTRY: - emitOneID(o1, i1, decision.instructionIDs[0], false); + emitOneID(o1, i1, decision.instructionIDs[0], true); break; case MODRM_SPLITRM: emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 - emitOneID(o1, i1, decision.instructionIDs[0xc0], false); // mod = 0b11 + emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11 break; case MODRM_FULL: for (index = 0; index < 256; ++index) - emitOneID(o1, i1, decision.instructionIDs[index], index < 255); + emitOneID(o1, i1, decision.instructionIDs[index], true); break; } - + i1--; - o1.indent(i1) << "};" << "\n"; - o1 << "\n"; - + o2.indent(i2) << "{ /* struct ModRMDecision */" << "\n"; i2++; - + o2.indent(i2) << stringForDecisionType(dt) << "," << "\n"; - o2.indent(i2) << "modRMTable" << sTableNumber << "\n"; - + o2.indent(i2) << sEntryNumber << " /* Table" << sTableNumber << " */\n"; + i2--; o2.indent(i2) << "}"; - + + switch (dt) { + default: + llvm_unreachable("Unknown decision type"); + case MODRM_ONEENTRY: + sEntryNumber += 1; + break; + case MODRM_SPLITRM: + sEntryNumber += 2; + break; + case MODRM_FULL: + sEntryNumber += 256; + break; + } + ++sTableNumber; } @@ -598,11 +593,16 @@ emitContextTable(o, i2); o << "\n"; - + + o << "static const InstrUID modRMTable[] = {\n"; + i1++; emitEmptyTable(o1, i1); + i1--; emitContextDecisions(o1, o2, i1, i2); - + o << o1.str(); + o << " 0x0\n"; + o << "};\n"; o << "\n"; o << o2.str(); o << "\n"; From tobias at grosser.es Thu Feb 9 02:09:12 2012 From: tobias at grosser.es (Tobias Grosser) Date: Thu, 09 Feb 2012 09:09:12 +0100 Subject: [llvm-commits] [zorg] r150113 - in /zorg/trunk/lnt/lnt/server/ui: templates/v4_run.html templates/v4_utils.html views.py In-Reply-To: <20120208233340.71F4B2A6C12C@llvm.org> References: <20120208233340.71F4B2A6C12C@llvm.org> Message-ID: <4F337F28.1060400@grosser.es> On 02/09/2012 12:33 AM, Daniel Dunbar wrote: > Author: ddunbar > Date: Wed Feb 8 17:33:40 2012 > New Revision: 150113 > > URL: http://llvm.org/viewvc/llvm-project?rev=150113&view=rev > Log: > [lnt/v0.4] lnt.server.ui: Add trivial UI for selecting a different run to compare to. Hey Daniel, would it be difficult to compare two runs from different testers. The idea is to compare the execution times e.g. of an an -O3 and a -vectorize tester. Cheers Tobi From nicholas at mxc.ca Thu Feb 9 02:56:46 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 09 Feb 2012 00:56:46 -0800 Subject: [llvm-commits] cxa_guard elimination In-Reply-To: <4F2B8CFF.9020606@mxc.ca> References: <4F0903F9.405@mxc.ca> <4F0BF82B.7030206@mxc.ca> <4F24F0E4.4090701@mxc.ca> <4F24FA31.50601@mxc.ca> <0058FB56-53A7-4012-A83D-3860C965113A@apple.com> <4F2B8CFF.9020606@mxc.ca> Message-ID: <4F338A4E.6040607@mxc.ca> Nick Lewycky wrote: > Chris Lattner wrote: >> On Jan 28, 2012, at 11:50 PM, Nick Lewycky wrote: >>>> The good news is that we already have a valid DomTree by the time >>>> simplify-libcalls runs, so we're good to request one here. >>>> >>>> The updated patch is barely more complicated, there's just an additional >>>> check to see whether there's a single predecessor block that's testing >>>> the guard variable, and an additional domtree BB test (so, no linear >>>> time) on each StoreInst. No sweat! >>>> >>>> Please review! I'd like to land this patch and then start working on >>>> some of its deficiencies in follow-up patches. >>> >>> Uh... I mailed out the entirely wrong patch. >>> >>> Correct patch attached! >> >> Hi Nick, >> >> Did you consider doing this as part of globalopt? > > Yes, that was the next thing in my email :) However, consider that: > > - I'd like it to run *after* the inliner so that I don't get fouled up > by constructor calls Of course GlobalOpt is interprocedural, since it already has to not be fouled up by constructor calls. Updated patch attached, including more bugfixes than ever before! Please review! Nick > - I'd like it to run *before (or with)* globalopt so that we can > transform other globals (like the guard variable) that only becomes > possible after the cxa-guard is eliminated. > > There is no such place in the pipeline. We can do things like refactor > globalopt into a utility the make cxa-guard-elim call it in its > doFinalization() or something. > > I was hoping to commit it to simplify-libcalls first to hammer out any > correctness issues while I figure out where it should ultimately live. > > Or if you ask, I can just drop it into globalopt for now and figure > something out later? > > Nick > > It already has "simulation" logic that could be reusable, and doing > this early means that you can optimize for the common case, where > inlining hasn't happened yet. It seems like it would eliminate some of > the dominator requirements, and wouldn't prevent merging > simplifylibcalls into instcombine in the future. >> >> -Chris >> > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > -------------- next part -------------- A non-text attachment was scrubbed... Name: globalopt-cxa_guard-1.patch Type: text/x-diff Size: 37952 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/2b1e9c4f/attachment.bin From craig.topper at gmail.com Thu Feb 9 02:58:07 2012 From: craig.topper at gmail.com (Craig Topper) Date: Thu, 09 Feb 2012 08:58:07 -0000 Subject: [llvm-commits] [llvm] r150167 - in /llvm/trunk: lib/Target/X86/Disassembler/X86DisassemblerDecoder.c lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h utils/TableGen/X86DisassemblerTables.cpp Message-ID: <20120209085807.E1B542A6C12C@llvm.org> Author: ctopper Date: Thu Feb 9 02:58:07 2012 New Revision: 150167 URL: http://llvm.org/viewvc/llvm-project?rev=150167&view=rev Log: More tweaks to get the size of the X86 disassembler tables down. Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c?rev=150167&r1=150166&r2=150167&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoder.c Thu Feb 9 02:58:07 2012 @@ -136,6 +136,10 @@ if (modFromModRM(modRM) == 0x3) return modRMTable[dec->instructionIDs+1]; return modRMTable[dec->instructionIDs]; + case MODRM_SPLITREG: + if (modFromModRM(modRM) == 0x3) + return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8]; + return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)]; case MODRM_FULL: return modRMTable[dec->instructionIDs+modRM]; } Modified: llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h?rev=150167&r1=150166&r2=150167&view=diff ============================================================================== --- llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h (original) +++ llvm/trunk/lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h Thu Feb 9 02:58:07 2012 @@ -156,6 +156,8 @@ * MODRM_SPLITRM - If the ModR/M byte is between 0x00 and 0xbf, the opcode * corresponds to one instruction; otherwise, it corresponds to * a different instruction. + * MODRM_SPLITREG - ModR/M byte divided by 8 is used to select instruction. This + corresponds to instructions that use reg field as opcode * MODRM_FULL - Potentially, each value of the ModR/M byte could correspond * to a different instruction. */ @@ -163,6 +165,7 @@ #define MODRMTYPES \ ENUM_ENTRY(MODRM_ONEENTRY) \ ENUM_ENTRY(MODRM_SPLITRM) \ + ENUM_ENTRY(MODRM_SPLITREG) \ ENUM_ENTRY(MODRM_FULL) #define ENUM_ENTRY(n) n, Modified: llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp?rev=150167&r1=150166&r2=150167&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp (original) +++ llvm/trunk/utils/TableGen/X86DisassemblerTables.cpp Thu Feb 9 02:58:07 2012 @@ -208,28 +208,40 @@ { bool satisfiesOneEntry = true; bool satisfiesSplitRM = true; - + bool satisfiesSplitReg = true; + uint16_t index; - + for (index = 0; index < 256; ++index) { if (decision.instructionIDs[index] != decision.instructionIDs[0]) satisfiesOneEntry = false; - + if (((index & 0xc0) == 0xc0) && (decision.instructionIDs[index] != decision.instructionIDs[0xc0])) satisfiesSplitRM = false; - + if (((index & 0xc0) != 0xc0) && (decision.instructionIDs[index] != decision.instructionIDs[0x00])) satisfiesSplitRM = false; + + if (((index & 0xc0) == 0xc0) && + (decision.instructionIDs[index] != decision.instructionIDs[index&0xf8])) + satisfiesSplitReg = false; + + if (((index & 0xc0) != 0xc0) && + (decision.instructionIDs[index] != decision.instructionIDs[index&0x38])) + satisfiesSplitReg = false; } - + if (satisfiesOneEntry) return MODRM_ONEENTRY; - + if (satisfiesSplitRM) return MODRM_SPLITRM; - + + if (satisfiesSplitReg) + return MODRM_SPLITREG; + return MODRM_FULL; } @@ -322,6 +334,12 @@ emitOneID(o1, i1, decision.instructionIDs[0x00], true); // mod = 0b00 emitOneID(o1, i1, decision.instructionIDs[0xc0], true); // mod = 0b11 break; + case MODRM_SPLITREG: + for (index = 0; index < 64; index += 8) + emitOneID(o1, i1, decision.instructionIDs[index], true); + for (index = 0xc0; index < 256; index += 8) + emitOneID(o1, i1, decision.instructionIDs[index], true); + break; case MODRM_FULL: for (index = 0; index < 256; ++index) emitOneID(o1, i1, decision.instructionIDs[index], true); @@ -348,6 +366,9 @@ case MODRM_SPLITRM: sEntryNumber += 2; break; + case MODRM_SPLITREG: + sEntryNumber += 16; + break; case MODRM_FULL: sEntryNumber += 256; break; From baldrick at free.fr Thu Feb 9 03:10:08 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 10:10:08 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> <4F32D43E.6010900@free.fr> Message-ID: <4F338D70.1040502@free.fr> Hi Dave, >> I didn't try, but turning __builtin_ia32_vpermilpd into an inline asm is >> presumably rather trivial. > > I don't know how hard it would be. The frontend would have to know > about mnemonics, at least. And it would have to know whether to > generate AT&T or Intel syntax. I'm not sure this is true any more. The LLVM code generators nowadays parse inline asm and can output it either as object code or in AT&T or Intel syntax. At least I think they can. If so, the syntax issue has gone away. Ciao, Duncan. It strikes me as the wrong place to do > this when the mechanisms already exist in the current codegen. > >> But why not give it a go? > > Because it works now, we've been using it for years and I have a million > other things to fix and improve. > > Could it be done? Sure. Is it worth the expense to do it given an > existing solution? No way. > >>> What is so difficult about keeping intrinsics around? Are they causing >>> some major issue? >> >> I'm not the one removing intrinsics, and I don't know what the reason is. >> However keeping useless functionality does create a maintenance burden for >> no real benefit. > > They're not useless. We are using them. And I question whether it is > much of a maintenance burden at all. Who goes and changes existing > intrinsics? > >> I call these intrinsics useless since you can get the same >> semantic effect using generic IR > > Users expect more than the same semantic effect. > >> or exactly the instruction using inline asm. > > With a lot of extra work which is completely unnecessary given that a > solution already exists. > >> If turning them into inline asm is a real pain as you suspect, then I >> for one would vote to keep the intrinsics. > > It is infinitely more painful than just using what we already have, what > we know works and which requires zero effort to keep working. > > -Dave From baldrick at free.fr Thu Feb 9 03:13:11 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 10:13:11 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: <4F338E27.6030400@free.fr> > Whether generic IR is a "win" isn't the primary issue here. The issue > is that the user wrote code using intrinsics and expects that exact code > to be in the asm. Whether or not that is the best performing code > possible doesn't matter. It's what they want and we have to respect it. > Our customers demand it. > > > Okay. This is a different issue then, and isn't even solved by using intrinsics; > the optimization passes are absolutely allowed to modify uses of intrinsics. We > do this in obvious cases for things like memset or ctz, but there is no reason > the optimization passes won't optimize the llvm.x86 intrinsics too. It's rare, > but you can see code in ValueTracking.cpp that > will analyze Intrinsic::x86_sse42_crc32_64_8 for one example, > ConstantFolding.cpp will fold through x86_sse_cvtss2si for another. Yeah, this is what I was trying to get at with my "historical essay". The compiler will transform intrinsics, and is only going to do this more and more as time goes on. If you want a particular asm, use inline asm. Though even that is likely to only work for a few years before people start implementing asm level optimizations (which is sure to be done because it can be done). Ciao, Duncan. From baldrick at free.fr Thu Feb 9 03:19:47 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 10:19:47 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> Message-ID: <4F338FB3.7090209@free.fr> Hi Craig, > I see that you removed all clang support for these builtins, rather than having > clang turn the builtin into a shufflevector instruction (which is what I thought > you did). Is that wise? You just reduced GCC compatibility, when you could > have kept it by expanding the builtins into generic IR. > > Ciao, Duncan. > > > That's correct, but what I did is no different than what is already done for > pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, > pshufhw, etc. was it really a good idea to remove them? You could have had clang support them at little cost, maintaining GCC compatibility. Ciao, Duncan. From clattner at apple.com Thu Feb 9 03:42:11 2012 From: clattner at apple.com (Chris Lattner) Date: Thu, 09 Feb 2012 01:42:11 -0800 Subject: [llvm-commits] [llvm] r150167 - in /llvm/trunk: lib/Target/X86/Disassembler/X86DisassemblerDecoder.c lib/Target/X86/Disassembler/X86DisassemblerDecoderCommon.h utils/TableGen/X86DisassemblerTables.cpp In-Reply-To: <20120209085807.E1B542A6C12C@llvm.org> References: <20120209085807.E1B542A6C12C@llvm.org> Message-ID: On Feb 9, 2012, at 12:58 AM, Craig Topper wrote: > Author: ctopper > Date: Thu Feb 9 02:58:07 2012 > New Revision: 150167 > > URL: http://llvm.org/viewvc/llvm-project?rev=150167&view=rev > Log: > More tweaks to get the size of the X86 disassembler tables down. Just to repeat the numbers I put into PR11953: Wow, that was a huge win! From 1988020 bytes and: Section (__TEXT, __text): 8356 Section (__TEXT, __cstring): 46982 Section (__DATA, __const): 962128 (relocatable data) Section (__TEXT, __const): 234816 (read only data) Section (__TEXT, __eh_frame): 408 to 890820 bytes and: Section (__TEXT, __text): 8448 Section (__TEXT, __cstring): 46982 Section (__DATA, __const): 249424 (down over 700K!) Section (__TEXT, __const): 432656 Section (__TEXT, __eh_frame): 408 You just carved off over a MB, and sped up the build of that .o file by a lot too! Thank you!! -Chris From clattner at apple.com Thu Feb 9 03:45:14 2012 From: clattner at apple.com (Chris Lattner) Date: Thu, 09 Feb 2012 01:45:14 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F338FB3.7090209@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> <4F338FB3.7090209@free.fr> Message-ID: <241C5BB5-08B2-40A0-BD5D-92EE79A44568@apple.com> On Feb 9, 2012, at 1:19 AM, Duncan Sands wrote: > Hi Craig, > >> I see that you removed all clang support for these builtins, rather than having >> clang turn the builtin into a shufflevector instruction (which is what I thought >> you did). Is that wise? You just reduced GCC compatibility, when you could >> have kept it by expanding the builtins into generic IR. >> >> Ciao, Duncan. >> >> >> That's correct, but what I did is no different than what is already done for >> pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, >> pshufhw, etc. > > was it really a good idea to remove them? You could have had clang support them > at little cost, maintaining GCC compatibility. Hi Duncan, I haven't been following the whole thread, but yes, we really do want to remove intrinsics that are redundant with core IR instructions. In reality, what we wanted is for them never to be added in the first place :). Over time, we hope that LLVM IR becomes more expressive, and as such it will increasingly overlap with things that are currently intrinsics. Another one that is on the chopping block at some point is the half-float conversion intrinsics, which are now redundant with casts to the native half-float type. -Chris From baldrick at free.fr Thu Feb 9 03:50:09 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 10:50:09 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <241C5BB5-08B2-40A0-BD5D-92EE79A44568@apple.com> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> <4F338FB3.7090209@free.fr> <241C5BB5-08B2-40A0-BD5D-92EE79A44568@apple.com> Message-ID: <4F3396D1.40708@free.fr> Hi Chris, >>> That's correct, but what I did is no different than what is already done for >>> pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, >>> pshufhw, etc. >> >> was it really a good idea to remove them? You could have had clang support them >> at little cost, maintaining GCC compatibility. > > Hi Duncan, > > I haven't been following the whole thread, but yes, we really do want to remove intrinsics that are redundant with core IR instructions. In reality, what we wanted is for them never to be added in the first place :). Over time, we hope that LLVM IR becomes more expressive, and as such it will increasingly overlap with things that are currently intrinsics. Another one that is on the chopping block at some point is the half-float conversion intrinsics, which are now redundant with casts to the native half-float type. I wasn't referring to removal of the intrinsics, I meant removing clang support for builtin_ia32_pshufd etc: clang could continue to support them by expanding them into generic LLVM IR. Ciao, Duncan. From clattner at apple.com Thu Feb 9 04:00:10 2012 From: clattner at apple.com (Chris Lattner) Date: Thu, 09 Feb 2012 02:00:10 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F3396D1.40708@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> <4F338FB3.7090209@free.fr> <241C5BB5-08B2-40A0-BD5D-92EE79A44568@apple.com> <4F3396D1.40708@free.fr> Message-ID: <202C5F03-D60E-431D-8CDA-EB6611D0B64C@apple.com> On Feb 9, 2012, at 1:50 AM, Duncan Sands wrote: > Hi Chris, > >>>> That's correct, but what I did is no different than what is already done for >>>> pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, >>>> pshufhw, etc. >>> >>> was it really a good idea to remove them? You could have had clang support them >>> at little cost, maintaining GCC compatibility. >> >> Hi Duncan, >> >> I haven't been following the whole thread, but yes, we really do want to remove intrinsics that are redundant with core IR instructions. In reality, what we wanted is for them never to be added in the first place :). Over time, we hope that LLVM IR becomes more expressive, and as such it will increasingly overlap with things that are currently intrinsics. Another one that is on the chopping block at some point is the half-float conversion intrinsics, which are now redundant with casts to the native half-float type. > > I wasn't referring to removal of the intrinsics, I meant removing clang support > for builtin_ia32_pshufd etc: clang could continue to support them by expanding > them into generic LLVM IR. The vector __builtin's are considered an internal implementation detail of the *intrin.h files, and clang's work completely differently than GCC's. We don't try to support uses of the builtins directly. See also: http://clang.llvm.org/compatibility.html#vector_builtins -Chris From benny.kra at googlemail.com Thu Feb 9 04:02:19 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 9 Feb 2012 11:02:19 +0100 Subject: [llvm-commits] [llvm] r150120 - /llvm/trunk/lib/Support/DataStream.cpp In-Reply-To: <20120209002919.34FC92A6C12C@llvm.org> References: <20120209002919.34FC92A6C12C@llvm.org> Message-ID: <-6665216174713128412@unknownmsgid> On 09.02.2012, at 01:35, David Blaikie wrote: > Author: dblaikie > Date: Wed Feb 8 18:29:19 2012 > New Revision: 150120 > > URL: http://llvm.org/viewvc/llvm-project?rev=150120&view=rev > Log: > Remove static initializer from DataStream.cpp Looks like PathV2.cpp and MemoryBuffer.cpp suffer from exactly the same problem. - Ben > > If someone would prefer a clear name for the 'success' error_value we could > come up with one - potentially just a 'named constructor' style > 'error_value::success()' to make this expression more self-documenting. If > I see this come up in other cases I'll certainly consider it. > > One step along the way to resolving PR11944. > > Modified: > llvm/trunk/lib/Support/DataStream.cpp > > Modified: llvm/trunk/lib/Support/DataStream.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=150120&r1=150119&r2=150120&view=diff > ============================================================================== > --- llvm/trunk/lib/Support/DataStream.cpp (original) > +++ llvm/trunk/lib/Support/DataStream.cpp Wed Feb 8 18:29:19 2012 > @@ -49,8 +49,6 @@ > > namespace { > > -const static error_code success; > - > // Very simple stream backed by a file. Mostly useful for stdin and debugging; > // actual file access is probably still best done with mmap. > class DataFileStreamer : public DataStreamer { > @@ -66,18 +64,20 @@ > } > > error_code OpenFile(const std::string &Filename) { > - int OpenFlags = O_RDONLY; > -#ifdef O_BINARY > - OpenFlags |= O_BINARY; // Open input file in binary mode on win32. > -#endif > if (Filename == "-") { > Fd = 0; > sys::Program::ChangeStdinToBinary(); > + return error_code(); > } > - else > - Fd = ::open(Filename.c_str(), OpenFlags); > - if (Fd == -1) return error_code(errno, posix_category()); > - return success; > + > + int OpenFlags = O_RDONLY; > +#ifdef O_BINARY > + OpenFlags |= O_BINARY; // Open input file in binary mode on win32. > +#endif > + Fd = ::open(Filename.c_str(), OpenFlags); > + if (Fd == -1) > + return error_code(errno, posix_category()); > + return error_code(); > } > }; > > @@ -87,8 +87,7 @@ > DataStreamer *getDataFileStreamer(const std::string &Filename, > std::string *StrError) { > DataFileStreamer *s = new DataFileStreamer(); > - error_code e = s->OpenFile(Filename); > - if (e != success) { > + if (error_code e = s->OpenFile(Filename)) { > *StrError = std::string("Could not open ") + Filename + ": " + > e.message() + "\n"; > return NULL; > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From james.molloy at arm.com Thu Feb 9 04:56:31 2012 From: james.molloy at arm.com (James Molloy) Date: Thu, 09 Feb 2012 10:56:31 -0000 Subject: [llvm-commits] [llvm] r150169 - in /llvm/trunk: lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/ARMInstrThumb.td test/MC/Disassembler/ARM/unpredictables-thumb.txt utils/TableGen/FixedLenDecoderEmitter.cpp Message-ID: <20120209105632.0B37A2A6C12C@llvm.org> Author: jamesm Date: Thu Feb 9 04:56:31 2012 New Revision: 150169 URL: http://llvm.org/viewvc/llvm-project?rev=150169&view=rev Log: Teach the MC and disassembler about SoftFail, and hook it up to UNPREDICTABLE on ARM. Wire this to tBLX in order to provide test coverage. Added: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt (with props) Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td llvm/trunk/lib/Target/ARM/ARMInstrThumb.td llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=150169&r1=150168&r2=150169&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original) +++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Thu Feb 9 04:56:31 2012 @@ -290,6 +290,14 @@ class Encoding { field bits<32> Inst; + // Mask of bits that cause an encoding to be UNPREDICTABLE. + // If a bit is set, then if the corresponding bit in the + // target encoding differs from its value in the "Inst" field, + // the instruction is UNPREDICTABLE (SoftFail in abstract parlance). + field bits<32> Unpredictable = 0; + // SoftFail is the generic name for this field, but we alias it so + // as to make it more obvious what it means in ARM-land. + field bits<32> SoftFail = Unpredictable; } class InstARM Rm; let Inst{6-3} = Rm; let Inst{2-0} = 0b000; + let Unpredictable{2-0} = 0b111; } } Added: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt?rev=150169&view=auto ============================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt (added) +++ llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt Thu Feb 9 04:56:31 2012 @@ -0,0 +1,5 @@ +# RUN: llvm-mc --disassemble %s -triple=thumbv7 |& FileCheck %s + +0x01 0x47 +# CHECK: 3:1: warning: potentially undefined +# CHECK: bx r0 Propchange: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt ------------------------------------------------------------------------------ svn:eol-style = native Propchange: llvm/trunk/test/MC/Disassembler/ARM/unpredictables-thumb.txt ------------------------------------------------------------------------------ svn:keywords = Rev Date Author URL Id Modified: llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp?rev=150169&r1=150168&r2=150169&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/FixedLenDecoderEmitter.cpp Thu Feb 9 04:56:31 2012 @@ -17,6 +17,7 @@ #include "FixedLenDecoderEmitter.h" #include "CodeGenTarget.h" #include "llvm/TableGen/Record.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -285,8 +286,19 @@ void insnWithID(insn_t &Insn, unsigned Opcode) const { BitsInit &Bits = getBitsField(*AllInstructions[Opcode]->TheDef, "Inst"); - for (unsigned i = 0; i < BitWidth; ++i) - Insn.push_back(bitFromBits(Bits, i)); + // We may have a SoftFail bitmask, which specifies a mask where an encoding + // may differ from the value in "Inst" and yet still be valid, but the + // disassembler should return SoftFail instead of Success. + // + // This is used for marking UNPREDICTABLE instructions in the ARM world. + BitsInit *SFBits = AllInstructions[Opcode]->TheDef->getValueAsBitsInit("SoftFail"); + + for (unsigned i = 0; i < BitWidth; ++i) { + if (SFBits && bitFromBits(*SFBits, i) == BIT_TRUE) + Insn.push_back(BIT_UNSET); + else + Insn.push_back(bitFromBits(Bits, i)); + } } // Returns the record name. @@ -334,6 +346,8 @@ // Returns true if predicate matches were emitted, false otherwise. bool emitPredicateMatch(raw_ostream &o, unsigned &Indentation,unsigned Opc); + void emitSoftFailCheck(raw_ostream &o, unsigned Indentation, unsigned Opc); + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool emitSingletonDecoder(raw_ostream &o, unsigned &Indentation,unsigned Opc); @@ -800,6 +814,64 @@ return Predicates->getSize() > 0; } +void FilterChooser::emitSoftFailCheck(raw_ostream &o, unsigned Indentation, unsigned Opc) { + BitsInit *SFBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("SoftFail"); + if (!SFBits) return; + BitsInit *InstBits = AllInstructions[Opc]->TheDef->getValueAsBitsInit("Inst"); + + APInt PositiveMask(BitWidth, 0ULL); + APInt NegativeMask(BitWidth, 0ULL); + for (unsigned i = 0; i < BitWidth; ++i) { + bit_value_t B = bitFromBits(*SFBits, i); + bit_value_t IB = bitFromBits(*InstBits, i); + + if (B != BIT_TRUE) continue; + + switch (IB) { + case BIT_FALSE: + // The bit is meant to be false, so emit a check to see if it is true. + PositiveMask.setBit(i); + break; + case BIT_TRUE: + // The bit is meant to be true, so emit a check to see if it is false. + NegativeMask.setBit(i); + break; + default: + // The bit is not set; this must be an error! + StringRef Name = AllInstructions[Opc]->TheDef->getName(); + errs() << "SoftFail Conflict: bit SoftFail{" << i << "} in " + << Name + << " is set but Inst{" << i <<"} is unset!\n" + << " - You can only mark a bit as SoftFail if it is fully defined" + << " (1/0 - not '?') in Inst\n"; + o << "#error SoftFail Conflict, " << Name << "::SoftFail{" << i + << "} set but Inst{" << i << "} undefined!\n"; + } + } + + bool NeedPositiveMask = PositiveMask.getBoolValue(); + bool NeedNegativeMask = NegativeMask.getBoolValue(); + + if (!NeedPositiveMask && !NeedNegativeMask) + return; + + std::string PositiveMaskStr = PositiveMask.toString(16, /*signed=*/false); + std::string NegativeMaskStr = NegativeMask.toString(16, /*signed=*/false); + StringRef BitExt = ""; + if (BitWidth > 32) + BitExt = "ULL"; + + o.indent(Indentation) << "if ("; + if (NeedPositiveMask) + o << "insn & 0x" << PositiveMaskStr << BitExt; + if (NeedPositiveMask && NeedNegativeMask) + o << " || "; + if (NeedNegativeMask) + o << "~insn & 0x" << NegativeMaskStr << BitExt; + o << ")\n"; + o.indent(Indentation+2) << "S = MCDisassembler::SoftFail;\n"; +} + // Emits code to decode the singleton. Return true if we have matched all the // well-known bits. bool FilterChooser::emitSingletonDecoder(raw_ostream &o, unsigned &Indentation, @@ -822,6 +894,7 @@ if (!emitPredicateMatch(o, Indentation, Opc)) o << "1"; o << ") {\n"; + emitSoftFailCheck(o, Indentation+2, Opc); o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; std::vector& InsnOperands = Operands[Opc]; for (std::vector::iterator @@ -871,6 +944,7 @@ else o << ") {\n"; } + emitSoftFailCheck(o, Indentation+2, Opc); o.indent(Indentation) << " MI.setOpcode(" << Opc << ");\n"; std::vector& InsnOperands = Operands[Opc]; for (std::vector::iterator From benny.kra at googlemail.com Thu Feb 9 05:25:09 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 09 Feb 2012 11:25:09 -0000 Subject: [llvm-commits] [llvm] r150170 - in /llvm/trunk: include/llvm/MC/MCInstrDesc.h utils/TableGen/InstrInfoEmitter.cpp Message-ID: <20120209112509.BC3D02A6C12C@llvm.org> Author: d0k Date: Thu Feb 9 05:25:09 2012 New Revision: 150170 URL: http://llvm.org/viewvc/llvm-project?rev=150170&view=rev Log: Move the Name field in MCInstrDesc to the end, saving 8 bytes of padding per entry on x86_64. No change on i386. Modified: llvm/trunk/include/llvm/MC/MCInstrDesc.h llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Modified: llvm/trunk/include/llvm/MC/MCInstrDesc.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCInstrDesc.h?rev=150170&r1=150169&r2=150170&view=diff ============================================================================== --- llvm/trunk/include/llvm/MC/MCInstrDesc.h (original) +++ llvm/trunk/include/llvm/MC/MCInstrDesc.h Thu Feb 9 05:25:09 2012 @@ -137,12 +137,12 @@ unsigned short NumDefs; // Num of args that are definitions unsigned short SchedClass; // enum identifying instr sched class unsigned short Size; // Number of bytes in encoding. - const char * Name; // Name of the instruction record in td file unsigned Flags; // Flags identifying machine instr class uint64_t TSFlags; // Target Specific Flag values const unsigned *ImplicitUses; // Registers implicitly read by this instr const unsigned *ImplicitDefs; // Registers implicitly defined by this instr const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands + const char *Name; // Name of the instruction record in td file /// getOperandConstraint - Returns the value of the specific constraint if /// it is set. Returns -1 if it is not set. Modified: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp?rev=150170&r1=150169&r2=150170&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp Thu Feb 9 05:25:09 2012 @@ -264,8 +264,7 @@ OS << Num << ",\t" << MinOperands << ",\t" << Inst.Operands.NumDefs << ",\t" << getItinClassNumber(Inst.TheDef) << ",\t" - << Inst.TheDef->getValueAsInt("Size") << ",\t\"" - << Inst.TheDef->getName() << "\", 0"; + << Inst.TheDef->getValueAsInt("Size") << ",\t0"; // Emit all of the target indepedent flags... if (Inst.isPseudo) OS << "|(1<second; + OS << ", \"" << Inst.TheDef->getName() << '"'; + OS << " }, // Inst #" << Num << " = " << Inst.TheDef->getName() << "\n"; } From samsonov at google.com Thu Feb 9 05:36:12 2012 From: samsonov at google.com (Alexey Samsonov) Date: Thu, 09 Feb 2012 11:36:12 -0000 Subject: [llvm-commits] [compiler-rt] r150171 - in /compiler-rt/trunk/lib/asan: Makefile.mk Makefile.old interception/Makefile.mk interception/interception_mac.cc interception/mach_override/ mach_override/ Message-ID: <20120209113612.6478F2A6C12C@llvm.org> Author: samsonov Date: Thu Feb 9 05:36:12 2012 New Revision: 150171 URL: http://llvm.org/viewvc/llvm-project?rev=150171&view=rev Log: AddressSanitizer: move mach_override inside interception library Added: compiler-rt/trunk/lib/asan/interception/mach_override/ - copied from r150169, compiler-rt/trunk/lib/asan/mach_override/ Removed: compiler-rt/trunk/lib/asan/mach_override/ Modified: compiler-rt/trunk/lib/asan/Makefile.mk compiler-rt/trunk/lib/asan/Makefile.old compiler-rt/trunk/lib/asan/interception/Makefile.mk compiler-rt/trunk/lib/asan/interception/interception_mac.cc Modified: compiler-rt/trunk/lib/asan/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.mk?rev=150171&r1=150170&r2=150171&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/Makefile.mk (original) +++ compiler-rt/trunk/lib/asan/Makefile.mk Thu Feb 9 05:36:12 2012 @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# ModuleName := asan -SubDirs := interception mach_override +SubDirs := interception Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) ObjNames := $(Sources:%.cc=%.o) @@ -18,7 +18,7 @@ # FIXME: use automatic dependencies? Dependencies := $(wildcard $(Dir)/*.h) Dependencies += $(wildcard $(Dir)/interception/*.h) -Dependencies += $(wildcard $(Dir)/mach_override/*.h) +Dependencies += $(wildcard $(Dir)/interception/mach_override/*.h) # Define a convenience variable for all the asan functions. AsanFunctions := $(Sources:%.cc=%) Modified: compiler-rt/trunk/lib/asan/Makefile.old URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/Makefile.old?rev=150171&r1=150170&r2=150171&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/Makefile.old (original) +++ compiler-rt/trunk/lib/asan/Makefile.old Thu Feb 9 05:36:12 2012 @@ -181,7 +181,7 @@ interception/interception.h \ interception/interception_linux.h \ interception/interception_mac.h \ - mach_override/mach_override.h + interception/mach_override/mach_override.h LIBASAN_OBJ=$(BIN)/asan_rtl$(SUFF).o \ $(BIN)/asan_allocator$(SUFF).o \ @@ -200,7 +200,7 @@ $(BIN)/asan_thread_registry$(SUFF).o \ $(BIN)/interception/interception_linux$(SUFF).o \ $(BIN)/interception/interception_mac$(SUFF).o \ - $(BIN)/mach_override/mach_override$(SUFF).o + $(BIN)/interception/mach_override/mach_override$(SUFF).o GTEST_ROOT=third_party/googletest GTEST_INCLUDE=-I$(GTEST_ROOT)/include @@ -233,7 +233,7 @@ mk_bin_dir: mkdir -p $(BIN) mkdir -p $(BIN)/interception - mkdir -p $(BIN)/mach_override + mkdir -p $(BIN)/interception/mach_override clang: cd ../ && llvm/rebuild_clang_and_asan.sh > /dev/null Modified: compiler-rt/trunk/lib/asan/interception/Makefile.mk URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/Makefile.mk?rev=150171&r1=150170&r2=150171&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/interception/Makefile.mk (original) +++ compiler-rt/trunk/lib/asan/interception/Makefile.mk Thu Feb 9 05:36:12 2012 @@ -8,7 +8,7 @@ #===------------------------------------------------------------------------===# ModuleName := asan -SubDirs := +SubDirs := mach_override Sources := $(foreach file,$(wildcard $(Dir)/*.cc),$(notdir $(file))) ObjNames := $(Sources:%.cc=%.o) @@ -17,6 +17,7 @@ # FIXME: use automatic dependencies? Dependencies := $(wildcard $(Dir)/*.h) +Dependencies += $(wildcard $(Dir)/mach_override/*.h) # Define a convenience variable for all the asan functions. AsanFunctions += $(Sources:%.cc=%) Modified: compiler-rt/trunk/lib/asan/interception/interception_mac.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception_mac.cc?rev=150171&r1=150170&r2=150171&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception_mac.cc (original) +++ compiler-rt/trunk/lib/asan/interception/interception_mac.cc Thu Feb 9 05:36:12 2012 @@ -17,8 +17,7 @@ #define INCLUDED_FROM_INTERCEPTION_LIB #include "interception_mac.h" #undef INCLUDED_FROM_INTERCEPTION_LIB -// FIXME(samsonov): Put mach_override/ under interception/ -#include "../mach_override/mach_override.h" +#include "mach_override/mach_override.h" namespace __interception { bool OverrideFunction(void *old_func, void *new_func, void **orig_old_func) { From samsonov at google.com Thu Feb 9 06:18:08 2012 From: samsonov at google.com (samsonov at google.com) Date: Thu, 09 Feb 2012 12:18:08 +0000 Subject: [llvm-commits] PATCH: AddressSanitizer: move interceptor of pthread_create to asan_posix.cc (issue 5648047) Message-ID: <20cf301af8ff43ce9504b8870123@google.com> Reviewers: ramosian.glider, kcc, Description: AddressSanitizer: move interceptor of pthread_create to asan_posix.cc Please review this at http://codereview.appspot.com/5648047/ Affected files: M asan_interceptors.cc M asan_internal.h M asan_posix.cc -------------- next part -------------- Index: asan_posix.cc =================================================================== --- asan_posix.cc (revision 150171) +++ asan_posix.cc (working copy) @@ -16,6 +16,7 @@ #include "asan_internal.h" #include "asan_interceptors.h" #include "asan_stack.h" +#include "asan_thread.h" #include "asan_thread_registry.h" #include @@ -113,6 +114,27 @@ pthread_setspecific(tsd_key, tsd); } +// ---------------------- Interceptors ---------------- {{{1 +static void *asan_thread_start(void *arg) { + AsanThread *t = (AsanThread*)arg; + asanThreadRegistry().SetCurrent(t); + return t->ThreadStart(); +} + +INTERCEPTOR(int, pthread_create, pthread_t *thread, + const pthread_attr_t *attr, + void *(*start_routine)(void*), void *arg) { + GET_STACK_TRACE_HERE(kStackTraceMax); + int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); + AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); + asanThreadRegistry().RegisterThread(t); + return REAL(pthread_create)(thread, attr, asan_thread_start, t); +} + +void AsanInterceptThreadingRoutines() { + CHECK(INTERCEPT_FUNCTION(pthread_create)); +} + } // namespace __asan #endif // __linux__ || __APPLE_ Index: asan_internal.h =================================================================== --- asan_internal.h (revision 150171) +++ asan_internal.h (working copy) @@ -150,6 +150,9 @@ int SScanf(const char *str, const char *format, ...); void Report(const char *format, ...); +// Interception. +void AsanInterceptThreadingRoutines(); + // Don't use std::min and std::max, to minimize dependency on libstdc++. template T Min(T a, T b) { return a < b ? a : b; } template T Max(T a, T b) { return a > b ? a : b; } Index: asan_interceptors.cc =================================================================== --- asan_interceptors.cc (revision 150171) +++ asan_interceptors.cc (working copy) @@ -26,10 +26,6 @@ #include #include -#ifndef _WIN32 -#include -#endif // _WIN32 - #if defined(__APPLE__) // FIXME(samsonov): Gradually replace system headers with declarations of // intercepted functions. @@ -198,23 +194,7 @@ void operator delete[](void *ptr, std::nothrow_t const&) throw() { OPERATOR_DELETE_BODY;} -static void *asan_thread_start(void *arg) { - AsanThread *t = (AsanThread*)arg; - asanThreadRegistry().SetCurrent(t); - return t->ThreadStart(); -} - #ifndef _WIN32 -INTERCEPTOR(int, pthread_create, pthread_t *thread, - const pthread_attr_t *attr, - void *(*start_routine)(void*), void *arg) { - GET_STACK_TRACE_HERE(kStackTraceMax); - int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); - AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); - asanThreadRegistry().RegisterThread(t); - return REAL(pthread_create)(thread, attr, asan_thread_start, t); -} - INTERCEPTOR(void*, signal, int signum, void *handler) { if (!AsanInterceptsSignal(signum)) { return REAL(signal)(signum, handler); @@ -557,8 +537,9 @@ CHECK(INTERCEPT_FUNCTION(longjmp)); CHECK(INTERCEPT_FUNCTION(_longjmp)); INTERCEPT_FUNCTION(__cxa_throw); - CHECK(INTERCEPT_FUNCTION(pthread_create)); + AsanInterceptThreadingRoutines(); + #ifdef __APPLE__ CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); From benny.kra at googlemail.com Thu Feb 9 06:35:37 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 09 Feb 2012 12:35:37 -0000 Subject: [llvm-commits] [llvm] r150173 - in /llvm/trunk: include/llvm/Target/TargetRegisterInfo.h utils/TableGen/RegisterInfoEmitter.cpp Message-ID: <20120209123537.71D7B2A6C12C@llvm.org> Author: d0k Date: Thu Feb 9 06:35:37 2012 New Revision: 150173 URL: http://llvm.org/viewvc/llvm-project?rev=150173&view=rev Log: Store just the SimpleValueType in the generated VT tables for each register class, eliminating static ctors. Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Modified: llvm/trunk/include/llvm/Target/TargetRegisterInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetRegisterInfo.h?rev=150173&r1=150172&r2=150173&view=diff ============================================================================== --- llvm/trunk/include/llvm/Target/TargetRegisterInfo.h (original) +++ llvm/trunk/include/llvm/Target/TargetRegisterInfo.h Thu Feb 9 06:35:37 2012 @@ -36,7 +36,7 @@ public: typedef const unsigned* iterator; typedef const unsigned* const_iterator; - typedef const EVT* vt_iterator; + typedef const MVT::SimpleValueType* vt_iterator; typedef const TargetRegisterClass* const * sc_iterator; private: virtual void anchor(); @@ -46,7 +46,8 @@ const sc_iterator SuperClasses; const sc_iterator SuperRegClasses; public: - TargetRegisterClass(const MCRegisterClass *MC, const EVT *vts, + TargetRegisterClass(const MCRegisterClass *MC, + const MVT::SimpleValueType *vts, const unsigned *subcm, const TargetRegisterClass * const *supcs, const TargetRegisterClass * const *superregcs) @@ -110,7 +111,7 @@ /// bool hasType(EVT vt) const { for(int i = 0; VTs[i] != MVT::Other; ++i) - if (VTs[i] == vt) + if (EVT(VTs[i]) == vt) return true; return false; } Modified: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp?rev=150173&r1=150172&r2=150173&view=diff ============================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp (original) +++ llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp Thu Feb 9 06:35:37 2012 @@ -521,7 +521,7 @@ // Emit the register list now. OS << " // " << Name << " Register Class Value Types...\n" - << " static const EVT " << Name + << " static const MVT::SimpleValueType " << Name << "[] = {\n "; for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i) OS << getEnumName(RC.VTs[i]) << ", "; From glider at google.com Thu Feb 9 07:39:41 2012 From: glider at google.com (glider at google.com) Date: Thu, 09 Feb 2012 13:39:41 +0000 Subject: [llvm-commits] AddressSanitizer: move interceptor of pthread_create to asan_posix.cc (issue 5648047) Message-ID: <0016e68fcfa2ebc9c604b8882473@google.com> LGTM http://codereview.appspot.com/5648047/ From timurrrr at google.com Thu Feb 9 07:50:22 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 13:50:22 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf300fb4ed20d51204b8884bb5@google.com> PTAL http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc File lib/asan/asan_allocator.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc#newcode692 lib/asan/asan_allocator.cc:692: #if defined(_WIN32) On 2012/02/08 18:03:10, kcc wrote: > instead of the ifdef clatter, I'd prefer to have > if (WINDOWS) Done. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode626 lib/asan/asan_interceptors.cc:626: #ifdef _WIN32 On 2012/02/08 18:03:10, kcc wrote: > if (WINDOWS) please > or "if (ASAN_WINDOWS)" You can't do that - it won't compile on Linux (where we don't include the headers defining memcpy/memset ) Here "#ifdef _WIN32" is doing what it should -> compile some code only on Windows > also, feel free to change the code below to if (ASAN_APPLE) Leaving this up to Alexander, as this might also not compile on non-Apple http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h#newcode63 lib/asan/asan_internal.h:63: # define ASAN_LINUX 1 Defined the ASAN_* macros. I don't like the N^2 number of definitions though http://codereview.appspot.com/5647052/ From timurrrr at google.com Thu Feb 9 07:50:16 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 13:50:16 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <0050450292dac618eb04b8884a58@google.com> PTAL http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc File lib/asan/asan_allocator.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc#newcode692 lib/asan/asan_allocator.cc:692: #if defined(_WIN32) On 2012/02/08 18:03:10, kcc wrote: > instead of the ifdef clatter, I'd prefer to have > if (WINDOWS) Done. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode626 lib/asan/asan_interceptors.cc:626: #ifdef _WIN32 On 2012/02/08 18:03:10, kcc wrote: > if (WINDOWS) please > or "if (ASAN_WINDOWS)" You can't do that - it won't compile on Linux (where we don't include the headers defining memcpy/memset ) Here "#ifdef _WIN32" is doing what it should -> compile some code only on Windows > also, feel free to change the code below to if (ASAN_APPLE) Leaving this up to Alexander, as this might also not compile on non-Apple http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h#newcode63 lib/asan/asan_internal.h:63: # define ASAN_LINUX 1 Defined the ASAN_* macros. I don't like the N^2 number of definitions though http://codereview.appspot.com/5647052/ From timurrrr at google.com Thu Feb 9 07:50:17 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 13:50:17 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <0016368e296fd6ae3404b8884afd@google.com> PTAL http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc File lib/asan/asan_allocator.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_allocator.cc#newcode692 lib/asan/asan_allocator.cc:692: #if defined(_WIN32) On 2012/02/08 18:03:10, kcc wrote: > instead of the ifdef clatter, I'd prefer to have > if (WINDOWS) Done. http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6001/lib/asan/asan_interceptors.cc#newcode626 lib/asan/asan_interceptors.cc:626: #ifdef _WIN32 On 2012/02/08 18:03:10, kcc wrote: > if (WINDOWS) please > or "if (ASAN_WINDOWS)" You can't do that - it won't compile on Linux (where we don't include the headers defining memcpy/memset ) Here "#ifdef _WIN32" is doing what it should -> compile some code only on Windows > also, feel free to change the code below to if (ASAN_APPLE) Leaving this up to Alexander, as this might also not compile on non-Apple http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h#newcode63 lib/asan/asan_internal.h:63: # define ASAN_LINUX 1 Defined the ASAN_* macros. I don't like the N^2 number of definitions though http://codereview.appspot.com/5647052/ From glider at google.com Thu Feb 9 07:53:11 2012 From: glider at google.com (glider at google.com) Date: Thu, 09 Feb 2012 13:53:11 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <0016e6d265b12f05b604b888556b@google.com> http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h#newcode63 lib/asan/asan_internal.h:63: # define ASAN_LINUX 1 #if defined(__linux__) # define ASAN_LINUX 1 #else # define ASAN_LINUX 0 #endif http://codereview.appspot.com/5647052/ From timurrrr at google.com Thu Feb 9 07:55:41 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 13:55:41 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf3005e0f6288fec04b8885eb9@google.com> Shame on me :) http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h File lib/asan/asan_internal.h (right): http://codereview.appspot.com/5647052/diff/10/lib/asan/asan_internal.h#newcode63 lib/asan/asan_internal.h:63: # define ASAN_LINUX 1 On 2012/02/09 13:53:11, glider wrote: > #if defined(__linux__) > # define ASAN_LINUX 1 > #else > # define ASAN_LINUX 0 > #endif Done. http://codereview.appspot.com/5647052/ From baldrick at free.fr Thu Feb 9 08:06:47 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 15:06:47 +0100 Subject: [llvm-commits] [llvm] r149226 - /llvm/trunk/lib/VMCore/Constants.cpp In-Reply-To: <20120130062121.7B36E2A6C12C@llvm.org> References: <20120130062121.7B36E2A6C12C@llvm.org> Message-ID: <4F33D2F7.3060005@free.fr> Hi Chris, > First step of flipping on ConstantDataSequential: enable ConstantDataVector > to be formed whenever ConstantVector::get is used. > --- llvm/trunk/lib/VMCore/Constants.cpp (original) > +++ llvm/trunk/lib/VMCore/Constants.cpp Mon Jan 30 00:21:21 2012 > @@ -836,11 +836,89 @@ > return ConstantAggregateZero::get(T); > if (isUndef) > return UndefValue::get(T); > + > + // Check to see if all of the elements are ConstantFP or ConstantInt and if > + // the element type is compatible with ConstantDataVector. If so, use it. > + if (ConstantDataSequential::isElementTypeCompatible(C->getType())&& > + (isa(C) || isa(C))) { > + // We speculatively build the elements here even if it turns out that there > + // is a constantexpr or something else weird in the array, since it is so > + // uncommon for that to happen. > + if (ConstantInt *CI = dyn_cast(C)) { > + if (CI->getType()->isIntegerTy(8)) { > + SmallVector Elts; > + for (unsigned i = 0, e = V.size(); i != e; ++i) > + if (ConstantInt *CI = dyn_cast(V[i])) > + Elts.push_back(CI->getZExtValue()); > + else > + break; here you know the first element of V is a ConstantInt, since that element is C and you checked C above. So this could be written like this instead SmallVector Elts; Elts.push_back(CI->getZExtValue()); for (unsigned i = 1, e = V.size(); i < e; ++i) if (ConstantInt *CI = dyn_cast(V[i])) Elts.push_back(CI->getZExtValue()); else break; saving one dyn_cast. Maybe not worth it. ... > + } > > + if (ConstantFP *CFP = dyn_cast(C)) { This could be } else if (ConstantFP *CFP = dyn_cast(C)) { saving a pointless dyn_cast if you got here from the ConstantInt case. Ciao, Duncan. From benny.kra at googlemail.com Thu Feb 9 08:26:06 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 09 Feb 2012 14:26:06 -0000 Subject: [llvm-commits] [llvm] r150174 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll Message-ID: <20120209142606.D49FB2A6C12C@llvm.org> Author: d0k Date: Thu Feb 9 08:26:06 2012 New Revision: 150174 URL: http://llvm.org/viewvc/llvm-project?rev=150174&view=rev Log: GlobalOpt: Be more aggressive about elminating side-effect free static dtors. GlobalOpt runs early in the pipeline (before inlining) and complex class hierarchies often introduce bitcasts or GEPs which weren't optimized away. Teach it to ignore side-effect free instructions instead of depending on other passes to remove them. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=150174&r1=150173&r2=150174&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 9 08:26:06 2012 @@ -2753,7 +2753,8 @@ /// destructor and can therefore be eliminated. /// Note that we assume that other optimization passes have already simplified /// the code so we only look for a function with a single basic block, where -/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. +/// the only allowed instructions side-effect free, 'ret' or 'call' to empty +/// C++ dtor. static bool cxxDtorIsEmpty(const Function &Fn, SmallPtrSet &CalledFunctions) { // FIXME: We could eliminate C++ destructors if they're readonly/readnone and @@ -2786,9 +2787,9 @@ if (!cxxDtorIsEmpty(*CalledFn, NewCalledFunctions)) return false; } else if (isa(*I)) - return true; - else - return false; + return true; // We're done. + else if (I->mayHaveSideEffects()) + return false; // Destructor with side effects, bail. } return false; Modified: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=150174&r1=150173&r2=150174&view=diff ============================================================================== --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (original) +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Thu Feb 9 08:26:06 2012 @@ -2,6 +2,7 @@ %0 = type { i32, void ()* } %struct.A = type { i8 } +%struct.B = type { } @a = global %struct.A zeroinitializer, align 1 @__dso_handle = external global i8* @@ -15,13 +16,14 @@ } define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { - call void @_ZN1AD2Ev(%struct.A* %this) + %t = bitcast %struct.A* %this to %struct.B* + call void @_ZN1BD1Ev(%struct.B* %t) ret void } declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) -define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { +define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 { ret void } From baldrick at free.fr Thu Feb 9 08:30:58 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 14:30:58 -0000 Subject: [llvm-commits] [dragonegg] r150175 - /dragonegg/trunk/include/dragonegg/Internals.h Message-ID: <20120209143058.B0B242A6C12C@llvm.org> Author: baldrick Date: Thu Feb 9 08:30:58 2012 New Revision: 150175 URL: http://llvm.org/viewvc/llvm-project?rev=150175&view=rev Log: Flip the order so compilers won't report the cast to void as unreachable. Modified: dragonegg/trunk/include/dragonegg/Internals.h Modified: dragonegg/trunk/include/dragonegg/Internals.h URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=150175&r1=150174&r2=150175&view=diff ============================================================================== --- dragonegg/trunk/include/dragonegg/Internals.h (original) +++ dragonegg/trunk/include/dragonegg/Internals.h Thu Feb 9 08:30:58 2012 @@ -109,8 +109,8 @@ /// DieAbjectly - An unrecoverable fatal error occurred - throw in the towel, /// give up the ghost, quit miserably. inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message) { - llvm_unreachable(Message); (void)Message; // Avoid unused variable warning when assertions are disabled. + llvm_unreachable(Message); } inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message, union gimple_statement_d *stmt){ From baldrick at free.fr Thu Feb 9 08:42:05 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 14:42:05 -0000 Subject: [llvm-commits] [dragonegg] r150176 - in /dragonegg/trunk/src: Convert.cpp Types.cpp x86/Target.cpp Message-ID: <20120209144205.8FCFE2A6C12C@llvm.org> Author: baldrick Date: Thu Feb 9 08:42:05 2012 New Revision: 150176 URL: http://llvm.org/viewvc/llvm-project?rev=150176&view=rev Log: More "assert(false)" -> llvm_unreachable work. Modified: dragonegg/trunk/src/Convert.cpp dragonegg/trunk/src/Types.cpp dragonegg/trunk/src/x86/Target.cpp Modified: dragonegg/trunk/src/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=150176&r1=150175&r2=150176&view=diff ============================================================================== --- dragonegg/trunk/src/Convert.cpp (original) +++ dragonegg/trunk/src/Convert.cpp Thu Feb 9 08:42:05 2012 @@ -1314,7 +1314,7 @@ V = CastToAnyType(V, VisSigned, IntTy, DestIsSigned); return Builder.CreateBitCast(V, DestTy); } - assert(false && "Unable to cast between these types!"); + llvm_unreachable("Unable to cast between these types!"); } // The types are different so we must cast. Use getCastOpcode to create an @@ -6196,7 +6196,7 @@ switch (code) { default: - assert(false && "Unhandled condition code!"); + llvm_unreachable("Unhandled condition code!"); case LT_EXPR: UIPred = CmpInst::ICMP_ULT; SIPred = CmpInst::ICMP_SLT; Modified: dragonegg/trunk/src/Types.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Types.cpp?rev=150176&r1=150175&r2=150176&view=diff ============================================================================== --- dragonegg/trunk/src/Types.cpp (original) +++ dragonegg/trunk/src/Types.cpp Thu Feb 9 08:42:05 2012 @@ -104,7 +104,7 @@ switch (TREE_CODE(type_ref)) { default: - assert(false && "Unexpected tree kind!"); + llvm_unreachable("Unexpected tree kind!"); case ARRAY_TYPE: case COMPLEX_TYPE: case POINTER_TYPE: @@ -148,7 +148,7 @@ static ContainedTypeIterator begin(tree type) { switch (TREE_CODE(type)) { default: - assert(false && "Unknown type!"); + llvm_unreachable("Unknown type!"); case BOOLEAN_TYPE: case ENUMERAL_TYPE: @@ -1226,7 +1226,7 @@ assert(type == TYPE_MAIN_VARIANT(type) && "Not converting the main variant!"); switch (TREE_CODE(type)) { default: - assert(false && "Unknown type!"); + llvm_unreachable("Unknown type!"); case BOOLEAN_TYPE: case ENUMERAL_TYPE: Modified: dragonegg/trunk/src/x86/Target.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/x86/Target.cpp?rev=150176&r1=150175&r2=150176&view=diff ============================================================================== --- dragonegg/trunk/src/x86/Target.cpp (original) +++ dragonegg/trunk/src/x86/Target.cpp Thu Feb 9 08:42:05 2012 @@ -138,7 +138,7 @@ switch (Handler) { case SearchForHandler: - assert(false && "Unexpected builtin code!"); + DieAbjectly("Unexpected builtin code!", stmt); case UnsupportedBuiltin: return false; case addps: case addps256: @@ -884,8 +884,7 @@ Result = Builder.CreateSExt(Result, ResultType); return true; } - DieAbjectly("Builtin not implemented!", stmt); - return false; + llvm_unreachable("Forgot case for code?"); } // One day we will do parameter marshalling right: by using CUMULATIVE_ARGS. From baldrick at free.fr Thu Feb 9 09:19:24 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 15:19:24 -0000 Subject: [llvm-commits] [dragonegg] r150177 - /dragonegg/trunk/src/Convert.cpp Message-ID: <20120209151924.63DF32A6C12D@llvm.org> Author: baldrick Date: Thu Feb 9 09:19:24 2012 New Revision: 150177 URL: http://llvm.org/viewvc/llvm-project?rev=150177&view=rev Log: Avoid warnings about this return being unreachable. Modified: dragonegg/trunk/src/Convert.cpp Modified: dragonegg/trunk/src/Convert.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=150177&r1=150176&r2=150177&view=diff ============================================================================== --- dragonegg/trunk/src/Convert.cpp (original) +++ dragonegg/trunk/src/Convert.cpp Thu Feb 9 09:19:24 2012 @@ -3584,8 +3584,8 @@ #else // Avoid compiler warnings about unused parameters. (void)stmt; (void)fndecl; (void)DestLoc; (void)Result; -#endif return false; +#endif } /// TargetBuiltinCache - A cache of builtin intrinsics indexed by the GCC From spande at codeaurora.org Thu Feb 9 09:20:33 2012 From: spande at codeaurora.org (Sirish Pande) Date: Thu, 09 Feb 2012 15:20:33 -0000 Subject: [llvm-commits] [llvm] r150178 - /llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Message-ID: <20120209152033.9D5F52A6C12D@llvm.org> Author: sirish Date: Thu Feb 9 09:20:33 2012 New Revision: 150178 URL: http://llvm.org/viewvc/llvm-project?rev=150178&view=rev Log: Test for commit access. Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Modified: llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h?rev=150178&r1=150177&r2=150178&view=diff ============================================================================== --- llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h (original) +++ llvm/trunk/lib/Target/Hexagon/MCTargetDesc/HexagonBaseInfo.h Thu Feb 9 09:20:33 2012 @@ -24,7 +24,7 @@ /// namespace HexagonII { - // *** The code below must match HexagonInstrFormat*.td *** + // *** The code below must match HexagonInstrFormat*.td *** // // MCInstrDesc TSFlags enum { @@ -34,7 +34,7 @@ PredicatedMask = 0x1 }; - // *** The code above must match HexagonInstrFormat*.td *** + // *** The code above must match HexagonInstrFormat*.td *** // } // End namespace HexagonII. From baldrick at free.fr Thu Feb 9 09:20:46 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 15:20:46 -0000 Subject: [llvm-commits] [dragonegg] r150179 - /dragonegg/trunk/src/Debug.cpp Message-ID: <20120209152046.CDDF82A6C12D@llvm.org> Author: baldrick Date: Thu Feb 9 09:20:46 2012 New Revision: 150179 URL: http://llvm.org/viewvc/llvm-project?rev=150179&view=rev Log: Remove unreachable "break" statements. Modified: dragonegg/trunk/src/Debug.cpp Modified: dragonegg/trunk/src/Debug.cpp URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Debug.cpp?rev=150179&r1=150178&r2=150179&view=diff ============================================================================== --- dragonegg/trunk/src/Debug.cpp (original) +++ dragonegg/trunk/src/Debug.cpp Thu Feb 9 09:20:46 2012 @@ -1028,7 +1028,6 @@ // Do not cache pointer type. The pointer may point to forward declared // struct. return createPointerType(type); - break; case OFFSET_TYPE: { // gen_type_die(TYPE_OFFSET_BASETYPE(type), context_die); @@ -1056,7 +1055,6 @@ case QUAL_UNION_TYPE: case UNION_TYPE: return createStructType(type); - break; case INTEGER_TYPE: case REAL_TYPE: From craig.topper at gmail.com Thu Feb 9 09:29:22 2012 From: craig.topper at gmail.com (Craig Topper) Date: Thu, 9 Feb 2012 07:29:22 -0800 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F338FB3.7090209@free.fr> References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F32ACA8.9080805@free.fr> <4F338FB3.7090209@free.fr> Message-ID: On Thu, Feb 9, 2012 at 1:19 AM, Duncan Sands wrote: > Hi Craig, > > > I see that you removed all clang support for these builtins, rather >> than having >> clang turn the builtin into a shufflevector instruction (which is what >> I thought >> you did). Is that wise? You just reduced GCC compatibility, when you >> could >> have kept it by expanding the builtins into generic IR. >> >> Ciao, Duncan. >> >> >> That's correct, but what I did is no different than what is already done >> for >> pshufd, shufps/pd, punpckl*, punpckh*, unpcklps/pd, unpckhps/pd, pshuflw, >> pshufhw, etc. >> > > was it really a good idea to remove them? You could have had clang > support them > at little cost, maintaining GCC compatibility. > > I only removed builtins for a couple avx/avx2 instruction, vpermil* and vperm2(f/i)128. pshufd and the others already didn't exist before I got here. > Ciao, Duncan. > -- ~Craig -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/3a341368/attachment.html From hfinkel at anl.gov Thu Feb 9 10:16:22 2012 From: hfinkel at anl.gov (Hal Finkel) Date: Thu, 09 Feb 2012 10:16:22 -0600 Subject: [llvm-commits] [llvm] r149468 - in /llvm/trunk: docs/ include/llvm-c/ include/llvm-c/Transforms/ include/llvm/ include/llvm/Transforms/ include/llvm/Transforms/IPO/ lib/Transforms/ lib/Transforms/IPO/ lib/Transforms/Vectorize/ test/Transforms/BBV In-Reply-To: References: Message-ID: <1328804182.2461.19.camel@sapling> On Thu, 2012-02-09 at 00:17 -0600, Sebastian Pop wrote: > On Tue, Jan 31, 2012 at 9:51 PM, Hal Finkel wrote: > > +namespace { > > + struct BBVectorize : public BasicBlockPass { > > + static char ID; // Pass identification, replacement for typeid > > + BBVectorize() : BasicBlockPass(ID) { > > + initializeBBVectorizePass(*PassRegistry::getPassRegistry()); > > + } > > + > > + typedef std::pair ValuePair; > > + typedef std::pair ValuePairWithDepth; > > + typedef std::pair VPPair; // A ValuePair pair > > + typedef std::pair::iterator, > > + std::multimap::iterator> VPIteratorPair; > > + typedef std::pair::iterator, > > + std::multimap::iterator> > > + VPPIteratorPair; > > + > > + AliasAnalysis *AA; > > + ScalarEvolution *SE; > > + TargetData *TD; > > + > > + // FIXME: const correct? > > + > > + bool vectorizePairs(BasicBlock &BB); > > + > > + void getCandidatePairs(BasicBlock &BB, > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts); > > + > > + void computeConnectedPairs(std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs); > > + > > + void buildDepMap(BasicBlock &BB, > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + DenseSet &PairableInstUsers); > > + > > + void choosePairs(std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs, > > + DenseSet &PairableInstUsers, > > + DenseMap& ChosenPairs); > > + > > + void fuseChosenPairs(BasicBlock &BB, > > + std::vector &PairableInsts, > > + DenseMap& ChosenPairs); > > + > > + bool isInstVectorizable(Instruction *I, bool &IsSimpleLoadStore); > > + > > + bool areInstsCompatible(Instruction *I, Instruction *J, > > + bool IsSimpleLoadStore); > > + > > + bool trackUsesOfI(DenseSet &Users, > > + AliasSetTracker &WriteSet, Instruction *I, > > + Instruction *J, bool UpdateUsers = true, > > + std::multimap *LoadMoveSet = 0); > > + > > + void computePairsConnectedTo( > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs, > > + ValuePair P); > > + > > + bool pairsConflict(ValuePair P, ValuePair Q, > > + DenseSet &PairableInstUsers, > > + std::multimap *PairableInstUserMap = 0); > > + > > + bool pairWillFormCycle(ValuePair P, > > + std::multimap &PairableInstUsers, > > + DenseSet &CurrentPairs); > > + > > + void pruneTreeFor( > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs, > > + DenseSet &PairableInstUsers, > > + std::multimap &PairableInstUserMap, > > + DenseMap &ChosenPairs, > > + DenseMap &Tree, > > + DenseSet &PrunedTree, ValuePair J, > > + bool UseCycleCheck); > > + > > + void buildInitialTreeFor( > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs, > > + DenseSet &PairableInstUsers, > > + DenseMap &ChosenPairs, > > + DenseMap &Tree, ValuePair J); > > + > > + void findBestTreeFor( > > + std::multimap &CandidatePairs, > > + std::vector &PairableInsts, > > + std::multimap &ConnectedPairs, > > + DenseSet &PairableInstUsers, > > + std::multimap &PairableInstUserMap, > > + DenseMap &ChosenPairs, > > + DenseSet &BestTree, size_t &BestMaxDepth, > > + size_t &BestEffSize, VPIteratorPair ChoiceRange, > > + bool UseCycleCheck); > > Having so many parameters to this and other methods above seems wrong: > you could try to refactor this by better structuring the data. I > could see at least the pair of vectorizable instructions and the tree > of pairs split out as separate classes. You can also add some of > these parameters to BBVectorize to avoid to pass them from method to > method. You are absolutely right, this needs to be refactored. I will work on this. Thanks again, Hal > > Sebastian > -- > Qualcomm Innovation Center, Inc is a member of Code Aurora Forum -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory From dblaikie at gmail.com Thu Feb 9 10:17:53 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 9 Feb 2012 08:17:53 -0800 Subject: [llvm-commits] [llvm] r150174 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: <20120209142606.D49FB2A6C12C@llvm.org> References: <20120209142606.D49FB2A6C12C@llvm.org> Message-ID: On Thu, Feb 9, 2012 at 6:26 AM, Benjamin Kramer wrote: > Author: d0k > Date: Thu Feb ?9 08:26:06 2012 > New Revision: 150174 > > URL: http://llvm.org/viewvc/llvm-project?rev=150174&view=rev > Log: > GlobalOpt: Be more aggressive about elminating side-effect free static dtors. > > GlobalOpt runs early in the pipeline (before inlining) and complex class > hierarchies often introduce bitcasts or GEPs which weren't optimized away. > Teach it to ignore side-effect free instructions instead of depending on > other passes to remove them. > > Modified: > ? ?llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > ? ?llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll > > Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=150174&r1=150173&r2=150174&view=diff > ============================================================================== > --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) > +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb ?9 08:26:06 2012 > @@ -2753,7 +2753,8 @@ > ?/// destructor and can therefore be eliminated. > ?/// Note that we assume that other optimization passes have already simplified > ?/// the code so we only look for a function with a single basic block, where > -/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. > +/// the only allowed instructions side-effect free, 'ret' or 'call' to empty > +/// C++ dtor. Is your revised comment missing an 'are' ("allowed instructions >>are<< side-effect free") though when I try to read that the "side-effect free" bit gets jumbled up with the following list, would it make more sense to say: "the only allowed instructions are 'ret' or 'call to an empty C++ dtor, both of which are side-effect free" ? > ?static bool cxxDtorIsEmpty(const Function &Fn, > ? ? ? ? ? ? ? ? ? ? ? ? ? ?SmallPtrSet &CalledFunctions) { > ? // FIXME: We could eliminate C++ destructors if they're readonly/readnone and > @@ -2786,9 +2787,9 @@ > ? ? ? if (!cxxDtorIsEmpty(*CalledFn, NewCalledFunctions)) > ? ? ? ? return false; > ? ? } else if (isa(*I)) > - ? ? ?return true; > - ? ?else > - ? ? ?return false; > + ? ? ?return true; // We're done. > + ? ?else if (I->mayHaveSideEffects()) > + ? ? ?return false; // Destructor with side effects, bail. a few else-after-returns ( http://llvm.org/docs/CodingStandards.html#hl_else_after_return ) - though I realize you didn't write the original code, you were just improving it. > ? } > > ? return false; > > Modified: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll > URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=150174&r1=150173&r2=150174&view=diff > ============================================================================== > --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (original) > +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Thu Feb ?9 08:26:06 2012 > @@ -2,6 +2,7 @@ > > ?%0 = type { i32, void ()* } > ?%struct.A = type { i8 } > +%struct.B = type { } > > ?@a = global %struct.A zeroinitializer, align 1 > ?@__dso_handle = external global i8* > @@ -15,13 +16,14 @@ > ?} > > ?define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { > - ?call void @_ZN1AD2Ev(%struct.A* %this) > + ?%t = bitcast %struct.A* %this to %struct.B* > + ?call void @_ZN1BD1Ev(%struct.B* %t) > ? ret void > ?} > > ?declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) > > -define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { > +define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 { > ? ret void > ?} > > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dblaikie at gmail.com Thu Feb 9 10:18:59 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 9 Feb 2012 08:18:59 -0800 Subject: [llvm-commits] [dragonegg] r150175 - /dragonegg/trunk/include/dragonegg/Internals.h In-Reply-To: <20120209143058.B0B242A6C12C@llvm.org> References: <20120209143058.B0B242A6C12C@llvm.org> Message-ID: On Thu, Feb 9, 2012 at 6:30 AM, Duncan Sands wrote: > Author: baldrick > Date: Thu Feb ?9 08:30:58 2012 > New Revision: 150175 > > URL: http://llvm.org/viewvc/llvm-project?rev=150175&view=rev > Log: > Flip the order so compilers won't report the cast to void as unreachable. > > Modified: > ? ?dragonegg/trunk/include/dragonegg/Internals.h > > Modified: dragonegg/trunk/include/dragonegg/Internals.h > URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=150175&r1=150174&r2=150175&view=diff > ============================================================================== > --- dragonegg/trunk/include/dragonegg/Internals.h (original) > +++ dragonegg/trunk/include/dragonegg/Internals.h Thu Feb ?9 08:30:58 2012 > @@ -109,8 +109,8 @@ > ?/// DieAbjectly - An unrecoverable fatal error occurred - throw in the towel, > ?/// give up the ghost, quit miserably. > ?inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message) { > - ?llvm_unreachable(Message); > ? (void)Message; // Avoid unused variable warning when assertions are disabled. does this actually need to be here at all? I didn't think llvm_unreachable compiled down to nothing when assertions are disabled... > + ?llvm_unreachable(Message); > ?} > ?inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message, > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? union gimple_statement_d *stmt){ > > > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From baldrick at free.fr Thu Feb 9 10:22:23 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 17:22:23 +0100 Subject: [llvm-commits] [dragonegg] r150175 - /dragonegg/trunk/include/dragonegg/Internals.h In-Reply-To: References: <20120209143058.B0B242A6C12C@llvm.org> Message-ID: <4F33F2BF.5030306@free.fr> Hi David, it is needed: >> --- dragonegg/trunk/include/dragonegg/Internals.h (original) >> +++ dragonegg/trunk/include/dragonegg/Internals.h Thu Feb 9 08:30:58 2012 >> @@ -109,8 +109,8 @@ >> /// DieAbjectly - An unrecoverable fatal error occurred - throw in the towel, >> /// give up the ghost, quit miserably. >> inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message) { >> - llvm_unreachable(Message); >> (void)Message; // Avoid unused variable warning when assertions are disabled. > > does this actually need to be here at all? I didn't think > llvm_unreachable compiled down to nothing when assertions are > disabled... #elif defined(LLVM_BUILTIN_UNREACHABLE) #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE ^ no use of msg in this case. That said, maybe there should be a (void)msg in this definition of llvm_unreachable just to suppress this kind of warning. Ciao, Duncan. From dblaikie at gmail.com Thu Feb 9 10:26:14 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 9 Feb 2012 08:26:14 -0800 Subject: [llvm-commits] [dragonegg] r150175 - /dragonegg/trunk/include/dragonegg/Internals.h In-Reply-To: <4F33F2BF.5030306@free.fr> References: <20120209143058.B0B242A6C12C@llvm.org> <4F33F2BF.5030306@free.fr> Message-ID: On Thu, Feb 9, 2012 at 8:22 AM, Duncan Sands wrote: > Hi David, it is needed: > > >>> --- dragonegg/trunk/include/dragonegg/Internals.h (original) >>> +++ dragonegg/trunk/include/dragonegg/Internals.h Thu Feb ?9 08:30:58 >>> 2012 >>> @@ -109,8 +109,8 @@ >>> ?/// DieAbjectly - An unrecoverable fatal error occurred - throw in the >>> towel, >>> ?/// give up the ghost, quit miserably. >>> ?inline void LLVM_ATTRIBUTE_NORETURN DieAbjectly(const char *Message) { >>> - ?llvm_unreachable(Message); >>> ? (void)Message; // Avoid unused variable warning when assertions are >>> disabled. >> >> >> does this actually need to be here at all? I didn't think >> llvm_unreachable compiled down to nothing when assertions are >> disabled... > > > #elif defined(LLVM_BUILTIN_UNREACHABLE) > #define llvm_unreachable(msg) LLVM_BUILTIN_UNREACHABLE > > ^ no use of msg in this case. Right - guess I just haven't done a llvm_unreachable with anything other than a literal before. > That said, maybe there should be a (void)msg in this definition of > llvm_unreachable just to suppress this kind of warning. Quite possibly - hardly seems like it'd be onerous & what you've got is probably the only use of an llvm_unreachable that doesn't take a literal string anyway (so it's not likely to cause weirdness in otehr use cases) - David From benny.kra at googlemail.com Thu Feb 9 10:28:15 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 09 Feb 2012 16:28:15 -0000 Subject: [llvm-commits] [llvm] r150183 - /llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Message-ID: <20120209162815.84F812A6C12E@llvm.org> Author: d0k Date: Thu Feb 9 10:28:15 2012 New Revision: 150183 URL: http://llvm.org/viewvc/llvm-project?rev=150183&view=rev Log: Tweak comment readability and grammar. Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=150183&r1=150182&r2=150183&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 9 10:28:15 2012 @@ -2753,8 +2753,8 @@ /// destructor and can therefore be eliminated. /// Note that we assume that other optimization passes have already simplified /// the code so we only look for a function with a single basic block, where -/// the only allowed instructions side-effect free, 'ret' or 'call' to empty -/// C++ dtor. +/// the only allowed instructions are 'ret', 'call' to an empty C++ dtor and +/// other side-effect free instructions. static bool cxxDtorIsEmpty(const Function &Fn, SmallPtrSet &CalledFunctions) { // FIXME: We could eliminate C++ destructors if they're readonly/readnone and From timurrrr at google.com Thu Feb 9 10:29:41 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Thu, 09 Feb 2012 16:29:41 -0000 Subject: [llvm-commits] [compiler-rt] r150184 - /compiler-rt/trunk/lib/asan/interception/interception.h Message-ID: <20120209162941.5E5A52A6C12E@llvm.org> Author: timurrrr Date: Thu Feb 9 10:29:41 2012 New Revision: 150184 URL: http://llvm.org/viewvc/llvm-project?rev=150184&view=rev Log: Test commit + fix an obvious typo Modified: compiler-rt/trunk/lib/asan/interception/interception.h Modified: compiler-rt/trunk/lib/asan/interception/interception.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/interception/interception.h?rev=150184&r1=150183&r2=150184&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/interception/interception.h (original) +++ compiler-rt/trunk/lib/asan/interception/interception.h Thu Feb 9 10:29:41 2012 @@ -128,7 +128,7 @@ # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) #else // defined(_WIN32) // FIXME: deal with interception on Win. -# define INTERCEPT_FUNCTON(func) true +# define INTERCEPT_FUNCTION(func) true #endif #undef INCLUDED_FROM_INTERCEPTION_LIB From benny.kra at googlemail.com Thu Feb 9 10:33:56 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Thu, 9 Feb 2012 17:33:56 +0100 Subject: [llvm-commits] [llvm] r150174 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: References: <20120209142606.D49FB2A6C12C@llvm.org> Message-ID: <7FC63B48-B4B1-49BD-B5FA-9101E37A0BAD@googlemail.com> On 09.02.2012, at 17:17, David Blaikie wrote: > On Thu, Feb 9, 2012 at 6:26 AM, Benjamin Kramer > wrote: >> Author: d0k >> Date: Thu Feb 9 08:26:06 2012 >> New Revision: 150174 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=150174&view=rev >> Log: >> GlobalOpt: Be more aggressive about elminating side-effect free static dtors. >> >> GlobalOpt runs early in the pipeline (before inlining) and complex class >> hierarchies often introduce bitcasts or GEPs which weren't optimized away. >> Teach it to ignore side-effect free instructions instead of depending on >> other passes to remove them. >> >> Modified: >> llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp >> llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll >> >> Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=150174&r1=150173&r2=150174&view=diff >> ============================================================================== >> --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) >> +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb 9 08:26:06 2012 >> @@ -2753,7 +2753,8 @@ >> /// destructor and can therefore be eliminated. >> /// Note that we assume that other optimization passes have already simplified >> /// the code so we only look for a function with a single basic block, where >> -/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. >> +/// the only allowed instructions side-effect free, 'ret' or 'call' to empty >> +/// C++ dtor. > > Is your revised comment missing an 'are' ("allowed instructions >>> are<< side-effect free") though when I try to read that the > "side-effect free" bit gets jumbled up with the following list, would > it make more sense to say: > > "the only allowed instructions are 'ret' or 'call to an empty C++ > dtor, both of which are side-effect free" I tweaked it a bit in r150183, hopefully more readable now :) > > ? > >> static bool cxxDtorIsEmpty(const Function &Fn, >> SmallPtrSet &CalledFunctions) { >> // FIXME: We could eliminate C++ destructors if they're readonly/readnone and >> @@ -2786,9 +2787,9 @@ >> if (!cxxDtorIsEmpty(*CalledFn, NewCalledFunctions)) >> return false; >> } else if (isa(*I)) >> - return true; >> - else >> - return false; >> + return true; // We're done. >> + else if (I->mayHaveSideEffects()) >> + return false; // Destructor with side effects, bail. > > a few else-after-returns ( > http://llvm.org/docs/CodingStandards.html#hl_else_after_return ) - > though I realize you didn't write the original code, you were just > improving it. The elses are actually needed here, you can fall through the first if. - Ben > >> } >> >> return false; >> >> Modified: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll >> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=150174&r1=150173&r2=150174&view=diff >> ============================================================================== >> --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (original) >> +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Thu Feb 9 08:26:06 2012 >> @@ -2,6 +2,7 @@ >> >> %0 = type { i32, void ()* } >> %struct.A = type { i8 } >> +%struct.B = type { } >> >> @a = global %struct.A zeroinitializer, align 1 >> @__dso_handle = external global i8* >> @@ -15,13 +16,14 @@ >> } >> >> define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { >> - call void @_ZN1AD2Ev(%struct.A* %this) >> + %t = bitcast %struct.A* %this to %struct.B* >> + call void @_ZN1BD1Ev(%struct.B* %t) >> ret void >> } >> >> declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) >> >> -define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { >> +define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 { >> ret void >> } >> >> >> >> _______________________________________________ >> llvm-commits mailing list >> llvm-commits at cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits From dblaikie at gmail.com Thu Feb 9 10:42:43 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 9 Feb 2012 08:42:43 -0800 Subject: [llvm-commits] [llvm] r150174 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/cxx-dtor.ll In-Reply-To: <7FC63B48-B4B1-49BD-B5FA-9101E37A0BAD@googlemail.com> References: <20120209142606.D49FB2A6C12C@llvm.org> <7FC63B48-B4B1-49BD-B5FA-9101E37A0BAD@googlemail.com> Message-ID: On Thu, Feb 9, 2012 at 8:33 AM, Benjamin Kramer wrote: > > On 09.02.2012, at 17:17, David Blaikie wrote: > >> On Thu, Feb 9, 2012 at 6:26 AM, Benjamin Kramer >> wrote: >>> Author: d0k >>> Date: Thu Feb ?9 08:26:06 2012 >>> New Revision: 150174 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=150174&view=rev >>> Log: >>> GlobalOpt: Be more aggressive about elminating side-effect free static dtors. >>> >>> GlobalOpt runs early in the pipeline (before inlining) and complex class >>> hierarchies often introduce bitcasts or GEPs which weren't optimized away. >>> Teach it to ignore side-effect free instructions instead of depending on >>> other passes to remove them. >>> >>> Modified: >>> ? ?llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp >>> ? ?llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll >>> >>> Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=150174&r1=150173&r2=150174&view=diff >>> ============================================================================== >>> --- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original) >>> +++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Thu Feb ?9 08:26:06 2012 >>> @@ -2753,7 +2753,8 @@ >>> ?/// destructor and can therefore be eliminated. >>> ?/// Note that we assume that other optimization passes have already simplified >>> ?/// the code so we only look for a function with a single basic block, where >>> -/// the only allowed instructions are 'ret' or 'call' to empty C++ dtor. >>> +/// the only allowed instructions side-effect free, 'ret' or 'call' to empty >>> +/// C++ dtor. >> >> Is your revised comment missing an 'are' ("allowed instructions >>>> are<< side-effect free") though when I try to read that the >> "side-effect free" bit gets jumbled up with the following list, would >> it make more sense to say: >> >> "the only allowed instructions are 'ret' or 'call to an empty C++ >> dtor, both of which are side-effect free" > > I tweaked it a bit in r150183, hopefully more readable now :) Thanks (: >> >> ? >> >>> ?static bool cxxDtorIsEmpty(const Function &Fn, >>> ? ? ? ? ? ? ? ? ? ? ? ? ? ?SmallPtrSet &CalledFunctions) { >>> ? // FIXME: We could eliminate C++ destructors if they're readonly/readnone and >>> @@ -2786,9 +2787,9 @@ >>> ? ? ? if (!cxxDtorIsEmpty(*CalledFn, NewCalledFunctions)) >>> ? ? ? ? return false; >>> ? ? } else if (isa(*I)) >>> - ? ? ?return true; >>> - ? ?else >>> - ? ? ?return false; >>> + ? ? ?return true; // We're done. >>> + ? ?else if (I->mayHaveSideEffects()) >>> + ? ? ?return false; // Destructor with side effects, bail. >> >> a few else-after-returns ( >> http://llvm.org/docs/CodingStandards.html#hl_else_after_return ) - >> though I realize you didn't write the original code, you were just >> improving it. > > The elses are actually needed here, you can fall through the first if. Ah, cunning. Sorry for the noise. > > - Ben >> >>> ? } >>> >>> ? return false; >>> >>> Modified: llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll >>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll?rev=150174&r1=150173&r2=150174&view=diff >>> ============================================================================== >>> --- llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll (original) >>> +++ llvm/trunk/test/Transforms/GlobalOpt/cxx-dtor.ll Thu Feb ?9 08:26:06 2012 >>> @@ -2,6 +2,7 @@ >>> >>> ?%0 = type { i32, void ()* } >>> ?%struct.A = type { i8 } >>> +%struct.B = type { } >>> >>> ?@a = global %struct.A zeroinitializer, align 1 >>> ?@__dso_handle = external global i8* >>> @@ -15,13 +16,14 @@ >>> ?} >>> >>> ?define linkonce_odr void @_ZN1AD1Ev(%struct.A* %this) nounwind align 2 { >>> - ?call void @_ZN1AD2Ev(%struct.A* %this) >>> + ?%t = bitcast %struct.A* %this to %struct.B* >>> + ?call void @_ZN1BD1Ev(%struct.B* %t) >>> ? ret void >>> ?} >>> >>> ?declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) >>> >>> -define linkonce_odr void @_ZN1AD2Ev(%struct.A* %this) nounwind align 2 { >>> +define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) nounwind align 2 { >>> ? ret void >>> ?} >>> >>> >>> >>> _______________________________________________ >>> llvm-commits mailing list >>> llvm-commits at cs.uiuc.edu >>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits > From timurrrr at google.com Thu Feb 9 10:50:25 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 16:50:25 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <0016e6d99c4104d8f904b88acfe4@google.com> Patch set 6 - rebased against the fresh trunk, otherwise the patch wasn't applying anymore. No new features/code/etc changed between PS5 and PS6 http://codereview.appspot.com/5647052/diff/6002/lib/asan/asan_interceptors.cc File lib/asan/asan_interceptors.cc (right): http://codereview.appspot.com/5647052/diff/6002/lib/asan/asan_interceptors.cc#newcode29 lib/asan/asan_interceptors.cc:29: # include this was removed upstream http://codereview.appspot.com/5647052/ From konstantin.s.serebryany at gmail.com Thu Feb 9 11:21:57 2012 From: konstantin.s.serebryany at gmail.com (konstantin.s.serebryany at gmail.com) Date: Thu, 09 Feb 2012 17:21:57 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <20cf300fb3d1d2431f04b88b3fd0@google.com> Looks good, please commit (and watch the bots). http://codereview.appspot.com/5647052/ From timurrrr at google.com Thu Feb 9 11:24:37 2012 From: timurrrr at google.com (timurrrr at google.com) Date: Thu, 09 Feb 2012 17:24:37 +0000 Subject: [llvm-commits] [ASan] The first version of the RTL for Windows (issue 5647052) Message-ID: <0016e6d99c4157dcb304b88b490c@google.com> r150185, thanks a lot! http://codereview.appspot.com/5647052/ From timurrrr at google.com Thu Feb 9 11:20:14 2012 From: timurrrr at google.com (Timur Iskhodzhanov) Date: Thu, 09 Feb 2012 17:20:14 -0000 Subject: [llvm-commits] [compiler-rt] r150185 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc asan_interceptors.cc asan_internal.h asan_rtl.cc asan_win.cc Message-ID: <20120209172014.6E2881BE003@llvm.org> Author: timurrrr Date: Thu Feb 9 11:20:14 2012 New Revision: 150185 URL: http://llvm.org/viewvc/llvm-project?rev=150185&view=rev Log: [asan] The first version of the RTL for Windows, reviewed at http://codereview.appspot.com/5647052 Added: compiler-rt/trunk/lib/asan/asan_win.cc (with props) Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc compiler-rt/trunk/lib/asan/asan_interceptors.cc compiler-rt/trunk/lib/asan/asan_internal.h compiler-rt/trunk/lib/asan/asan_rtl.cc Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=150185&r1=150184&r2=150185&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_allocator.cc (original) +++ compiler-rt/trunk/lib/asan/asan_allocator.cc Thu Feb 9 11:20:14 2012 @@ -689,6 +689,11 @@ Describe((uintptr_t)ptr, 1); ShowStatsAndAbort(); } else if (m->chunk_state != CHUNK_ALLOCATED) { + if (ASAN_WINDOWS) { + // FIXME: On Windows there are a few extra "unknown free()s" + // from __endstdio, need investigating. + return; + } Report("ERROR: AddressSanitizer attempting free on address which was not" " malloc()-ed: %p\n", ptr); stack->PrintStack(); Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=150185&r1=150184&r2=150185&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original) +++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Thu Feb 9 11:20:14 2012 @@ -27,8 +27,12 @@ #include #ifndef _WIN32 -#include -#endif // _WIN32 +# include +#else +// FIXME: remove when we start intercepting on Windows. Currently it's needed to +// define memset/memcpy intrinsics. +# include +#endif #if defined(__APPLE__) // FIXME(samsonov): Gradually replace system headers with declarations of @@ -559,6 +563,13 @@ INTERCEPT_FUNCTION(__cxa_throw); CHECK(INTERCEPT_FUNCTION(pthread_create)); +#ifdef _WIN32 + // FIXME: We don't intercept properly on Windows yet, so use the original + // functions for now. + REAL(memcpy) = memcpy; + REAL(memset) = memset; +#endif + #ifdef __APPLE__ CHECK(INTERCEPT_FUNCTION(dispatch_async_f)); CHECK(INTERCEPT_FUNCTION(dispatch_sync_f)); Modified: compiler-rt/trunk/lib/asan/asan_internal.h URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=150185&r1=150184&r2=150185&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_internal.h (original) +++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Feb 9 11:20:14 2012 @@ -59,6 +59,24 @@ #endif #endif +#if defined(__linux__) +# define ASAN_LINUX 1 +#else +# define ASAN_LINUX 0 +#endif + +#if defined(__APPLE__) +# define ASAN_MAC 1 +#else +# define ASAN_MAC 0 +#endif + +#if defined(_WIN32) +# define ASAN_WINDOWS 1 +#else +# define ASAN_WINDOWS 0 +#endif + #if !defined(__has_feature) #define __has_feature(x) 0 #endif @@ -215,14 +233,21 @@ const size_t kPageSize = 1UL << kPageSizeBits; #ifndef _WIN32 +const size_t kMmapGranularity = kPageSize; # define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) # define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) #else +const size_t kMmapGranularity = 1UL << 16; # define GET_CALLER_PC() (uintptr_t)_ReturnAddress() // CaptureStackBackTrace doesn't need to know BP on Windows. // FIXME: This macro is still used when printing error reports though it's not // clear if the BP value is needed in the ASan reports on Windows. # define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF + +# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER +# define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize +bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size); +# endif #endif #define GET_BP_PC_SP \ Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=150185&r1=150184&r2=150185&view=diff ============================================================================== --- compiler-rt/trunk/lib/asan/asan_rtl.cc (original) +++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Feb 9 11:20:14 2012 @@ -465,8 +465,8 @@ { if (kLowShadowBeg != kLowShadowEnd) { - // mmap the low shadow plus one page. - ReserveShadowMemoryRange(kLowShadowBeg - kPageSize, kLowShadowEnd); + // mmap the low shadow plus at least one page. + ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd); } // mmap the high shadow. ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd); Added: compiler-rt/trunk/lib/asan/asan_win.cc URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=150185&view=auto ============================================================================== --- compiler-rt/trunk/lib/asan/asan_win.cc (added) +++ compiler-rt/trunk/lib/asan/asan_win.cc Thu Feb 9 11:20:14 2012 @@ -0,0 +1,263 @@ +//===-- asan_win.cc -------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific details. +//===----------------------------------------------------------------------===// +#ifdef _WIN32 +#include + +#include +#include // FIXME: get rid of this. + +#include // FIXME: temporarily needed for placement new in AsanLock. + +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_lock.h" +#include "asan_procmaps.h" +#include "asan_thread.h" + +namespace __asan { + +// ---------------------- Memory management ---------------- {{{1 +void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size) { + return VirtualAlloc((LPVOID)fixed_addr, size, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); +} + +void *AsanMmapSomewhereOrDie(size_t size, const char *mem_type) { + void *rv = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (rv == NULL) + OutOfMemoryMessageAndDie(mem_type, size); + return rv; +} + +void *AsanMprotect(uintptr_t fixed_addr, size_t size) { + return VirtualAlloc((LPVOID)fixed_addr, size, + MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); +} + +void AsanUnmapOrDie(void *addr, size_t size) { + UNIMPLEMENTED(); +} +// }}} + +// ---------------------- IO ---------------- {{{1 +size_t AsanWrite(int fd, const void *buf, size_t count) { + if (fd != 2) + UNIMPLEMENTED(); + + // FIXME: use WriteFile instead? + return fwrite(buf, 1, count, stderr); +} + +// FIXME: Looks like these functions are not needed and are linked in by the +// code unreachable on Windows. We should clean this up. +int AsanOpenReadonly(const char* filename) { + UNIMPLEMENTED(); + return -1; +} + +size_t AsanRead(int fd, void *buf, size_t count) { + UNIMPLEMENTED(); + return -1; +} + +int AsanClose(int fd) { + UNIMPLEMENTED(); + return -1; +} +// }}} + +// ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 +static AsanLock dbghelp_lock(LINKER_INITIALIZED); +static bool dbghelp_initialized = false; +#pragma comment(lib, "dbghelp.lib") + +void AsanThread::SetThreadStackTopAndBottom() { + MEMORY_BASIC_INFORMATION mbi; + CHECK(VirtualQuery(&mbi /* on stack */, + &mbi, sizeof(mbi)) != 0); + // FIXME: is it possible for the stack to not be a single allocation? + // Are these values what ASan expects to get (reserved, not committed; + // including stack guard page) ? + stack_top_ = (uintptr_t)mbi.BaseAddress + mbi.RegionSize; + stack_bottom_ = (uintptr_t)mbi.AllocationBase; +} + +void AsanStackTrace::GetStackTrace(size_t max_s, uintptr_t pc, uintptr_t bp) { + max_size = max_s; + void *tmp[kStackTraceMax]; + + // FIXME: CaptureStackBackTrace might be too slow for us. + // FIXME: Compare with StackWalk64. + // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc + size_t cs_ret = CaptureStackBackTrace(1, max_size, tmp, NULL), + offset = 0; + // Skip the RTL frames by searching for the PC in the stacktrace. + // FIXME: this doesn't work well for the malloc/free stacks yet. + for (size_t i = 0; i < cs_ret; i++) { + if (pc != (uintptr_t)tmp[i]) + continue; + offset = i; + break; + } + + size = cs_ret - offset; + for (size_t i = 0; i < size; i++) + trace[i] = (uintptr_t)tmp[i + offset]; +} + +bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size) { + ScopedLock lock(&dbghelp_lock); + if (!dbghelp_initialized) { + SymSetOptions(SYMOPT_DEFERRED_LOADS | + SYMOPT_UNDNAME | + SYMOPT_LOAD_LINES); + CHECK(SymInitialize(GetCurrentProcess(), NULL, TRUE)); + // FIXME: We don't call SymCleanup() on exit yet - should we? + dbghelp_initialized = true; + } + + // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx + char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)]; + PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer; + symbol->SizeOfStruct = sizeof(SYMBOL_INFO); + symbol->MaxNameLen = MAX_SYM_NAME; + DWORD64 offset = 0; + BOOL got_objname = SymFromAddr(GetCurrentProcess(), + (DWORD64)addr, &offset, symbol); + if (!got_objname) + return false; + + DWORD unused; + IMAGEHLP_LINE64 info; + info.SizeOfStruct = sizeof(IMAGEHLP_LINE64); + BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), + (DWORD64)addr, &unused, &info); + int written = 0; + out_buffer[0] = '\0'; + // FIXME: it might be useful to print out 'obj' or 'obj+offset' info too. + if (got_fileline) { + written += SNPrintf(out_buffer + written, buffer_size - written, + " %s %s:%d", symbol->Name, + info.FileName, info.LineNumber); + } else { + written += SNPrintf(out_buffer + written, buffer_size - written, + " %s+0x%p", symbol->Name, offset); + } + return true; +} +// }}} + +// ---------------------- AsanLock ---------------- {{{1 +enum LockState { + LOCK_UNINITIALIZED = 0, + LOCK_READY = -1, +}; + +AsanLock::AsanLock(LinkerInitialized li) { + // FIXME: see comments in AsanLock::Lock() for the details. + CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED); + + CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); + InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + owner_ = LOCK_READY; +} + +void AsanLock::Lock() { + if (owner_ == LOCK_UNINITIALIZED) { + // FIXME: hm, global AsanLock objects are not initialized?!? + // This might be a side effect of the clang+cl+link Frankenbuild... + new(this) AsanLock((LinkerInitialized)(LINKER_INITIALIZED + 1)); + + // FIXME: If it turns out the linker doesn't invoke our + // constructors, we should probably manually Lock/Unlock all the global + // locks while we're starting in one thread to avoid double-init races. + } + EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + CHECK(owner_ == LOCK_READY); + owner_ = GetThreadSelf(); +} + +void AsanLock::Unlock() { + CHECK(owner_ == GetThreadSelf()); + owner_ = LOCK_READY; + LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); +} +// }}} + +// ---------------------- TSD ---------------- {{{1 +static bool tsd_key_inited = false; + +// FIXME: is __declspec enough? +static __declspec(thread) void *fake_tsd = NULL; + +void AsanTSDInit(void (*destructor)(void *tsd)) { + // FIXME: we're ignoring the destructor for now. + tsd_key_inited = true; +} + +void *AsanTSDGet() { + CHECK(tsd_key_inited); + return fake_tsd; +} + +void AsanTSDSet(void *tsd) { + CHECK(tsd_key_inited); + fake_tsd = tsd; +} +// }}} + +// ---------------------- Various stuff ---------------- {{{1 +void *AsanDoesNotSupportStaticLinkage() { + // FIXME: shall we do anything here on Windows? + return NULL; +} + +int AtomicInc(int *a) { + return InterlockedExchangeAdd((LONG*)a, 1) + 1; +} + +const char* AsanGetEnv(const char* name) { + // FIXME: implement. + return NULL; +} + +int GetPid() { + return GetProcessId(GetCurrentProcess()); +} + +uintptr_t GetThreadSelf() { + return GetCurrentThreadId(); +} + +void InstallSignalHandlers() { + // FIXME: Decide what to do on Windows. +} + +void AsanDisableCoreDumper() { + UNIMPLEMENTED(); +} + +void AsanDie() { + // FIXME: AsanDie() should be the same on all platforms. + if (FLAG_sleep_before_dying) { + Report("Sleeping for %d second(s)\n", FLAG_sleep_before_dying); + Sleep(FLAG_sleep_before_dying * 1000); + } + _exit(FLAG_exitcode); +} +// }}} + +} // namespace __asan + +#endif // _WIN32 Propchange: compiler-rt/trunk/lib/asan/asan_win.cc ------------------------------------------------------------------------------ svn:eol-style = LF From dpatel at apple.com Thu Feb 9 11:34:01 2012 From: dpatel at apple.com (Devang Patel) Date: Thu, 09 Feb 2012 17:34:01 -0000 Subject: [llvm-commits] [llvm] r150187 - /llvm/trunk/docs/SourceLevelDebugging.html Message-ID: <20120209173401.7F1E22A6C12D@llvm.org> Author: dpatel Date: Thu Feb 9 11:34:01 2012 New Revision: 150187 URL: http://llvm.org/viewvc/llvm-project?rev=150187&view=rev Log: Now subprogram descriptors are not collected by llvm.dbg.sp NamedMDNode. Update document to reflect this change. Modified: llvm/trunk/docs/SourceLevelDebugging.html Modified: llvm/trunk/docs/SourceLevelDebugging.html URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/SourceLevelDebugging.html?rev=150187&r1=150186&r2=150187&view=diff ============================================================================== --- llvm/trunk/docs/SourceLevelDebugging.html (original) +++ llvm/trunk/docs/SourceLevelDebugging.html Thu Feb 9 11:34:01 2012 @@ -459,8 +459,6 @@

      These descriptors provide debug information about functions, methods and subprograms. They provide details such as name, return types and the source location where the subprogram is defined. - All subprogram descriptors are collected by a named metadata - !llvm.dbg.sp.

      From nicholas at mxc.ca Thu Feb 9 12:21:57 2012 From: nicholas at mxc.ca (Nick Lewycky) Date: Thu, 09 Feb 2012 10:21:57 -0800 Subject: [llvm-commits] cxa_guard elimination In-Reply-To: <4F338A4E.6040607@mxc.ca> References: <4F0903F9.405@mxc.ca> <4F0BF82B.7030206@mxc.ca> <4F24F0E4.4090701@mxc.ca> <4F24FA31.50601@mxc.ca> <0058FB56-53A7-4012-A83D-3860C965113A@apple.com> <4F2B8CFF.9020606@mxc.ca> <4F338A4E.6040607@mxc.ca> Message-ID: <4F340EC5.5030404@mxc.ca> On 02/09/2012 12:56 AM, Nick Lewycky wrote: > Nick Lewycky wrote: >> Chris Lattner wrote: >>> On Jan 28, 2012, at 11:50 PM, Nick Lewycky wrote: >>>>> The good news is that we already have a valid DomTree by the time >>>>> simplify-libcalls runs, so we're good to request one here. >>>>> >>>>> The updated patch is barely more complicated, there's just an >>>>> additional >>>>> check to see whether there's a single predecessor block that's testing >>>>> the guard variable, and an additional domtree BB test (so, no linear >>>>> time) on each StoreInst. No sweat! >>>>> >>>>> Please review! I'd like to land this patch and then start working on >>>>> some of its deficiencies in follow-up patches. >>>> >>>> Uh... I mailed out the entirely wrong patch. >>>> >>>> Correct patch attached! >>> >>> Hi Nick, >>> >>> Did you consider doing this as part of globalopt? >> >> Yes, that was the next thing in my email :) However, consider that: >> >> - I'd like it to run *after* the inliner so that I don't get fouled up >> by constructor calls > > Of course GlobalOpt is interprocedural, since it already has to not be > fouled up by constructor calls. > > Updated patch attached, including more bugfixes than ever before! Please > review! Updated patch again, now without memory corruption. Also slightly more aggressive by ignoring AllocaTmps when scanning through ReadMemory and MutatedMemory. It turns out that llvm-test is not a good test suite for this particular change. Nick -------------- next part -------------- A non-text attachment was scrubbed... Name: globalopt-cxa_guard-2.patch Type: text/x-diff Size: 38329 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/62783ed5/attachment.bin From stoklund at 2pi.dk Thu Feb 9 12:25:06 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Thu, 09 Feb 2012 18:25:06 -0000 Subject: [llvm-commits] [llvm] r150191 - /llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Message-ID: <20120209182506.2900D2A6C12D@llvm.org> Author: stoklund Date: Thu Feb 9 12:25:05 2012 New Revision: 150191 URL: http://llvm.org/viewvc/llvm-project?rev=150191&view=rev Log: Add register mask support to RAGreedy. This only adds the interference checks required for correctness. We still need to take advantage of register masks for the interference driven live range splitting. Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp?rev=150191&r1=150190&r2=150191&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp Thu Feb 9 12:25:05 2012 @@ -175,6 +175,19 @@ } }; + // Register mask interference. The current VirtReg is checked for register + // mask interference on entry to selectOrSplit(). If there is no + // interference, UsableRegs is left empty. If there is interference, + // UsableRegs has a bit mask of registers that can be used without register + // mask interference. + BitVector UsableRegs; + + /// clobberedByRegMask - Returns true if PhysReg is not directly usable + /// because of register mask clobbers. + bool clobberedByRegMask(unsigned PhysReg) const { + return !UsableRegs.empty() && !UsableRegs.test(PhysReg); + } + // splitting state. std::auto_ptr SA; std::auto_ptr SE; @@ -450,9 +463,12 @@ SmallVectorImpl &NewVRegs) { Order.rewind(); unsigned PhysReg; - while ((PhysReg = Order.next())) + while ((PhysReg = Order.next())) { + if (clobberedByRegMask(PhysReg)) + continue; if (!checkPhysRegInterference(VirtReg, PhysReg)) break; + } if (!PhysReg || Order.isHint(PhysReg)) return PhysReg; @@ -461,7 +477,7 @@ // If we missed a simple hint, try to cheaply evict interference from the // preferred register. if (unsigned Hint = MRI->getSimpleHint(VirtReg.reg)) - if (Order.isHint(Hint)) { + if (Order.isHint(Hint) && !clobberedByRegMask(Hint)) { DEBUG(dbgs() << "missed hint " << PrintReg(Hint, TRI) << '\n'); EvictionCost MaxCost(1); if (canEvictInterference(VirtReg, Hint, true, MaxCost)) { @@ -633,6 +649,8 @@ Order.rewind(); while (unsigned PhysReg = Order.next()) { + if (clobberedByRegMask(PhysReg)) + continue; if (TRI->getCostPerUse(PhysReg) >= CostPerUseLimit) continue; // The first use of a callee-saved register in a function has cost 1. @@ -1559,6 +1577,11 @@ unsigned RAGreedy::selectOrSplit(LiveInterval &VirtReg, SmallVectorImpl &NewVRegs) { + // Check if VirtReg is live across any calls. + UsableRegs.clear(); + if (LIS->checkRegMaskInterference(VirtReg, UsableRegs)) + DEBUG(dbgs() << "Live across regmasks.\n"); + // First try assigning a free register. AllocationOrder Order(VirtReg.reg, *VRM, RegClassInfo); if (unsigned PhysReg = tryAssign(VirtReg, Order, NewVRegs)) From clattner at apple.com Thu Feb 9 12:57:49 2012 From: clattner at apple.com (Chris Lattner) Date: Thu, 09 Feb 2012 10:57:49 -0800 Subject: [llvm-commits] [llvm] r150170 - in /llvm/trunk: include/llvm/MC/MCInstrDesc.h utils/TableGen/InstrInfoEmitter.cpp In-Reply-To: <20120209112509.BC3D02A6C12C@llvm.org> References: <20120209112509.BC3D02A6C12C@llvm.org> Message-ID: <0F2A3A57-6A1C-4E57-A412-F32A5C88F340@apple.com> On Feb 9, 2012, at 3:25 AM, Benjamin Kramer wrote: > Author: d0k > Date: Thu Feb 9 05:25:09 2012 > New Revision: 150170 > > URL: http://llvm.org/viewvc/llvm-project?rev=150170&view=rev > Log: > Move the Name field in MCInstrDesc to the end, saving 8 bytes of padding per entry on x86_64. Nice :) This simple fix cut 22K off ARMMCTargetDesc.o and 35K off X86MCTargetDesc.o! :) -Chris From dblaikie at gmail.com Thu Feb 9 13:24:12 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 09 Feb 2012 19:24:12 -0000 Subject: [llvm-commits] [llvm] r150197 - in /llvm/trunk: include/llvm/Support/system_error.h lib/Support/DataStream.cpp lib/Support/FileUtilities.cpp lib/Support/MemoryBuffer.cpp lib/Support/PathV2.cpp lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV2.inc Message-ID: <20120209192412.CA6A81BE003@llvm.org> Author: dblaikie Date: Thu Feb 9 13:24:12 2012 New Revision: 150197 URL: http://llvm.org/viewvc/llvm-project?rev=150197&view=rev Log: Change default error_code ctor to a 'named ctor' so it's more self-documenting. Unify default construction of error_code uses on this idiom so that users don't feel compelled to make static globals for naming convenience. (unfortunately I couldn't make the original ctor private as some APIs don't return their result, instead using an out parameter (that makes sense to default construct) - which is a bit of a pity. I did, however, find/fix some cases of unnecessary default construction of error_code before I hit the unfixable cases) Modified: llvm/trunk/include/llvm/Support/system_error.h llvm/trunk/lib/Support/DataStream.cpp llvm/trunk/lib/Support/FileUtilities.cpp llvm/trunk/lib/Support/MemoryBuffer.cpp llvm/trunk/lib/Support/PathV2.cpp llvm/trunk/lib/Support/Unix/PathV2.inc llvm/trunk/lib/Support/Windows/PathV2.inc Modified: llvm/trunk/include/llvm/Support/system_error.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/system_error.h?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/include/llvm/Support/system_error.h (original) +++ llvm/trunk/include/llvm/Support/system_error.h Thu Feb 9 13:24:12 2012 @@ -738,6 +738,10 @@ public: error_code() : _val_(0), _cat_(&system_category()) {} + static error_code success() { + return error_code(); + } + error_code(int _val, const error_category& _cat) : _val_(_val), _cat_(&_cat) {} Modified: llvm/trunk/lib/Support/DataStream.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DataStream.cpp?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/DataStream.cpp (original) +++ llvm/trunk/lib/Support/DataStream.cpp Thu Feb 9 13:24:12 2012 @@ -67,7 +67,7 @@ if (Filename == "-") { Fd = 0; sys::Program::ChangeStdinToBinary(); - return error_code(); + return error_code::success(); } int OpenFlags = O_RDONLY; @@ -77,7 +77,7 @@ Fd = ::open(Filename.c_str(), OpenFlags); if (Fd == -1) return error_code(errno, posix_category()); - return error_code(); + return error_code::success(); } }; Modified: llvm/trunk/lib/Support/FileUtilities.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/FileUtilities.cpp?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/FileUtilities.cpp (original) +++ llvm/trunk/lib/Support/FileUtilities.cpp Thu Feb 9 13:24:12 2012 @@ -200,7 +200,6 @@ // Now its safe to mmap the files into memory because both files // have a non-zero size. - error_code ec; OwningPtr F1; if (error_code ec = MemoryBuffer::getFile(FileA.c_str(), F1)) { if (Error) Modified: llvm/trunk/lib/Support/MemoryBuffer.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/MemoryBuffer.cpp?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/MemoryBuffer.cpp (original) +++ llvm/trunk/lib/Support/MemoryBuffer.cpp Thu Feb 9 13:24:12 2012 @@ -36,8 +36,6 @@ #include using namespace llvm; -namespace { const llvm::error_code success; } - //===----------------------------------------------------------------------===// // MemoryBuffer implementation itself. //===----------------------------------------------------------------------===// @@ -306,7 +304,7 @@ RealMapOffset)) { result.reset(GetNamedBuffer( StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator)); - return success; + return error_code::success(); } } @@ -344,7 +342,7 @@ } result.swap(SB); - return success; + return error_code::success(); } //===----------------------------------------------------------------------===// @@ -373,5 +371,5 @@ } while (ReadBytes != 0); result.reset(getMemBufferCopy(Buffer, "")); - return success; + return error_code::success(); } Modified: llvm/trunk/lib/Support/PathV2.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/PathV2.cpp?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/PathV2.cpp (original) +++ llvm/trunk/lib/Support/PathV2.cpp Thu Feb 9 13:24:12 2012 @@ -31,8 +31,6 @@ const char prefered_separator = '/'; #endif - const llvm::error_code success; - StringRef find_first_component(StringRef path) { // Look for this first component in the following order. // * empty (in this case we return an empty string) @@ -607,7 +605,7 @@ // Already absolute. if (rootName && rootDirectory) - return success; + return error_code::success(); // All of the following conditions will need the current directory. SmallString<128> current_dir; @@ -619,7 +617,7 @@ path::append(current_dir, p); // Set path to the result. path.swap(current_dir); - return success; + return error_code::success(); } if (!rootName && rootDirectory) { @@ -628,7 +626,7 @@ path::append(curDirRootName, p); // Set path to the result. path.swap(curDirRootName); - return success; + return error_code::success(); } if (rootName && !rootDirectory) { @@ -640,7 +638,7 @@ SmallString<128> res; path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath); path.swap(res); - return success; + return error_code::success(); } llvm_unreachable("All rootName and rootDirectory combinations should have " @@ -679,7 +677,7 @@ if (error_code ec = status(path, st)) return ec; result = is_directory(st); - return success; + return error_code::success(); } bool is_regular_file(file_status status) { @@ -691,7 +689,7 @@ if (error_code ec = status(path, st)) return ec; result = is_regular_file(st); - return success; + return error_code::success(); } bool is_symlink(file_status status) { @@ -703,7 +701,7 @@ if (error_code ec = status(path, st)) return ec; result = is_symlink(st); - return success; + return error_code::success(); } bool is_other(file_status status) { @@ -730,13 +728,13 @@ if (ec == errc::value_too_large) { // Magic.size() > file_size(Path). result = false; - return success; + return error_code::success(); } return ec; } result = Magic == Buffer; - return success; + return error_code::success(); } /// @brief Identify the magic in magic. @@ -857,7 +855,7 @@ return ec; result = identify_magic(Magic); - return success; + return error_code::success(); } namespace { @@ -884,7 +882,7 @@ ++count; } - return success; + return error_code::success(); } } // end unnamed namespace Modified: llvm/trunk/lib/Support/Unix/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Unix/PathV2.inc?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/Unix/PathV2.inc (original) +++ llvm/trunk/lib/Support/Unix/PathV2.inc Thu Feb 9 13:24:12 2012 @@ -87,7 +87,7 @@ result.clear(); StringRef d(dir); result.append(d.begin(), d.end()); - return success; + return error_code::success(); } } @@ -110,7 +110,7 @@ } result.set_size(strlen(result.data())); - return success; + return error_code::success(); } error_code copy_file(const Twine &from, const Twine &to, copy_option copt) { @@ -169,7 +169,7 @@ if (sz_read < 0) return error_code(errno, system_category()); - return success; + return error_code::success(); } error_code create_directory(const Twine &path, bool &existed) { @@ -183,7 +183,7 @@ } else existed = false; - return success; + return error_code::success(); } error_code create_hard_link(const Twine &to, const Twine &from) { @@ -196,7 +196,7 @@ if (::link(t.begin(), f.begin()) == -1) return error_code(errno, system_category()); - return success; + return error_code::success(); } error_code create_symlink(const Twine &to, const Twine &from) { @@ -209,7 +209,7 @@ if (::symlink(t.begin(), f.begin()) == -1) return error_code(errno, system_category()); - return success; + return error_code::success(); } error_code remove(const Twine &path, bool &existed) { @@ -223,7 +223,7 @@ } else existed = true; - return success; + return error_code::success(); } error_code rename(const Twine &from, const Twine &to) { @@ -245,7 +245,7 @@ return error_code(errno, system_category()); } - return success; + return error_code::success(); } error_code resize_file(const Twine &path, uint64_t size) { @@ -255,7 +255,7 @@ if (::truncate(p.begin(), size) == -1) return error_code(errno, system_category()); - return success; + return error_code::success(); } error_code exists(const Twine &path, bool &result) { @@ -270,7 +270,7 @@ } else result = true; - return success; + return error_code::success(); } bool equivalent(file_status A, file_status B) { @@ -284,7 +284,7 @@ if (error_code ec = status(A, fsA)) return ec; if (error_code ec = status(B, fsB)) return ec; result = equivalent(fsA, fsB); - return success; + return error_code::success(); } error_code file_size(const Twine &path, uint64_t &result) { @@ -298,7 +298,7 @@ return make_error_code(errc::operation_not_permitted); result = status.st_size; - return success; + return error_code::success(); } error_code status(const Twine &path, file_status &result) { @@ -333,7 +333,7 @@ result.st_dev = status.st_dev; result.st_ino = status.st_ino; - return success; + return error_code::success(); } error_code unique_file(const Twine &model, int &result_fd, @@ -428,7 +428,7 @@ result_path.append(d.begin(), d.end()); result_fd = RandomFD; - return success; + return error_code::success(); } error_code detail::directory_iterator_construct(detail::DirIterState &it, @@ -450,7 +450,7 @@ ::closedir(reinterpret_cast(it.IterationHandle)); it.IterationHandle = 0; it.CurrentEntry = directory_entry(); - return success; + return error_code::success(); } error_code detail::directory_iterator_increment(detail::DirIterState &it) { @@ -467,7 +467,7 @@ } else return directory_iterator_destruct(it); - return success; + return error_code::success(); } error_code get_magic(const Twine &path, uint32_t len, @@ -498,7 +498,7 @@ } std::fclose(file); result.set_size(len); - return success; + return error_code::success(); } } // end namespace fs Modified: llvm/trunk/lib/Support/Windows/PathV2.inc URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/Windows/PathV2.inc?rev=150197&r1=150196&r2=150197&view=diff ============================================================================== --- llvm/trunk/lib/Support/Windows/PathV2.inc (original) +++ llvm/trunk/lib/Support/Windows/PathV2.inc Thu Feb 9 13:24:12 2012 @@ -62,7 +62,7 @@ utf16.push_back(0); utf16.pop_back(); - return success; + return error_code::success(); } error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len, @@ -92,7 +92,7 @@ utf8.push_back(0); utf8.pop_back(); - return success; + return error_code::success(); } error_code TempDir(SmallVectorImpl &result) { @@ -108,7 +108,7 @@ } result.set_size(len); - return success; + return error_code::success(); } bool is_separator(const wchar_t value) { @@ -167,7 +167,7 @@ if (len == 0) return windows_error(::GetLastError()); - return success; + return error_code::success(); } error_code copy_file(const Twine &from, const Twine &to, copy_option copt) { @@ -190,7 +190,7 @@ if (res == 0) return windows_error(::GetLastError()); - return success; + return error_code::success(); } error_code create_directory(const Twine &path, bool &existed) { @@ -210,7 +210,7 @@ } else existed = false; - return success; + return error_code::success(); } error_code create_hard_link(const Twine &to, const Twine &from) { @@ -229,7 +229,7 @@ if (!::CreateHardLinkW(wide_from.begin(), wide_to.begin(), NULL)) return windows_error(::GetLastError()); - return success; + return error_code::success(); } error_code create_symlink(const Twine &to, const Twine &from) { @@ -252,7 +252,7 @@ if (!create_symbolic_link_api(wide_from.begin(), wide_to.begin(), 0)) return windows_error(::GetLastError()); - return success; + return error_code::success(); } error_code remove(const Twine &path, bool &existed) { @@ -285,7 +285,7 @@ existed = true; } - return success; + return error_code::success(); } error_code rename(const Twine &from, const Twine &to) { @@ -305,7 +305,7 @@ MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING)) return windows_error(::GetLastError()); - return success; + return error_code::success(); } error_code resize_file(const Twine &path, uint64_t size) { @@ -347,7 +347,7 @@ result = false; } else result = true; - return success; + return error_code::success(); } bool equivalent(file_status A, file_status B) { @@ -366,7 +366,7 @@ if (error_code ec = status(A, fsA)) return ec; if (error_code ec = status(B, fsB)) return ec; result = equivalent(fsA, fsB); - return success; + return error_code::success(); } error_code file_size(const Twine &path, uint64_t &result) { @@ -387,7 +387,7 @@ (uint64_t(FileData.nFileSizeHigh) << (sizeof(FileData.nFileSizeLow) * 8)) + FileData.nFileSizeLow; - return success; + return error_code::success(); } static bool isReservedName(StringRef path) { @@ -420,7 +420,7 @@ StringRef path8 = path.toStringRef(path_storage); if (isReservedName(path8)) { result = file_status(file_type::character_file); - return success; + return error_code::success(); } if (error_code ec = UTF8ToUTF16(path8, path_utf16)) @@ -470,7 +470,7 @@ result.VolumeSerialNumber = Info.dwVolumeSerialNumber; } - return success; + return error_code::success(); handle_status_error: error_code ec = windows_error(::GetLastError()); @@ -484,7 +484,7 @@ return ec; } - return success; + return error_code::success(); } error_code unique_file(const Twine &model, int &result_fd, @@ -611,7 +611,7 @@ } result_fd = fd; - return success; + return error_code::success(); } error_code get_magic(const Twine &path, uint32_t len, @@ -653,7 +653,7 @@ } result.set_size(len); - return success; + return error_code::success(); } error_code detail::directory_iterator_construct(detail::DirIterState &it, @@ -705,7 +705,7 @@ path::append(directory_entry_path, directory_entry_name_utf8.str()); it.CurrentEntry = directory_entry(directory_entry_path.str()); - return success; + return error_code::success(); } error_code detail::directory_iterator_destruct(detail::DirIterState &it) { @@ -714,7 +714,7 @@ ScopedFindHandle close(HANDLE(it.IterationHandle)); it.IterationHandle = 0; it.CurrentEntry = directory_entry(); - return success; + return error_code::success(); } error_code detail::directory_iterator_increment(detail::DirIterState &it) { @@ -740,7 +740,7 @@ return ec; it.CurrentEntry.replace_filename(Twine(directory_entry_path_utf8)); - return success; + return error_code::success(); } } // end namespace fs From dag at cray.com Thu Feb 9 14:21:58 2012 From: dag at cray.com (David Greene) Date: Thu, 9 Feb 2012 14:21:58 -0600 Subject: [llvm-commits] [PATCH] Add Foreach Loop Message-ID: <0372d45abc0e643b756cf0e8b139060dbf9876e7.1328818538.git.dag@cray.com> Here is an updated version of the foreach patch series, squashed as requested. I think I have addressed all of the review feedback. Please review. Thanks! -Dave Add some data structures to represent for loops. These will be referenced during object processing to do any needed iteration and instantiation. Add foreach keyword support to the lexer. Add a mode to indicate that we're parsing a foreach loop. This allows the value parser to early-out when processing the foreach value list. Add a routine to parse foreach iteration declarations. This is separate from ParseDeclaration because the type of the named value (the iterator) doesn't match the type of the initializer value (the value list). It also needs to add two values to the foreach record: the iterator and the value list. Add parsing support for foreach. Add the code to process foreach loops and create defs based on iterator values. Allow foreach loops to be matched at the top level. When parsing an IDValue check if it is a foreach loop iterator for one of the active loops. If so, return a VarInit for it. Add Emacs keyword support for foreach. Add VIM keyword support for foreach. Add tests to check foreach operation. Add TableGen documentation for foreach. --- llvm/docs/TableGenFundamentals.html | 28 +++++ llvm/include/llvm/TableGen/Record.h | 1 + llvm/lib/TableGen/TGLexer.cpp | 1 + llvm/lib/TableGen/TGLexer.h | 2 +- llvm/lib/TableGen/TGParser.cpp | 195 ++++++++++++++++++++++++++++++++++- llvm/lib/TableGen/TGParser.h | 73 +++++++++++++- llvm/test/TableGen/ForeachLoop.td | 43 ++++++++ llvm/test/TableGen/NestedForeach.td | 74 +++++++++++++ llvm/utils/emacs/tablegen-mode.el | 2 +- llvm/utils/vim/tablegen.vim | 2 +- 10 files changed, 414 insertions(+), 7 deletions(-) create mode 100644 llvm/test/TableGen/ForeachLoop.td create mode 100644 llvm/test/TableGen/NestedForeach.td diff --git old/llvm/docs/TableGenFundamentals.html new/llvm/docs/TableGenFundamentals.html index 6db1827..2030bc8 100644 --- old/llvm/docs/TableGenFundamentals.html +++ new/llvm/docs/TableGenFundamentals.html @@ -37,6 +37,7 @@
      1. File inclusion
      2. 'let' expressions
      3. +
      4. 'foreach' blocks
    • TableGen backends @@ -401,6 +402,11 @@ which case the user must specify it explicitly.
      list[4-7,17,2-3]
      A slice of the 'list' list, including elements 4,5,6,7,17,2, and 3 from it. Elements may be included multiple times.
      +
      foreach <var> = <list> { <body> }
      +
      Replicate <body> replacing instances of <var> with each value + in <list>. <var> is scoped at the level of the foreach + loop and must not conflict with any other object introduced in <body>. + Currently only defs are expanded within <body>.
      (DEF a, b)
      a dag value. The first element is required to be a record definition, the remaining elements in the list may be arbitrary other values, including nested @@ -880,6 +886,28 @@ several levels of multiclass instanciations. This also avoids the need of using + +

      + Looping +

      + +
      +

      TableGen supports the 'foreach' block, which textually replicates +the loop body, substituting iterator values for iterator references in the +body. Example:

      + +
      +
      +foreach i = [0, 1, 2, 3] {
      +  def R#i : Register<...>;
      +}
      +
      +
      + +

      This will create objects R0, R1, R2 and +R3. foreach blocks may be nested.

      +
      + diff --git old/llvm/include/llvm/TableGen/Record.h new/llvm/include/llvm/TableGen/Record.h index f51af28..5e68c10 100644 --- old/llvm/include/llvm/TableGen/Record.h +++ new/llvm/include/llvm/TableGen/Record.h @@ -1535,6 +1535,7 @@ struct MultiClass { class RecordKeeper { std::map Classes, Defs; + public: ~RecordKeeper() { for (std::map::iterator I = Classes.begin(), diff --git old/llvm/lib/TableGen/TGLexer.cpp new/llvm/lib/TableGen/TGLexer.cpp index 79d9ed2..ff322e7 100644 --- old/llvm/lib/TableGen/TGLexer.cpp +++ new/llvm/lib/TableGen/TGLexer.cpp @@ -274,6 +274,7 @@ tgtok::TokKind TGLexer::LexIdentifier() { .Case("dag", tgtok::Dag) .Case("class", tgtok::Class) .Case("def", tgtok::Def) + .Case("foreach", tgtok::Foreach) .Case("defm", tgtok::Defm) .Case("multiclass", tgtok::MultiClass) .Case("field", tgtok::Field) diff --git old/llvm/lib/TableGen/TGLexer.h new/llvm/lib/TableGen/TGLexer.h index 0246ab6..8a850b5 100644 --- old/llvm/lib/TableGen/TGLexer.h +++ new/llvm/lib/TableGen/TGLexer.h @@ -42,7 +42,7 @@ namespace tgtok { paste, // # // Keywords. - Bit, Bits, Class, Code, Dag, Def, Defm, Field, In, Int, Let, List, + Bit, Bits, Class, Code, Dag, Def, Foreach, Defm, Field, In, Int, Let, List, MultiClass, String, // !keywords. diff --git old/llvm/lib/TableGen/TGParser.cpp new/llvm/lib/TableGen/TGParser.cpp index c7cf097..6a25455 100644 --- old/llvm/lib/TableGen/TGParser.cpp +++ new/llvm/lib/TableGen/TGParser.cpp @@ -289,6 +289,108 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC, return false; } +/// ProcessForeachDefs - Given a record, apply all of the variable +/// values in all surrounding foreach loops, creating new records for +/// each combination of values. +bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass, + SMLoc Loc) { + // We want to instantiate a new copy of CurRec for each combination + // of nested loop iterator values. We don't want top instantiate + // any copies until we have values for each loop iterator. + IterSet IterVals; + for (loop_iterator Loop = loops_begin(), LoopEnd = loops_end(); + Loop != LoopEnd; + ++Loop) { + // Process this loop. + if (ProcessForeachDefs(CurRec, CurMultiClass, Loc, + IterVals, *Loop, Loop+1)) { + Error(Loc, + "Could not process loops for def " + CurRec->getNameInitAsString()); + return true; + } + } + + return false; +} + +/// ProcessForeachDefs - Given a record, a loop and a loop iterator, +/// apply each of the variable values in this loop and then process +/// subloops. +bool TGParser::ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass, + SMLoc Loc, IterSet &IterVals, + ForeachLoop &CurLoop, + loop_iterator NextLoop) { + Init *IterVar = CurLoop.IterVar; + ListInit *List = dynamic_cast(CurLoop.ListValue); + + if (List == 0) { + Error(Loc, "Loop list is not a list"); + return true; + } + + // Process each value. + for (int64_t i = 0; i < List->getSize(); ++i) { + Init *ItemVal = List->resolveListElementReference(*CurRec, 0, i); + IterVals.push_back(IterRecord(IterVar, ItemVal)); + + if (IterVals.size() == loops_size()) { + // Ok, we have all of the iterator values for this point in the + // iteration space. Instantiate a new record to reflect this + // combination of values. + Record *IterRec = new Record(*CurRec); + + // Set the iterator values now. + for (IterSet::iterator i = IterVals.begin(), iend = IterVals.end(); + i != iend; + ++i) { + VarInit *IterVar = dynamic_cast(i->IterVar); + if (IterVar == 0) { + Error(Loc, "foreach iterator is unresolved"); + return true; + } + + TypedInit *IVal = dynamic_cast(i->IterValue); + if (IVal == 0) { + Error(Loc, "foreach iterator value is untyped"); + return true; + } + + IterRec->addValue(RecordVal(IterVar->getName(), IVal->getType(), false)); + + if (SetValue(IterRec, Loc, IterVar->getName(), + std::vector(), IVal)) { + Error(Loc, "when instantiating this def"); + return true; + } + + // Resolve it next. + IterRec->resolveReferencesTo(IterRec->getValue(IterVar->getName())); + + // Remove it. + IterRec->removeValue(IterVar->getName()); + } + + Records.addDef(IterRec); + IterRec->resolveReferences(); + } + + if (NextLoop != loops_end()) { + // Process nested loops. + if (ProcessForeachDefs(CurRec, CurMultiClass, Loc, IterVals, *NextLoop, + NextLoop+1)) { + Error(Loc, + "Could not process loops for def " + + CurRec->getNameInitAsString()); + return true; + } + } + + // We're done with this iterator. + IterVals.pop_back(); + } + return false; +} + //===----------------------------------------------------------------------===// // Parser Code //===----------------------------------------------------------------------===// @@ -296,7 +398,8 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC, /// isObjectStart - Return true if this is a valid first token for an Object. static bool isObjectStart(tgtok::TokKind K) { return K == tgtok::Class || K == tgtok::Def || - K == tgtok::Defm || K == tgtok::Let || K == tgtok::MultiClass; + K == tgtok::Defm || K == tgtok::Let || + K == tgtok::MultiClass || K == tgtok::Foreach; } static std::string GetNewAnonymousName() { @@ -698,6 +801,15 @@ Init *TGParser::ParseIDValue(Record *CurRec, } } + // If this is in a foreach loop, make sure it's not a loop iterator + for (loop_iterator i = loops_begin(), iend = loops_end(); + i != iend; + ++i) { + VarInit *IterVar = dynamic_cast(i->IterVar); + if (IterVar && IterVar->getName() == Name) + return IterVar; + } + if (Mode == ParseNameMode) return StringInit::get(Name); @@ -1353,7 +1465,7 @@ Init *TGParser::ParseValue(Record *CurRec, RecTy *ItemType, IDParseMode Mode) { switch (Lex.getCode()) { default: return Result; case tgtok::l_brace: { - if (Mode == ParseNameMode) + if (Mode == ParseNameMode || Mode == ParseForeachMode) // This is the beginning of the object body. return Result; @@ -1605,6 +1717,42 @@ Init *TGParser::ParseDeclaration(Record *CurRec, return DeclName; } +/// ParseForeachDeclaration - Read a foreach declaration, returning +/// the name of the declared object or a NULL Init on error. Return +/// the name of the parsed initializer list through ForeachListName. +/// +/// ForeachDeclaration ::= Type ID '=' Value +/// +Init *TGParser::ParseForeachDeclaration(Init *&ForeachListValue) { + RecTy *Type = ParseType(); + if (Type == 0) return 0; + + if (Lex.getCode() != tgtok::Id) { + TokError("Expected identifier in foreach declaration"); + return 0; + } + + Init *DeclName = StringInit::get(Lex.getCurStrVal()); + Lex.Lex(); + + VarInit *IterVar = VarInit::get(DeclName, Type); + + // If a value is present, parse it. + if (Lex.getCode() != tgtok::equal) { + TokError("Expected '=' in foreach declaration"); + return 0; + } + Lex.Lex(); // Eat the '=' + + RecTy *ValueType = Type; + + // Expect a list initializer. + ValueType = ListRecTy::get(Type); + ForeachListValue = ParseValue(0, ValueType, ParseForeachMode); + + return IterVar; +} + /// ParseTemplateArgList - Read a template argument list, which is a non-empty /// sequence of template-declarations in <>'s. If CurRec is non-null, these are /// template args for a def, which may or may not be in a multiclass. If null, @@ -1817,6 +1965,47 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) { } } + if (ProcessForeachDefs(CurRec, CurMultiClass, DefLoc)) { + Error(DefLoc, + "Could not process loops for def" + CurRec->getNameInitAsString()); + return true; + } + + return false; +} + +/// ParseForeach - Parse a for statement. Return the record corresponding +/// to it. This returns true on error. +/// +/// For ::= FOREACH Declaration '=' Value ObjectBody +/// +bool TGParser::ParseForeach(MultiClass *CurMultiClass) { + assert(Lex.getCode() == tgtok::Foreach && "Unknown tok"); + Lex.Lex(); // Eat the 'for' token. + + // Make a temporary object to record items associated with the for + // loop. + Init *ListValue = 0; + Init *IterName = ParseForeachDeclaration(ListValue); + if (IterName == 0) + return TokError("expected declaration in for"); + + if (Lex.getCode() != tgtok::l_brace) + return TokError("Unknown tok"); + Lex.Lex(); // Eat the { + + // Create a loop object and remember it. + pushLoop(ForeachLoop(IterName, ListValue)); + + while (Lex.getCode() != tgtok::r_brace) { + if (ParseObject(CurMultiClass)) + return true; + } + Lex.Lex(); // Eat the } + + // We've processed everything in this loop. + popLoop(); + return false; } @@ -2010,6 +2199,7 @@ bool TGParser::ParseMultiClass() { case tgtok::Let: case tgtok::Def: case tgtok::Defm: + case tgtok::Foreach: if (ParseObject(CurMultiClass)) return true; break; @@ -2305,6 +2495,7 @@ bool TGParser::ParseObject(MultiClass *MC) { return TokError("Expected class, def, defm, multiclass or let definition"); case tgtok::Let: return ParseTopLevelLet(MC); case tgtok::Def: return ParseDef(MC); + case tgtok::Foreach: return ParseForeach(MC); case tgtok::Defm: return ParseDefm(MC); case tgtok::Class: return ParseClass(); case tgtok::MultiClass: return ParseMultiClass(); diff --git old/llvm/lib/TableGen/TGParser.h new/llvm/lib/TableGen/TGParser.h index 54cd99a..e8b370e 100644 --- old/llvm/lib/TableGen/TGParser.h +++ new/llvm/lib/TableGen/TGParser.h @@ -42,11 +42,25 @@ namespace llvm { } }; + /// ForeachLoop - Record the iteration state associated with a for loop. + /// This is used to instantiate items in the loop body. + struct ForeachLoop { + Init *IterVar; + Init *ListValue; + + ForeachLoop(Init *IVar, Init *LValue) : IterVar(IVar), ListValue(LValue) {}; + }; + class TGParser { TGLexer Lex; std::vector > LetStack; std::map MultiClasses; + /// Loops - Keep track of any foreach loops we are within. + /// + typedef std::vector LoopVector; + LoopVector Loops; + /// CurMultiClass - If we are parsing a 'multiclass' definition, this is the /// current value. MultiClass *CurMultiClass; @@ -60,8 +74,10 @@ class TGParser { // in the middle of creating in. For those situations, allow the // parser to ignore missing object errors. enum IDParseMode { - ParseValueMode, // We are parsing a value we expect to look up. - ParseNameMode // We are parsing a name of an object that does not yet exist. + ParseValueMode, // We are parsing a value we expect to look up. + ParseNameMode, // We are parsing a name of an object that does not yet + // exist. + ParseForeachMode // We are parsing a foreach init. }; public: @@ -82,6 +98,40 @@ public: const std::vector &getDependencies() const { return Lex.getDependencies(); } + + // Foreach management. + + /// pushLoop - Add a loop to the existing loop context. + /// + void pushLoop(const ForeachLoop &loop) { + Loops.push_back(loop); + } + + /// popLoop - Pop a loop from the existing loop context. + /// + void popLoop() { + Loops.pop_back(); + } + + /// topLoop - Return a reference to the current innermost loop. + /// + ForeachLoop &topLoop() { + assert(!Loops.empty() && "Loop underflow!"); + return Loops.back(); + } + + typedef LoopVector::iterator loop_iterator; + + loop_iterator loops_begin() { + return Loops.begin(); + } + loop_iterator loops_end() { + return Loops.end(); + } + std::size_t loops_size() { + return Loops.size(); + } + private: // Semantic analysis methods. bool AddValue(Record *TheRec, SMLoc Loc, const RecordVal &RV); bool SetValue(Record *TheRec, SMLoc Loc, Init *ValName, @@ -94,6 +144,23 @@ private: // Semantic analysis methods. bool AddSubMultiClass(MultiClass *CurMC, SubMultiClassReference &SubMultiClass); + // IterRecord: Map an iterator name to a value. + struct IterRecord { + Init *IterVar; + Init *IterValue; + IterRecord(Init *Var, Init *Val) : IterVar(Var), IterValue(Val) {} + }; + + // IterSet: The set of all iterator values at some point in the + // iteration space. + typedef std::vector IterSet; + + bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass, + SMLoc Loc); + bool ProcessForeachDefs(Record *CurRec, MultiClass *CurMultiClass, + SMLoc Loc, IterSet &IterVals, ForeachLoop &CurLoop, + loop_iterator NextLoop); + private: // Parser methods. bool ParseObjectList(MultiClass *MC = 0); bool ParseObject(MultiClass *MC); @@ -116,6 +183,7 @@ private: // Parser methods. SMLoc DefmPrefixLoc); bool ParseDefm(MultiClass *CurMultiClass); bool ParseDef(MultiClass *CurMultiClass); + bool ParseForeach(MultiClass *CurMultiClass); bool ParseTopLevelLet(MultiClass *CurMultiClass); std::vector ParseLetList(); @@ -125,6 +193,7 @@ private: // Parser methods. bool ParseTemplateArgList(Record *CurRec); Init *ParseDeclaration(Record *CurRec, bool ParsingTemplateArgs); + Init *ParseForeachDeclaration(Init *&ForeachListValue); SubClassReference ParseSubClassReference(Record *CurRec, bool isDefm); SubMultiClassReference ParseSubMultiClassReference(MultiClass *CurMC); diff --git old/llvm/test/TableGen/ForeachLoop.td new/llvm/test/TableGen/ForeachLoop.td new file mode 100644 index 0000000..97fc8af3 --- /dev/null +++ new/llvm/test/TableGen/ForeachLoop.td @@ -0,0 +1,43 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +class Register { + string Name = name; + int Index = idx; +} + +foreach int i = [0, 1, 2, 3, 4, 5, 6, 7] { + def R#i : Register<"R"#i, i>; +} + +// CHECK: def R0 +// CHECK: string Name = "R0"; +// CHECK: int Index = 0; + +// CHECK: def R1 +// CHECK: string Name = "R1"; +// CHECK: int Index = 1; + +// CHECK: def R2 +// CHECK: string Name = "R2"; +// CHECK: int Index = 2; + +// CHECK: def R3 +// CHECK: string Name = "R3"; +// CHECK: int Index = 3; + +// CHECK: def R4 +// CHECK: string Name = "R4"; +// CHECK: int Index = 4; + +// CHECK: def R5 +// CHECK: string Name = "R5"; +// CHECK: int Index = 5; + +// CHECK: def R6 +// CHECK: string Name = "R6"; +// CHECK: int Index = 6; + +// CHECK: def R7 +// CHECK: string Name = "R7"; +// CHECK: int Index = 7; diff --git old/llvm/test/TableGen/NestedForeach.td new/llvm/test/TableGen/NestedForeach.td new file mode 100644 index 0000000..05e0952 --- /dev/null +++ new/llvm/test/TableGen/NestedForeach.td @@ -0,0 +1,74 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +class Droid { + string Series = series; + int Release = release; + string Model = model; + int Patchlevel = patchlevel; +} + +foreach string S = ["R", "C"] { + foreach int R = [2, 3, 4] { + foreach string M = ["D", "P", "Q"] { + foreach int P = [0, 2, 4] { + def S#R#M#P : Droid; + } + } + } +} + +// CHECK: def C2D0 +// CHECK: def C2D2 +// CHECK: def C2D4 +// CHECK: def C2P0 +// CHECK: def C2P2 +// CHECK: def C2P4 +// CHECK: def C2Q0 +// CHECK: def C2Q2 +// CHECK: def C2Q4 +// CHECK: def C3D0 +// CHECK: def C3D2 +// CHECK: def C3D4 +// CHECK: def C3P0 +// CHECK: def C3P2 +// CHECK: def C3P4 +// CHECK: def C3Q0 +// CHECK: def C3Q2 +// CHECK: def C3Q4 +// CHECK: def C4D0 +// CHECK: def C4D2 +// CHECK: def C4D4 +// CHECK: def C4P0 +// CHECK: def C4P2 +// CHECK: def C4P4 +// CHECK: def C4Q0 +// CHECK: def C4Q2 +// CHECK: def C4Q4 +// CHECK: def R2D0 +// CHECK: def R2D2 +// CHECK: def R2D4 +// CHECK: def R2P0 +// CHECK: def R2P2 +// CHECK: def R2P4 +// CHECK: def R2Q0 +// CHECK: def R2Q2 +// CHECK: def R2Q4 +// CHECK: def R3D0 +// CHECK: def R3D2 +// CHECK: def R3D4 +// CHECK: def R3P0 +// CHECK: def R3P2 +// CHECK: def R3P4 +// CHECK: def R3Q0 +// CHECK: def R3Q2 +// CHECK: def R3Q4 +// CHECK: def R4D0 +// CHECK: def R4D2 +// CHECK: def R4D4 +// CHECK: def R4P0 +// CHECK: def R4P2 +// CHECK: def R4P4 +// CHECK: def R4Q0 +// CHECK: def R4Q2 +// CHECK: def R4Q4 diff --git old/llvm/utils/emacs/tablegen-mode.el new/llvm/utils/emacs/tablegen-mode.el index 3853ce6..26b6639 100644 --- old/llvm/utils/emacs/tablegen-mode.el +++ new/llvm/utils/emacs/tablegen-mode.el @@ -13,7 +13,7 @@ (defvar tablegen-font-lock-keywords (let ((kw (regexp-opt '("class" "defm" "def" "field" "include" "in" - "let" "multiclass") + "let" "multiclass", "foreach") 'words)) (type-kw (regexp-opt '("bit" "bits" "code" "dag" "int" "list" "string") 'words)) diff --git old/llvm/utils/vim/tablegen.vim new/llvm/utils/vim/tablegen.vim index 3043489..a9b0e4e 100644 --- old/llvm/utils/vim/tablegen.vim +++ new/llvm/utils/vim/tablegen.vim @@ -14,7 +14,7 @@ syntax sync minlines=100 syn case match -syn keyword tgKeyword def let in code dag field include defm +syn keyword tgKeyword def let in code dag field include defm foreach syn keyword tgType class int string list bit bits multiclass syn match tgNumber /\<\d\+\>/ -- 1.7.8.4 From dag at cray.com Thu Feb 9 14:36:08 2012 From: dag at cray.com (David A. Greene) Date: Thu, 09 Feb 2012 14:36:08 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Nick Lewycky's message of "Wed, 8 Feb 2012 18:33:54 -0600") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> Message-ID: Nick Lewycky writes: > That seems like a mistake and is not what I would expect to happen with > intrinsics. ?I can understand why compiler developers might want to do > that but some users will be surprised. > > No, it's not the compiler developers. Our programmers expect the > compiler to be capable of comprehending what the builtins mean and > perform constant folding, licm, etc., and will file bugs when we don't > emit optimal code. Ok, so your customers want exactly the opposite of what ours do. :) > > Suppose you emit code like this: create your own functions with > > definitions that use the IR implementations, and mark them > > noinline. At the very end, you inline them with a pass that calls > > InlineFunction() directly. Does this preserve the order, or do you > > still have trouble with the backend doing too much reordering? > > It's not just reordering. ?Instcombine, dagcombine, etc. do a lot of > massaging. > > Sure, but with what I proposed instcombine can't touch them > (technically it *can*, but it won't do anything since each little > intrinsic definition is already locally optimal). But there's no guarantee that codegen will take the generic IR and always emit the same instruction either. I can't predict how the pattern matching will change in the coming years. This also seems like a lot of work that obfuscate the IR and make debugging more cumbersome. > However, DAGCombine might fold them. If this is a problem in practice, > my next idea is to wrap the functions in compiler barriers. Would that > sufficient to prevent the problems you'd have? It would hurt other optimization. > Again, what is the trouble with keeping intrinsics? ?Why rip them out if > people find them useful and necessary? ?If the behavior of the optimizer > changes wrt the intrinsics, we can deal with that when it happens. > > Your argument that the intrinsics are useful is falling flat because > the use-case you've given is not one that would be solved by the > presence of intrinsics. I think "intrinsics" needs a better definition then. When I think of these kinds of intrinsics, I think, "do exactly this instruction." Why not have a generic shufflevector intrinsic and have users use that if they want them massaged? > Just having intrinsics doesn't guarantee that they won't be "massaged" > by the compiler. Also, waiting until you encounter a problem with the > optimizer is only deferring the problem; when you bring up that issue > the response will be "working as intended" and we'll be right back > here. But it will at least buy some time for us to figure out an alternative. I'm very lucky that I caught that commit. I'm sure I missed a bunch of others that already ripped stuff out that we use. > It's entirely possible that the solution to your problem will involve > intrinsics, but we have to work out exactly what. We could try adding > an i1 flag to the intrinsics that indicate whether it should be > treated as volatile. We could add a volatile bit to the > IntrinsicInst/CallInst, maybe. Actually, we probably already need a volatile bit on a call to prevent code motion as I posted about a couple of weeks ago. It's an interesting idea for intrinsics and I'm definitely open to that. > We could add a new bit to some immutable spot (similar to > TargetLibraryInfo) to indicate whether intrinsics are sacred or > not. We could turn it around and say that the compiler may not > optimize intrinsics except in a single pass, much like how only > SimplifyLibCalls was only place allowed to assume that C functions had > the behaviour their names implied (before we had TargetLibraryInfo). > > I'm trying to start with approaches that serve your use-case with the > minimal change to LLVM first. Yep, I appreciate that. I do like the idea of a bit that controls whether intrinsics are massaged or not. Whether it's on each call or a global bit I don't think would matter to us. Of course the former is more flexible. -Dave From dag at cray.com Thu Feb 9 14:39:32 2012 From: dag at cray.com (David A. Greene) Date: Thu, 09 Feb 2012 14:39:32 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F338D70.1040502@free.fr> (Duncan Sands's message of "Thu, 9 Feb 2012 03:10:08 -0600") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> <4F32D43E.6010900@free.fr> <4F338D70.1040502@free.fr> Message-ID: Duncan Sands writes: > Hi Dave, > >>> I didn't try, but turning __builtin_ia32_vpermilpd into an inline asm is >>> presumably rather trivial. >> >> I don't know how hard it would be. The frontend would have to know >> about mnemonics, at least. And it would have to know whether to >> generate AT&T or Intel syntax. > > I'm not sure this is true any more. The LLVM code generators nowadays parse > inline asm and can output it either as object code or in AT&T or Intel syntax. > At least I think they can. If so, the syntax issue has gone away. If that's true it's a little more palatable, so maybe this would work after all. I like Nick's idea of a bit to indicate whether intrinsics should be left alone as well. Is inline asm guaranteed to be left alone? -Dave From dag at cray.com Thu Feb 9 14:41:33 2012 From: dag at cray.com (David A. Greene) Date: Thu, 09 Feb 2012 14:41:33 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: <4F338E27.6030400@free.fr> (Duncan Sands's message of "Thu, 9 Feb 2012 03:13:11 -0600") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F338E27.6030400@free.fr> Message-ID: Duncan Sands writes: > Though even that is likely to only work for a few years before people > start implementing asm level optimizations (which is sure to be done > because it can be done). Ah, you just answered the question I posted. :) We absolutely need some way to tell LLVM, "leave this alone." It goes beyond intrinsics even. A loop pipeliner often wants the code it emits to be leftt alone, though that's a more general and more difficult problem. Let's start with the basics. :) I think Nick's ideas on modifier bits have some promise. -Dave From baldrick at free.fr Thu Feb 9 14:50:14 2012 From: baldrick at free.fr (Duncan Sands) Date: Thu, 09 Feb 2012 21:50:14 +0100 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F32A65E.802@free.fr> <4F32AAF0.6090601@free.fr> <4F32D43E.6010900@free.fr> <4F338D70.1040502@free.fr> Message-ID: <4F343186.9000806@free.fr> Hi Dave, >>>> I didn't try, but turning __builtin_ia32_vpermilpd into an inline asm is >>>> presumably rather trivial. >>> >>> I don't know how hard it would be. The frontend would have to know >>> about mnemonics, at least. And it would have to know whether to >>> generate AT&T or Intel syntax. >> >> I'm not sure this is true any more. The LLVM code generators nowadays parse >> inline asm and can output it either as object code or in AT&T or Intel syntax. >> At least I think they can. If so, the syntax issue has gone away. > > If that's true it's a little more palatable, so maybe this would work > after all. I like Nick's idea of a bit to indicate whether intrinsics > should be left alone as well. > > Is inline asm guaranteed to be left alone? it is left alone currently, but as I pointed out in my historical musings that may change in the future. I wouldn't worry about it if I were you though. Ciao, Duncan. From arcata at gmail.com Thu Feb 9 14:50:16 2012 From: arcata at gmail.com (Joe Groff) Date: Thu, 9 Feb 2012 12:50:16 -0800 Subject: [llvm-commits] Patch to use proper calling convention for i386--win32 _ftol2 runtime function In-Reply-To: References: Message-ID: On Fri, Jan 27, 2012 at 1:48 PM, Joe Groff wrote: > Here's a patch that adds a WIN_FTOL_* family of pseudo-instructions > modelling the unique calling convention used by the Win32 _ftol2 > runtime function. I'm not totally happy with the tests I wrote; even > using -O0, it appears to depend on the behavior of the scheduler > somewhat, so any feedback on how to write a more robust test would be > appreciated, along with any other comments. Thanks Jakob Stoklund > Olesen for walking me through things. Here's a revised version of the patch with additional tests to test the kill and no-kill cases for the new FTOL pseudo-instruction. -Joe -------------- next part -------------- A non-text attachment was scrubbed... Name: llvm-ftol2-4.diff Type: application/octet-stream Size: 15994 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/079d69ab/attachment.obj From chandlerc at google.com Thu Feb 9 14:51:54 2012 From: chandlerc at google.com (Chandler Carruth) Date: Thu, 9 Feb 2012 10:51:54 -1000 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F338E27.6030400@free.fr> Message-ID: I think the primary problem here are the many definitions and understandings of what 'intrinsics' mean. To be clear, I think most of the LLVM developers have been operating under the following assumption: intrinsics are a library-means of expressing operations very useful or common on a particular system which have no in-language formulation. As such, they are just a language extension with defined and specified semantics. The compiler is then free to interpret them, lower them, optimize, and even delete them according to the as-if rules. I think that's fundamentally the *right* model, as there is no alternative. If you want to express operations on SSE vectors, but would like the compiler to have all of its usual freedom, what else can you use besides intrinsics? However... On Thu, Feb 9, 2012 at 10:41 AM, David A. Greene wrote: > We absolutely need some way to tell LLVM, "leave this alone." It goes > beyond intrinsics even. > This is a very reasonable requirement, and I actually think LLVM has exactly the means to deal with it: *volatile* inline asm. This says to the compiler, explicitly and without ambiguity, "leave this alone". It must not be changed, it must be preserved at all costs. I think anything short of volatile inline asm is subject to as-if, and merely a matter of time before the compiler begins optimizing even these sequences. -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/1616c4e5/attachment.html From kai.nacke at redstar.de Thu Feb 9 15:01:49 2012 From: kai.nacke at redstar.de (Kai Nacke) Date: Thu, 09 Feb 2012 22:01:49 +0100 Subject: [llvm-commits] [PATCH] TLS support for Windows 32+64bit In-Reply-To: References: <4F1F1386.8020508@redstar.de> Message-ID: <4F34343D.9000908@redstar.de> Hi Michael! I incorporated all your changes. The attached patch also includes the suggestions from Eli. Please, could someone with knowledge of ISelLowering have a look at this patch? Thank you! Regards Kai On 03.02.2012 02:56, Michael Spencer wrote: > On Tue, Jan 24, 2012 at 12:24 PM, Kai wrote: >> Hello, >> >> the attached patch adds TLS support for x86_64-pc-win32 and x86-pc-win32. >> Implemented is the implicit TLS model (__declspec(thread) in Visual C++). >> This is one of the missing pieces for the Win64 port of >> LDC (the LLVM based D compiler). It should also be useful for implementing >> the Microsoft specific TLS extension in Clang. >> >> Please review and commit if acceptable. Thank you very much! >> >> Regards >> Kai > The patch looks good, however, I am not familiar enough with > ISelLowering to give approval. I've tested it and the behavior matches > what VC++ generates. > > There are some LLVM style issues that I've noted below. > > @@ -231,6 +232,12 @@ EmitImmediate(const MCOperand&DispOp, unsigned > Size, MCFixupKind FixupKind, > if (Kind == GOT_Normal) > ImmOffset = CurByte; > } > + else if (Expr->getKind() == MCExpr::SymbolRef) { > + const MCSymbolRefExpr *Ref = static_cast(Expr); > + if (Ref->getKind() == MCSymbolRefExpr::VK_SECREL) { > + FixupKind = MCFixupKind(FK_SecRel_4); > + } > + } > > There should not be a new line between the } and else if. > > + // If GV is an alias then use the aliasee for determining > + // thread-localness. > + if (const GlobalAlias *GA = dyn_cast(GV)) > + GV = GA->resolveAliasedGlobal(false); > + DebugLoc dl = GA->getDebugLoc(); > + SDValue Chain = DAG.getEntryNode(); > > The indentation drops by one space here to the end of the block. > > + if (Subtarget->is64Bit()) > + IDX = DAG.getExtLoad(ISD::ZEXTLOAD, dl, getPointerTy(), Chain, > + IDX, MachinePointerInfo(), MVT::i32, > + false, false, 0); > + else > + IDX = DAG.getLoad(getPointerTy(), dl, Chain, IDX, MachinePointerInfo(), > + false, false, false, 0); > > These are indented too far. We use two space indentation. > > - assert(Inst.getOperand(0).isReg()&& Inst.getOperand(ImmOp).isImm()&& > + assert(Inst.getOperand(0).isReg()&& > + (Inst.getOperand(ImmOp).isImm() || > + (Inst.getOperand(ImmOp).isExpr()&& > + Inst.getOperand(ImmOp).getExpr()->getKind() == MCExpr::SymbolRef)&& > + static_cast MCSymbolRefExpr*>(Inst.getOperand(ImmOp).getExpr())->getKind() == > MCSymbolRefExpr::VK_SECREL)&& > > This is over 80 columns. It also contains tabs. > > +; RUN: llc< %s -march=x86-64 -mtriple=x86_64-pc-win32> %t3 > +; RUN: grep {movl _tls_index(%rip), %eax} %t3 > +; RUN: grep {movabsq \$i at SECREL, %rcx} %t3 > +; RUN: llc< %s -march=x86 -mtriple=x86-pc-win32> %t4 > +; RUN: grep {movl __tls_index, %eax} %t4 > +; RUN: grep {movl %fs:__tls_array, %ecx} %t4 > +; RUN: grep {movl _i at SECREL(%eax), %eax} %t4 > > You should use FileCheck instead of grep for new tests. > > Thanks for working on this. I'm excited to see more work on Windows codegen :) > > - Michael Spencer > -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: tls-20120209.diff Url: http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/727cfd3b/attachment.pl From hfinkel at anl.gov Thu Feb 9 15:17:43 2012 From: hfinkel at anl.gov (Hal Finkel) Date: Thu, 09 Feb 2012 15:17:43 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F338E27.6030400@free.fr> Message-ID: <1328822263.2502.38.camel@sapling> On Thu, 2012-02-09 at 10:51 -1000, Chandler Carruth wrote: > I think the primary problem here are the many definitions and > understandings of what 'intrinsics' mean. > > > To be clear, I think most of the LLVM developers have been operating > under the following assumption: intrinsics are a library-means of > expressing operations very useful or common on a particular system > which have no in-language formulation. As such, they are just a > language extension with defined and specified semantics. The compiler > is then free to interpret them, lower them, optimize, and even delete > them according to the as-if rules. I think that's fundamentally the > *right* model, as there is no alternative. If you want to express > operations on SSE vectors, but would like the compiler to have all of > its usual freedom, what else can you use besides intrinsics? There is an alternate view which says: intrinsics form an embedded domain-specific language within C/C++ which allows programming assembly while letting the compiler take care of scheduling and register allocation. In order words, it is a method for doing user-specified instruction selection when the compiler's built-in abilities in this area are lacking (while letting the compiler do other things that it is good at doing). In general, I don't know of anyone who minds their intrinsics being constant folded, etc. so long as doing so never hurts performance (and this is important for some use cases like when intrinsics are used as part of C++ expression template libraries for matrix operations). On the other hand, doing things that can perform worse, or using completely different instruction, is another matter. -Hal > > > However... > > On Thu, Feb 9, 2012 at 10:41 AM, David A. Greene wrote: > We absolutely need some way to tell LLVM, "leave this alone." > It goes > beyond intrinsics even. > > > This is a very reasonable requirement, and I actually think LLVM has > exactly the means to deal with it: *volatile* inline asm. This says to > the compiler, explicitly and without ambiguity, "leave this alone". It > must not be changed, it must be preserved at all costs. > > > I think anything short of volatile inline asm is subject to as-if, and > merely a matter of time before the compiler begins optimizing even > these sequences. > _______________________________________________ > llvm-commits mailing list > llvm-commits at cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits -- Hal Finkel Postdoctoral Appointee Leadership Computing Facility Argonne National Laboratory From anton at korobeynikov.info Thu Feb 9 15:44:32 2012 From: anton at korobeynikov.info (Anton Korobeynikov) Date: Fri, 10 Feb 2012 01:44:32 +0400 Subject: [llvm-commits] [PATCH] TLS support for Windows 32+64bit In-Reply-To: <4F34343D.9000908@redstar.de> References: <4F1F1386.8020508@redstar.de> <4F34343D.9000908@redstar.de> Message-ID: > Please, could someone with knowledge of ISelLowering have a look at this > patch? Thank you! ISel part is fine for me. Kai, which linker you're using for LDC? Who provides the _tls_index variable? For me it seems that the patch should be for isTargetWindows() && isTargetMingw() at least, no? -- With best regards, Anton Korobeynikov Faculty of Mathematics and Mechanics, Saint Petersburg State University From dag at cray.com Thu Feb 9 16:02:47 2012 From: dag at cray.com (David A. Greene) Date: Thu, 09 Feb 2012 16:02:47 -0600 Subject: [llvm-commits] [llvm] r150060 - in /llvm/trunk: include/llvm/IntrinsicsX86.td lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86InstrSSE.td In-Reply-To: (Chandler Carruth's message of "Thu, 9 Feb 2012 10:51:54 -1000") References: <20120208063657.D34492A6C12C@llvm.org> <4F322499.2060706@free.fr> <4F322B6B.5080909@free.fr> <8739alpcbf.fsf@smith.obbligato.org> <4F3297AC.6010409@free.fr> <4F329F19.2040709@free.fr> <4F338E27.6030400@free.fr> Message-ID: Chandler Carruth writes: > I think the primary problem here are the many definitions and > understandings of what 'intrinsics' mean. I agree. > To be clear, I think most of the LLVM developers have been operating > under the following assumption: intrinsics are a library-means of > expressing operations very useful or common on a particular system > which have no in-language formulation. As such, they are just a > language extension with defined and specified semantics. I agree here as well. It just happened to be the only way in the past to provide a "leave this alone" guarantee. It's clear now that we need something else. > The compiler is then free to interpret them, lower them, optimize, and > even delete them according to the as-if rules. I think that's > fundamentally the *right* model, as there is no alternative. If you > want to express operations on SSE vectors, but would like the compiler > to have all of its usual freedom, what else can you use besides > intrinsics? I think it's perfectly reasonable to say the compiler should be able to optimize certain kinds of these things. There's another kind of "intrinsic" which is a source-level construct provided by many compilers. I think here the definition is much more muddy. Some users expect optimizations, others expect the compiler to leave them alone. We need some way of expression both desires in the IR so that various implementations can translate them the proper way based on requirements. > However... > > On Thu, Feb 9, 2012 at 10:41 AM, David A. Greene wrote: > > We absolutely need some way to tell LLVM, "leave this alone." ?It goes > beyond intrinsics even. > > This is a very reasonable requirement, and I actually think LLVM has > exactly the means to deal with it: *volatile* inline asm. This says to > the compiler, explicitly and without ambiguity, "leave this alone". It > must not be changed, it must be preserved at all costs. Ok, if "volatile" on inline asm provides this guarantee and if Duncan's guesses as to the ease of using them hold up, this should be fine for us. If "volatile" doesn't currently provide this guarantee, then we'll have to add that semantic to the IR. -Dave From dag at cray.com Thu Feb 9 16:04:37 2012 From: dag at cray.com (David A. Greene) Date: Thu, 09 Feb 2012 16:04:37 -0600 Subject: [llvm-commits] Dedicated commit lists In-Reply-To: (David Blaikie's message of "Wed, 8 Feb 2012 16:17:58 -0800") References: <114101cce6a4$9ecaaf10$dc600d30$@org> <1328741783.2463.129.camel@sapling> Message-ID: David Blaikie writes: >> That would be highly useful. ?It seems pretty complicated, however, and >> reinventing the wheel/NIH. ?How about something like gerrit? > > I believe some people have already been experimenting with a patchwerk > variant for the LLVM lists: https://github.com/asl/llvm-patchwork Someone else noted that. This looks like a great step forward! -Dave From bigcheesegs at gmail.com Thu Feb 9 17:36:36 2012 From: bigcheesegs at gmail.com (Michael Spencer) Date: Thu, 9 Feb 2012 15:36:36 -0800 Subject: [llvm-commits] [llvm] r150197 - in /llvm/trunk: include/llvm/Support/system_error.h lib/Support/DataStream.cpp lib/Support/FileUtilities.cpp lib/Support/MemoryBuffer.cpp lib/Support/PathV2.cpp lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV Message-ID: On Thu, Feb 9, 2012 at 11:24 AM, David Blaikie wrote: > Author: dblaikie > Date: Thu Feb ?9 13:24:12 2012 > New Revision: 150197 > > URL: http://llvm.org/viewvc/llvm-project?rev=150197&view=rev > Log: > Change default error_code ctor to a 'named ctor' so it's more self-documenting. > > Unify default construction of error_code uses on this idiom so that users don't > feel compelled to make static globals for naming convenience. (unfortunately I > couldn't make the original ctor private as some APIs don't return their result, > instead using an out parameter (that makes sense to default construct) - which > is a bit of a pity. I did, however, find/fix some cases of unnecessary default > construction of error_code before I hit the unfixable cases) The out parameters are needed for constructors since we can't use exceptions :P. I like the rest of it. It's sad that the standard doesn't define an automatic conversion between errc::success and error_code(0, generic_category()). - Michael Spencer From bigcheesegs at gmail.com Thu Feb 9 17:40:33 2012 From: bigcheesegs at gmail.com (Michael Spencer) Date: Thu, 9 Feb 2012 15:40:33 -0800 Subject: [llvm-commits] [PATCH] YAML parser. In-Reply-To: References: Message-ID: Attached is the latest patch. Implements most of your comments, and the items discussed on IRC. - Michael Spencer -------------- next part -------------- A non-text attachment was scrubbed... Name: yaml-parser-09-02-2012.patch Type: application/octet-stream Size: 165865 bytes Desc: not available Url : http://lists.cs.uiuc.edu/pipermail/llvm-commits/attachments/20120209/21ef2437/attachment-0001.obj From dblaikie at gmail.com Thu Feb 9 17:45:53 2012 From: dblaikie at gmail.com (David Blaikie) Date: Thu, 9 Feb 2012 15:45:53 -0800 Subject: [llvm-commits] [llvm] r150197 - in /llvm/trunk: include/llvm/Support/system_error.h lib/Support/DataStream.cpp lib/Support/FileUtilities.cpp lib/Support/MemoryBuffer.cpp lib/Support/PathV2.cpp lib/Support/Unix/PathV2.inc lib/Support/Windows/PathV In-Reply-To: References: Message-ID: On Thu, Feb 9, 2012 at 3:36 PM, Michael Spencer wrote: > On Thu, Feb 9, 2012 at 11:24 AM, David Blaikie wrote: >> Author: dblaikie >> Date: Thu Feb ?9 13:24:12 2012 >> New Revision: 150197 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=150197&view=rev >> Log: >> Change default error_code ctor to a 'named ctor' so it's more self-documenting. >> >> Unify default construction of error_code uses on this idiom so that users don't >> feel compelled to make static globals for naming convenience. (unfortunately I >> couldn't make the original ctor private as some APIs don't return their result, >> instead using an out parameter (that makes sense to default construct) - which >> is a bit of a pity. I did, however, find/fix some cases of unnecessary default >> construction of error_code before I hit the unfixable cases) > > The out parameters are needed for constructors since we can't use > exceptions :P. Actually I didn't get far enough to find ctors using this idiom. What I ran into was the error-providing iterator "increment(errorcode&)" API. > I like the rest of it. It's sad that the standard > doesn't define an automatic conversion between errc::success and > error_code(0, generic_category()). Yeah - that is a bit awkward if there's not a nicer way to create a success system_error in the standard API From benny.kra at googlemail.com Thu Feb 9 18:28:31 2012 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Fri, 10 Feb 2012 00:28:31 -0000 Subject: [llvm-commits] [llvm] r150214 - /llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Message-ID: <20120210002831.E770C2A6C12D@llvm.org> Author: d0k Date: Thu Feb 9 18:28:31 2012 New Revision: 150214 URL: http://llvm.org/viewvc/llvm-project?rev=150214&view=rev Log: Cache iterators. Some of these are expensive to create. Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Modified: llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp?rev=150214&r1=150213&r2=150214&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp (original) +++ llvm/trunk/lib/CodeGen/MachineBasicBlock.cpp Thu Feb 9 18:28:31 2012 @@ -141,8 +141,8 @@ } MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() { - instr_iterator I = instr_begin(); - while (I != end() && I->isPHI()) + instr_iterator I = instr_begin(), E = instr_end(); + while (I != E && I->isPHI()) ++I; assert(!I->isInsideBundle() && "First non-phi MI cannot be inside a bundle!"); return I; @@ -150,7 +150,8 @@ MachineBasicBlock::iterator MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) { - while (I != end() && (I->isPHI() || I->isLabel() || I->isDebugValue())) + iterator E = end(); + while (I != E && (I->isPHI() || I->isLabel() || I->isDebugValue())) ++I; // FIXME: This needs to change if we wish to bundle labels / dbg_values // inside the bundle. @@ -160,29 +161,29 @@ } MachineBasicBlock::iterator MachineBasicBlock::getFirstTerminator() { - iterator I = end(); - while (I != begin() && ((--I)->isTerminator() || I->isDebugValue())) + iterator B = begin(), E = end(), I = E; + while (I != B && ((--I)->isTerminator() || I->isDebugValue())) ; /*noop */ - while (I != end() && !I->isTerminator()) + while (I != E && !I->isTerminator()) ++I; return I; } MachineBasicBlock::const_iterator MachineBasicBlock::getFirstTerminator() const { - const_iterator I = end(); - while (I != begin() && ((--I)->isTerminator() || I->isDebugValue())) + const_iterator B = begin(), E = end(), I = E; + while (I != B && ((--I)->isTerminator() || I->isDebugValue())) ; /*noop */ - while (I != end() && !I->isTerminator()) + while (I != E && !I->isTerminator()) ++I; return I; } MachineBasicBlock::instr_iterator MachineBasicBlock::getFirstInstrTerminator() { - instr_iterator I = instr_end(); - while (I != instr_begin() && ((--I)->isTerminator() || I->isDebugValue())) + instr_iterator B = instr_begin(), E = instr_end(), I = E; + while (I != B && ((--I)->isTerminator() || I->isDebugValue())) ; /*noop */ - while (I != instr_end() && !I->isTerminator()) + while (I != E && !I->isTerminator()) ++I; return I; } @@ -726,8 +727,9 @@ MachineInstr *MachineBasicBlock::remove(MachineInstr *I) { if (I->isBundle()) { - MachineBasicBlock::instr_iterator MII = I; ++MII; - while (MII != end() && MII->isInsideBundle()) { + instr_iterator MII = llvm::next(I); + iterator E = end(); + while (MII != E && MII->isInsideBundle()) { MachineInstr *MI = &*MII++; Insts.remove(MI); } From stoklund at 2pi.dk Thu Feb 9 19:23:56 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 10 Feb 2012 01:23:56 -0000 Subject: [llvm-commits] [llvm] r150218 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120210012356.414C52A6C12D@llvm.org> Author: stoklund Date: Thu Feb 9 19:23:55 2012 New Revision: 150218 URL: http://llvm.org/viewvc/llvm-project?rev=150218&view=rev Log: Optimize LiveIntervals::intervalIsInOneMBB(). No looping and binary searches necessary. Return a pointer to the containing block instead of just a bool. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=150218&r1=150217&r2=150218&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Feb 9 19:23:55 2012 @@ -255,9 +255,10 @@ const SmallVectorImpl *SpillIs, bool &isLoad); - /// intervalIsInOneMBB - Returns true if the specified interval is entirely - /// within a single basic block. - bool intervalIsInOneMBB(const LiveInterval &li) const; + /// intervalIsInOneMBB - If LI is confined to a single basic block, return + /// a pointer to that block. If LI is live in to or out of any block, + /// return NULL. + MachineBasicBlock *intervalIsInOneMBB(const LiveInterval &LI) const; /// addKillFlags - Add kill flags to any instruction that kills a virtual /// register. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150218&r1=150217&r2=150218&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Feb 9 19:23:55 2012 @@ -1086,23 +1086,28 @@ return true; } -bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const { - LiveInterval::Ranges::const_iterator itr = li.ranges.begin(); - - MachineBasicBlock *mbb = indexes_->getMBBCoveringRange(itr->start, itr->end); - - if (mbb == 0) - return false; - - for (++itr; itr != li.ranges.end(); ++itr) { - MachineBasicBlock *mbb2 = - indexes_->getMBBCoveringRange(itr->start, itr->end); - - if (mbb2 != mbb) - return false; - } - - return true; +MachineBasicBlock* +LiveIntervals::intervalIsInOneMBB(const LiveInterval &LI) const { + // A local live range must be fully contained inside the block, meaning it is + // defined and killed at instructions, not at block boundaries. It is not + // live in or or out of any block. + // + // It is technically possible to have a PHI-defined live range identical to a + // single block, but we are going to return false in that case. + + SlotIndex Start = LI.beginIndex(); + if (Start.isBlock()) + return NULL; + + SlotIndex Stop = LI.endIndex(); + if (Stop.isBlock()) + return NULL; + + // getMBBFromIndex doesn't need to search the MBB table when both indexes + // belong to proper instructions. + MachineBasicBlock *MBB1 = indexes_->getMBBFromIndex(Start); + MachineBasicBlock *MBB2 = indexes_->getMBBFromIndex(Stop); + return MBB1 == MBB2 ? MBB1 : NULL; } float From stoklund at 2pi.dk Thu Feb 9 19:26:30 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 10 Feb 2012 01:26:30 -0000 Subject: [llvm-commits] [llvm] r150219 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120210012630.201BD2A6C12D@llvm.org> Author: stoklund Date: Thu Feb 9 19:26:29 2012 New Revision: 150219 URL: http://llvm.org/viewvc/llvm-project?rev=150219&view=rev Log: Cache basic block boundaries for faster RegMaskSlots access. Provide API to get a list of register mask slots and bits in a basic block. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=150219&r1=150218&r2=150219&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Feb 9 19:26:29 2012 @@ -82,6 +82,13 @@ /// Also see the comment in LiveInterval::find(). SmallVector RegMaskBits; + /// For each basic block number, keep (begin, size) pairs indexing into the + /// RegMaskSlots and RegMaskBits arrays. + /// Note that basic block numbers may not be layout contiguous, that's why + /// we can't just keep track of the first register mask in each basic + /// block. + SmallVector, 8> RegMaskBlocks; + public: static char ID; // Pass identification, replacement for typeid LiveIntervals() : MachineFunctionPass(ID) { @@ -280,10 +287,29 @@ // LiveIntervalAnalysis maintains a sorted list of instructions with // register mask operands. - /// getRegMaskSlots - Returns asorted array of slot indices of all + /// getRegMaskSlots - Returns a sorted array of slot indices of all /// instructions with register mask operands. ArrayRef getRegMaskSlots() const { return RegMaskSlots; } + /// getRegMaskSlotsInBlock - Returns a sorted array of slot indices of all + /// instructions with register mask operands in the basic block numbered + /// MBBNum. + ArrayRef getRegMaskSlotsInBlock(unsigned MBBNum) const { + std::pair P = RegMaskBlocks[MBBNum]; + return getRegMaskSlots().slice(P.first, P.second); + } + + /// getRegMaskBits() - Returns an array of register mask pointers + /// corresponding to getRegMaskSlots(). + ArrayRef getRegMaskBits() const { return RegMaskBits; } + + /// getRegMaskBitsInBlock - Returns an array of mask pointers corresponding + /// to getRegMaskSlotsInBlock(MBBNum). + ArrayRef getRegMaskBitsInBlock(unsigned MBBNum) const { + std::pair P = RegMaskBlocks[MBBNum]; + return getRegMaskBits().slice(P.first, P.second); + } + /// checkRegMaskInterference - Test if LI is live across any register mask /// instructions, and compute a bit mask of physical registers that are not /// clobbered by any of them. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150219&r1=150218&r2=150219&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Feb 9 19:26:29 2012 @@ -90,6 +90,7 @@ r2iMap_.clear(); RegMaskSlots.clear(); RegMaskBits.clear(); + RegMaskBlocks.clear(); // Release VNInfo memory regions, VNInfo objects don't need to be dtor'd. VNInfoAllocator.Reset(); @@ -533,10 +534,14 @@ << "********** Function: " << ((Value*)mf_->getFunction())->getName() << '\n'); + RegMaskBlocks.resize(mf_->getNumBlockIDs()); + SmallVector UndefUses; for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end(); MBBI != E; ++MBBI) { MachineBasicBlock *MBB = MBBI; + RegMaskBlocks[MBB->getNumber()].first = RegMaskSlots.size(); + if (MBB->empty()) continue; @@ -587,6 +592,10 @@ // Move to the next instr slot. MIIndex = indexes_->getNextNonNullIndex(MIIndex); } + + // Compute the number of register mask instructions in this block. + std::pair &RMB = RegMaskBlocks[MBB->getNumber()]; + RMB.second = RegMaskSlots.size() - RMB.first;; } // Create empty intervals for registers defined by implicit_def's (except From stoklund at 2pi.dk Thu Feb 9 19:31:31 2012 From: stoklund at 2pi.dk (Jakob Stoklund Olesen) Date: Fri, 10 Feb 2012 01:31:31 -0000 Subject: [llvm-commits] [llvm] r150220 - /llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120210013131.AA4492A6C12D@llvm.org> Author: stoklund Date: Thu Feb 9 19:31:31 2012 New Revision: 150220 URL: http://llvm.org/viewvc/llvm-project?rev=150220&view=rev Log: Constrain the regmask search space for local live ranges. When checking a local live range for interference, restrict the binary search to the single block. Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150220&r1=150219&r2=150220&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Feb 9 19:31:31 2012 @@ -1161,11 +1161,21 @@ BitVector &UsableRegs) { if (LI.empty()) return false; + LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); + + // Use a smaller arrays for local live ranges. + ArrayRef Slots; + ArrayRef Bits; + if (MachineBasicBlock *MBB = intervalIsInOneMBB(LI)) { + Slots = getRegMaskSlotsInBlock(MBB->getNumber()); + Bits = getRegMaskBitsInBlock(MBB->getNumber()); + } else { + Slots = getRegMaskSlots(); + Bits = getRegMaskBits(); + } // We are going to enumerate all the register mask slots contained in LI. // Start with a binary search of RegMaskSlots to find a starting point. - LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end(); - ArrayRef Slots = getRegMaskSlots(); ArrayRef::iterator SlotI = std::lower_bound(Slots.begin(), Slots.end(), LiveI->start); ArrayRef::iterator SlotE = Slots.end(); @@ -1187,7 +1197,7 @@ Found = true; } // Remove usable registers clobbered by this mask. - UsableRegs.clearBitsNotInMask(RegMaskBits[SlotI-Slots.begin()]); + UsableRegs.clearBitsNotInMask(Bits[SlotI-Slots.begin()]); if (++SlotI == SlotE) return Found; } From grosbach at apple.com Thu Feb 9 20:21:50 2012 From: grosbach at apple.com (Jim Grosbach) Date: Fri, 10 Feb 2012 02:21:50 -0000 Subject: [llvm-commits] [llvm] r150222 - /llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp Message-ID: <20120210022150.289602A6C12D@llvm.org> Author: grosbach Date: Thu Feb 9 20:21:49 2012 New Revision: 150222 URL: http://llvm.org/viewvc/llvm-project?rev=150222&view=rev Log: ARM on darwin, v6 implies the presence of VFP for the assembler. rdar://10838899 Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp?rev=150222&r1=150221&r2=150222&view=diff ============================================================================== --- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp (original) +++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp Thu Feb 9 20:21:49 2012 @@ -66,13 +66,21 @@ // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk"; } else if (SubVer == '6') { - if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') + Triple TheTriple(TT); + if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2') { ARMArchFeature = "+v6t2"; - else if (Len >= Idx+2 && TT[Idx+1] == 'm') + // On darwin, v6 implies VFP. + if (TheTriple.isOSDarwin()) + ARMArchFeature += ",+vfp2"; + } else if (Len >= Idx+2 && TT[Idx+1] == 'm') // v6m: FeatureNoARM, FeatureMClass ARMArchFeature = "+v6t2,+noarm,+mclass"; - else + else { ARMArchFeature = "+v6"; + // On darwin, v6 implies VFP. + if (TheTriple.isOSDarwin()) + ARMArchFeature += ",+vfp2"; + } } else if (SubVer == '5') { if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == 'e') ARMArchFeature = "+v5te"; From lhames at gmail.com Thu Feb 9 21:19:36 2012 From: lhames at gmail.com (Lang Hames) Date: Fri, 10 Feb 2012 03:19:36 -0000 Subject: [llvm-commits] [llvm] r150224 - in /llvm/trunk: include/llvm/CodeGen/LiveIntervalAnalysis.h lib/CodeGen/LiveIntervalAnalysis.cpp Message-ID: <20120210031936.D1F1B2A6C12D@llvm.org> Author: lhames Date: Thu Feb 9 21:19:36 2012 New Revision: 150224 URL: http://llvm.org/viewvc/llvm-project?rev=150224&view=rev Log: Remove unused 'isAlias' parameter. Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Modified: llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h?rev=150224&r1=150223&r2=150224&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h (original) +++ llvm/trunk/include/llvm/CodeGen/LiveIntervalAnalysis.h Thu Feb 9 21:19:36 2012 @@ -355,7 +355,7 @@ /// handleLiveInRegister - Create interval for a livein register. void handleLiveInRegister(MachineBasicBlock* mbb, SlotIndex MIIdx, - LiveInterval &interval, bool isAlias = false); + LiveInterval &interval); /// getReMatImplicitUse - If the remat definition MI has one (for now, we /// only allow one) virtual register operand, then its uses are implicitly Modified: llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp?rev=150224&r1=150223&r2=150224&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp (original) +++ llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp Thu Feb 9 21:19:36 2012 @@ -455,7 +455,7 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, SlotIndex MIIdx, - LiveInterval &interval, bool isAlias) { + LiveInterval &interval) { DEBUG(dbgs() << "\t\tlivein register: " << PrintReg(interval.reg, tri_)); // Look for kills, if it reaches a def before it's killed, then it shouldn't @@ -505,13 +505,8 @@ // Live-in register might not be used at all. if (!SeenDefUse) { - if (isAlias) { - DEBUG(dbgs() << " dead"); - end = MIIdx.getDeadSlot(); - } else { - DEBUG(dbgs() << " live through"); - end = getMBBEndIdx(MBB); - } + DEBUG(dbgs() << " live through"); + end = getMBBEndIdx(MBB); } SlotIndex defIdx = getMBBStartIdx(MBB); From atrick at apple.com Thu Feb 9 22:10:26 2012 From: atrick at apple.com (Andrew Trick) Date: Fri, 10 Feb 2012 04:10:26 -0000 Subject: [llvm-commits] [llvm] r150225 - /llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Message-ID: <20120210041026.68B4E2A6C12D@llvm.org> Author: atrick Date: Thu Feb 9 22:10:26 2012 New Revision: 150225 URL: http://llvm.org/viewvc/llvm-project?rev=150225&view=rev Log: whitespace Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Modified: llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp?rev=150225&r1=150224&r2=150225&view=diff ============================================================================== --- llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp (original) +++ llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp Thu Feb 9 22:10:26 2012 @@ -163,7 +163,7 @@ VReg2Node::const_iterator nodeItr = vreg2Node.find(vreg); assert(nodeItr != vreg2Node.end() && "No node for vreg."); return nodeItr->second; - + } const PBQPRAProblem::AllowedSet& @@ -190,7 +190,7 @@ typedef std::vector LIVector; MachineRegisterInfo *mri = &mf->getRegInfo(); - const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo(); + const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo(); std::auto_ptr p(new PBQPRAProblem()); PBQP::Graph &g = p->getGraph(); @@ -207,7 +207,7 @@ BitVector reservedRegs = tri->getReservedRegs(*mf); - // Iterate over vregs. + // Iterate over vregs. for (RegSet::const_iterator vregItr = vregs.begin(), vregEnd = vregs.end(); vregItr != vregEnd; ++vregItr) { unsigned vreg = *vregItr; @@ -263,7 +263,7 @@ } // Construct the node. - PBQP::Graph::NodeItr node = + PBQP::Graph::NodeItr node = g.addNode(PBQP::Vector(vrAllowed.size() + 1, 0)); // Record the mapping and allowed set in the problem. @@ -364,7 +364,7 @@ const float copyFactor = 0.5; // Cost of copy relative to load. Current // value plucked randomly out of the air. - + PBQP::PBQPNum cBenefit = copyFactor * LiveIntervals::getSpillWeight(false, true, loopInfo->getLoopDepth(mbb)); @@ -375,7 +375,7 @@ } const PBQPRAProblem::AllowedSet &allowed = p->getAllowedSet(src); - unsigned pregOpt = 0; + unsigned pregOpt = 0; while (pregOpt < allowed.size() && allowed[pregOpt] != dst) { ++pregOpt; } @@ -400,7 +400,7 @@ std::swap(allowed1, allowed2); } } - + addVirtRegCoalesce(g.getEdgeCosts(edge), *allowed1, *allowed2, cBenefit); } @@ -432,7 +432,7 @@ if (preg1 == preg2) { costMat[i + 1][j + 1] += -benefit; - } + } } } } @@ -502,10 +502,10 @@ unsigned alloc = solution.getSelection(node); if (problem.isPRegOption(vreg, alloc)) { - unsigned preg = problem.getPRegForOption(vreg, alloc); + unsigned preg = problem.getPRegForOption(vreg, alloc); DEBUG(dbgs() << "VREG " << vreg << " -> " << tri->getName(preg) << "\n"); assert(preg != 0 && "Invalid preg selected."); - vrm->assignVirt2Phys(vreg, preg); + vrm->assignVirt2Phys(vreg, preg); } else if (problem.isSpillOption(vreg, alloc)) { vregsToAlloc.erase(vreg); SmallVector newSpills; @@ -609,7 +609,7 @@ tm = &mf->getTarget(); tri = tm->getRegisterInfo(); tii = tm->getInstrInfo(); - mri = &mf->getRegInfo(); + mri = &mf->getRegInfo(); lis = &getAnalysis(); lss = &getAnalysis(); From atrick at apple.com Thu Feb 9 22:10:37 2012 From: atrick at apple.com (Andrew Trick) Date: Fri, 10 Feb 2012 04:10:37 -0000 Subject: [llvm-commits] [llvm] r150226 - in /llvm/trunk: include/llvm/CodeGen/ include/llvm/Target/ lib/CodeGen/ lib/Target/ lib/Target/PTX/ test/CodeGen/ARM/ test/CodeGen/X86/ tools/llc/ Message-ID: <20120210041037.A53652A6C12D@llvm.org> Author: atrick Date: Thu Feb 9 22:10:36 2012 New Revision: 150226 URL: http://llvm.org/viewvc/llvm-project?rev=150226&view=rev Log: RegAlloc superpass: includes phi elimination, coalescing, and scheduling. Creates a configurable regalloc pipeline. Ensure specific llc options do what they say and nothing more: -reglloc=... has no effect other than selecting the allocator pass itself. This patch introduces a new umbrella flag, "-optimize-regalloc", to enable/disable the optimizing regalloc "superpass". This allows for example testing coalscing and scheduling under -O0 or vice-versa. When a CodeGen pass requires the MachineFunction to have a particular property, we need to explicitly define that property so it can be directly queried rather than naming a specific Pass. For example, to check for SSA, use MRI->isSSA, not addRequired. CodeGen transformation passes are never "required" as an analysis ProcessImplicitDefs does not require LiveVariables. We have a plan to massively simplify some of the early passes within the regalloc superpass. Modified: llvm/trunk/include/llvm/CodeGen/Passes.h llvm/trunk/include/llvm/Target/TargetOptions.h llvm/trunk/lib/CodeGen/LiveIntervalAnalysis.cpp llvm/trunk/lib/CodeGen/LiveVariables.cpp llvm/trunk/lib/CodeGen/MachineScheduler.cpp llvm/trunk/lib/CodeGen/PHIElimination.cpp llvm/trunk/lib/CodeGen/Passes.cpp llvm/trunk/lib/CodeGen/ProcessImplicitDefs.cpp llvm/trunk/lib/CodeGen/RegAllocBasic.cpp llvm/trunk/lib/CodeGen/RegAllocFast.cpp llvm/trunk/lib/CodeGen/RegAllocGreedy.cpp llvm/trunk/lib/CodeGen/RegAllocPBQP.cpp llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp llvm/trunk/lib/CodeGen/TwoAddressInstructionPass.cpp llvm/trunk/lib/Target/PTX/PTXRegAlloc.cpp llvm/trunk/lib/Target/PTX/PTXTargetMachine.cpp llvm/trunk/lib/Target/TargetMachine.cpp llvm/trunk/test/CodeGen/ARM/2010-05-20-NEONSpillCrash.ll llvm/trunk/test/CodeGen/ARM/fast-isel-redefinition.ll llvm/trunk/test/CodeGen/X86/2008-05-21-CoalescerBug.ll llvm/trunk/test/CodeGen/X86/fast-isel-bc.ll llvm/trunk/test/CodeGen/X86/inline-asm-tied.ll llvm/trunk/test/CodeGen/X86/object-size.ll llvm/trunk/tools/llc/llc.cpp Modified: llvm/trunk/include/llvm/CodeGen/Passes.h URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=150226&r1=150225&r2=150226&view=diff ============================================================================== --- llvm/trunk/include/llvm/CodeGen/Passes.h (original) +++ llvm/trunk/include/llvm/CodeGen/Passes.h Thu Feb 9 22:10:36 2012 @@ -76,6 +76,8 @@ bool getEnableTailMerge() const { return EnableTailMerge; } void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } + bool getOptimizeRegAlloc() const; + /// Add common target configurable passes that perform LLVM IR to IR /// transforms following machine independent optimization. virtual void addIRPasses(); @@ -122,8 +124,17 @@ return false; } - // addRegAlloc - Add standard passes related to register allocation. - virtual void addRegAlloc(); + /// createTargetRegisterAllocator - Create the register allocator pass for + /// this target at the current optimization level. + virtual FunctionPass *createTargetRegisterAllocator(bool Optimized); + + /// addFastRegAlloc - Add the minimum set of target-independent passes that + /// are required for fast register allocation. + virtual void addFastRegAlloc(FunctionPass *RegAllocPass); + + // addOptimizedRegAlloc - Add passes related to regis