aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/llvm/Analysis/BlockFrequency.h53
-rw-r--r--include/llvm/Analysis/BlockFrequencyImpl.h345
-rw-r--r--include/llvm/Analysis/DIBuilder.h3
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h8
-rw-r--r--include/llvm/Analysis/ValueTracking.h4
-rw-r--r--include/llvm/BasicBlock.h6
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h6
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h2
-rw-r--r--include/llvm/CodeGen/MachineFunction.h2
-rw-r--r--include/llvm/CodeGen/MachineInstr.h32
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h31
-rw-r--r--include/llvm/CodeGen/MachineOperand.h16
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h12
-rw-r--r--include/llvm/CodeGen/Passes.h11
-rw-r--r--include/llvm/CodeGen/RegisterCoalescer.h244
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h10
-rw-r--r--include/llvm/CodeGen/ScoreboardHazardRecognizer.h1
-rw-r--r--include/llvm/Constants.h6
-rw-r--r--include/llvm/InitializePasses.h5
-rw-r--r--include/llvm/InlineAsm.h26
-rw-r--r--include/llvm/MC/MCInstrDesc.h (renamed from include/llvm/Target/TargetInstrDesc.h)135
-rw-r--r--include/llvm/MC/MCInstrInfo.h51
-rw-r--r--include/llvm/MC/MCInstrItineraries.h (renamed from include/llvm/Target/TargetInstrItineraries.h)6
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h192
-rw-r--r--include/llvm/MC/MCRegisterInfo.h129
-rw-r--r--include/llvm/MC/SubtargetFeature.h (renamed from include/llvm/Target/SubtargetFeature.h)42
-rw-r--r--include/llvm/Object/Binary.h67
-rw-r--r--include/llvm/Object/COFF.h115
-rw-r--r--include/llvm/Object/Error.h50
-rw-r--r--include/llvm/Object/ObjectFile.h154
-rw-r--r--include/llvm/Support/BranchProbability.h10
-rw-r--r--include/llvm/Support/IRBuilder.h35
-rw-r--r--include/llvm/Target/Target.td39
-rw-r--r--include/llvm/Target/TargetAsmInfo.h4
-rw-r--r--include/llvm/Target/TargetInstrInfo.h44
-rw-r--r--include/llvm/Target/TargetLowering.h7
-rw-r--r--include/llvm/Target/TargetMachine.h22
-rw-r--r--include/llvm/Target/TargetOptions.h4
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h126
-rw-r--r--include/llvm/Target/TargetRegistry.h134
40 files changed, 1539 insertions, 650 deletions
diff --git a/include/llvm/Analysis/BlockFrequency.h b/include/llvm/Analysis/BlockFrequency.h
new file mode 100644
index 0000000..c4b1e08
--- /dev/null
+++ b/include/llvm/Analysis/BlockFrequency.h
@@ -0,0 +1,53 @@
+//========-------- BlockFrequency.h - Block Frequency Analysis -------========//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Loops should be simplified before this analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BLOCKFREQUENCY_H
+#define LLVM_ANALYSIS_BLOCKFREQUENCY_H
+
+#include "llvm/Pass.h"
+#include <climits>
+
+namespace llvm {
+
+class BranchProbabilityInfo;
+template<class BlockT, class FunctionT, class BranchProbInfoT>
+class BlockFrequencyImpl;
+
+/// BlockFrequency pass uses BlockFrequencyImpl implementation to estimate
+/// IR basic block frequencies.
+class BlockFrequency : public FunctionPass {
+
+ BlockFrequencyImpl<BasicBlock, Function, BranchProbabilityInfo> *BFI;
+
+public:
+ static char ID;
+
+ BlockFrequency();
+
+ ~BlockFrequency();
+
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ bool runOnFunction(Function &F);
+
+ /// getblockFreq - Return block frequency. Never return 0, value must be
+ /// positive. Please note that initial frequency is equal to 1024. It means
+ /// that we should not rely on the value itself, but only on the comparison to
+ /// the other block frequencies. We do this to avoid using of the floating
+ /// points.
+ uint32_t getBlockFreq(BasicBlock *BB);
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/BlockFrequencyImpl.h b/include/llvm/Analysis/BlockFrequencyImpl.h
new file mode 100644
index 0000000..cef375f
--- /dev/null
+++ b/include/llvm/Analysis/BlockFrequencyImpl.h
@@ -0,0 +1,345 @@
+//===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Shared implementation of BlockFrequency for IR and Machine Instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
+#define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Support/BranchProbability.h"
+#include "llvm/Support/Debug.h"
+#include <vector>
+#include <sstream>
+#include <string>
+
+namespace llvm {
+
+
+class BlockFrequency;
+/// BlockFrequencyImpl implements block frequency algorithm for IR and
+/// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
+/// for the entry block and then propagates frequencies using branch weights
+/// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
+/// algorithm can find "backedges" by itself.
+template<class BlockT, class FunctionT, class BlockProbInfoT>
+class BlockFrequencyImpl {
+
+ DenseMap<BlockT *, uint32_t> Freqs;
+
+ BlockProbInfoT *BPI;
+
+ FunctionT *Fn;
+
+ typedef GraphTraits< Inverse<BlockT *> > GT;
+
+ static const uint32_t START_FREQ = 1024;
+
+ std::string getBlockName(BasicBlock *BB) const {
+ return BB->getNameStr();
+ }
+
+ std::string getBlockName(MachineBasicBlock *MBB) const {
+ std::stringstream ss;
+ ss << "BB#" << MBB->getNumber();
+ const BasicBlock *BB = MBB->getBasicBlock();
+
+ if (BB)
+ ss << " derived from LLVM BB " << BB->getNameStr();
+
+ return ss.str();
+ }
+
+ void setBlockFreq(BlockT *BB, uint32_t Freq) {
+ Freqs[BB] = Freq;
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
+ }
+
+ /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
+ /// edge probability.
+ uint32_t getEdgeFreq(BlockT *Src, BlockT *Dst) const {
+ BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
+ uint64_t N = Prob.getNumerator();
+ uint64_t D = Prob.getDenominator();
+ uint64_t Res = (N * getBlockFreq(Src)) / D;
+
+ assert(Res <= UINT32_MAX);
+ return (uint32_t) Res;
+ }
+
+ /// incBlockFreq - Increase BB block frequency by FREQ.
+ ///
+ void incBlockFreq(BlockT *BB, uint32_t Freq) {
+ Freqs[BB] += Freq;
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
+ << " --> " << Freqs[BB] << "\n");
+ }
+
+ /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
+ ///
+ void divBlockFreq(BlockT *BB, BranchProbability Prob) {
+ uint64_t N = Prob.getNumerator();
+ assert(N && "Illegal division by zero!");
+ uint64_t D = Prob.getDenominator();
+ uint64_t Freq = (Freqs[BB] * D) / N;
+
+ // Should we assert it?
+ if (Freq > UINT32_MAX)
+ Freq = UINT32_MAX;
+
+ Freqs[BB] = (uint32_t) Freq;
+ DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
+ << ") --> " << Freqs[BB] << "\n");
+ }
+
+ // All blocks in postorder.
+ std::vector<BlockT *> POT;
+
+ // Map Block -> Position in reverse-postorder list.
+ DenseMap<BlockT *, unsigned> RPO;
+
+ // Cycle Probability for each bloch.
+ DenseMap<BlockT *, uint32_t> CycleProb;
+
+ // (reverse-)postorder traversal iterators.
+ typedef typename std::vector<BlockT *>::iterator pot_iterator;
+ typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
+
+ pot_iterator pot_begin() { return POT.begin(); }
+ pot_iterator pot_end() { return POT.end(); }
+
+ rpot_iterator rpot_begin() { return POT.rbegin(); }
+ rpot_iterator rpot_end() { return POT.rend(); }
+
+ rpot_iterator rpot_at(BlockT *BB) {
+ rpot_iterator I = rpot_begin();
+ unsigned idx = RPO[BB];
+ assert(idx);
+ std::advance(I, idx - 1);
+
+ assert(*I == BB);
+ return I;
+ }
+
+
+ /// Return a probability of getting to the DST block through SRC->DST edge.
+ ///
+ BranchProbability getBackEdgeProbability(BlockT *Src, BlockT *Dst) const {
+ uint32_t N = getEdgeFreq(Src, Dst);
+ uint32_t D = getBlockFreq(Dst);
+
+ return BranchProbability(N, D);
+ }
+
+ /// isReachable - Returns if BB block is reachable from the entry.
+ ///
+ bool isReachable(BlockT *BB) {
+ return RPO.count(BB);
+ }
+
+ /// isBackedge - Return if edge Src -> Dst is a backedge.
+ ///
+ bool isBackedge(BlockT *Src, BlockT *Dst) {
+ assert(isReachable(Src));
+ assert(isReachable(Dst));
+
+ unsigned a = RPO[Src];
+ unsigned b = RPO[Dst];
+
+ return a > b;
+ }
+
+ /// getSingleBlockPred - return single BB block predecessor or NULL if
+ /// BB has none or more predecessors.
+ BlockT *getSingleBlockPred(BlockT *BB) {
+ typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+
+ if (PI == PE)
+ return 0;
+
+ BlockT *Pred = *PI;
+
+ ++PI;
+ if (PI != PE)
+ return 0;
+
+ return Pred;
+ }
+
+ void doBlock(BlockT *BB, BlockT *LoopHead,
+ SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
+
+ DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
+ setBlockFreq(BB, 0);
+
+ if (BB == LoopHead) {
+ setBlockFreq(BB, START_FREQ);
+ return;
+ }
+
+ if(BlockT *Pred = getSingleBlockPred(BB)) {
+ if (BlocksInLoop.count(Pred))
+ setBlockFreq(BB, getEdgeFreq(Pred, BB));
+ // TODO: else? irreducible, ignore it for now.
+ return;
+ }
+
+ bool isInLoop = false;
+ bool isLoopHead = false;
+
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+ PI != PE; ++PI) {
+ BlockT *Pred = *PI;
+
+ if (isReachable(Pred) && isBackedge(Pred, BB)) {
+ isLoopHead = true;
+ } else if (BlocksInLoop.count(Pred)) {
+ incBlockFreq(BB, getEdgeFreq(Pred, BB));
+ isInLoop = true;
+ }
+ // TODO: else? irreducible.
+ }
+
+ if (!isInLoop)
+ return;
+
+ if (!isLoopHead)
+ return;
+
+ assert(START_FREQ >= CycleProb[BB]);
+ uint32_t CProb = CycleProb[BB];
+ uint32_t Numerator = START_FREQ - CProb ? START_FREQ - CProb : 1;
+ divBlockFreq(BB, BranchProbability(Numerator, START_FREQ));
+ }
+
+ /// doLoop - Propagate block frequency down throught the loop.
+ void doLoop(BlockT *Head, BlockT *Tail) {
+ DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
+ << getBlockName(Tail) << ")\n");
+
+ SmallPtrSet<BlockT *, 8> BlocksInLoop;
+
+ for (rpot_iterator I = rpot_at(Head), E = rpot_end(); I != E; ++I) {
+ BlockT *BB = *I;
+ doBlock(BB, Head, BlocksInLoop);
+
+ BlocksInLoop.insert(BB);
+ }
+
+ // Compute loop's cyclic probability using backedges probabilities.
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
+ PI != PE; ++PI) {
+ BlockT *Pred = *PI;
+ assert(Pred);
+ if (isReachable(Pred) && isBackedge(Pred, Head)) {
+ BranchProbability Prob = getBackEdgeProbability(Pred, Head);
+ uint64_t N = Prob.getNumerator();
+ uint64_t D = Prob.getDenominator();
+ uint64_t Res = (N * START_FREQ) / D;
+
+ assert(Res <= UINT32_MAX);
+ CycleProb[Head] += (uint32_t) Res;
+ }
+ }
+ }
+
+ friend class BlockFrequency;
+
+ void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
+ Fn = fn;
+ BPI = bpi;
+
+ // Clear everything.
+ RPO.clear();
+ POT.clear();
+ CycleProb.clear();
+ Freqs.clear();
+
+ BlockT *EntryBlock = fn->begin();
+
+ copy(po_begin(EntryBlock), po_end(EntryBlock), back_inserter(POT));
+
+ unsigned RPOidx = 0;
+ for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
+ BlockT *BB = *I;
+ RPO[BB] = ++RPOidx;
+ DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
+ }
+
+ // Travel over all blocks in postorder.
+ for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
+ BlockT *BB = *I;
+ BlockT *LastTail = 0;
+ DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
+
+ for (typename GT::ChildIteratorType
+ PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
+ PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
+ PI != PE; ++PI) {
+
+ BlockT *Pred = *PI;
+ if (isReachable(Pred) && isBackedge(Pred, BB)
+ && (!LastTail || RPO[Pred] > RPO[LastTail]))
+ LastTail = Pred;
+ }
+
+ if (LastTail)
+ doLoop(BB, LastTail);
+ }
+
+ // At the end assume the whole function as a loop, and travel over it once
+ // again.
+ doLoop(*(rpot_begin()), *(pot_begin()));
+ }
+
+public:
+ /// getBlockFreq - Return block frequency. Never return 0, value must be
+ /// positive.
+ uint32_t getBlockFreq(BlockT *BB) const {
+ typename DenseMap<BlockT *, uint32_t>::const_iterator I = Freqs.find(BB);
+ if (I != Freqs.end())
+ return I->second ? I->second : 1;
+ return 1;
+ }
+
+ void print(raw_ostream &OS) const {
+ OS << "\n\n---- Block Freqs ----\n";
+ for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
+ BlockT *BB = I++;
+ OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
+
+ for (typename GraphTraits<BlockT *>::ChildIteratorType
+ SI = GraphTraits<BlockT *>::child_begin(BB),
+ SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
+ BlockT *Succ = *SI;
+ OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ)
+ << " = " << getEdgeFreq(BB, Succ) << "\n";
+ }
+ }
+ }
+
+ void dump() const {
+ print(dbgs());
+ }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Analysis/DIBuilder.h b/include/llvm/Analysis/DIBuilder.h
index 96c6587..a706cc8 100644
--- a/include/llvm/Analysis/DIBuilder.h
+++ b/include/llvm/Analysis/DIBuilder.h
@@ -135,6 +135,7 @@ namespace llvm {
unsigned Flags);
/// createMemberType - Create debugging information entry for a member.
+ /// @param Scope Member scope.
/// @param Name Member name.
/// @param File File where this member is defined.
/// @param LineNo Line number.
@@ -143,7 +144,7 @@ namespace llvm {
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
- DIType createMemberType(StringRef Name, DIFile File,
+ DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
unsigned LineNo, uint64_t SizeInBits,
uint64_t AlignInBits, uint64_t OffsetInBits,
unsigned Flags, DIType Ty);
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index 39d378e..647a7dc 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -30,6 +30,10 @@ namespace llvm {
/// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
+
+ // New instructions receive a name to identifies them with the current pass.
+ const char* IVName;
+
std::map<std::pair<const SCEV *, Instruction *>, AssertingVH<Value> >
InsertedExpressions;
std::set<AssertingVH<Value> > InsertedValues;
@@ -67,8 +71,8 @@ namespace llvm {
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
- explicit SCEVExpander(ScalarEvolution &se)
- : SE(se), IVIncInsertLoop(0), CanonicalMode(true),
+ explicit SCEVExpander(ScalarEvolution &se, const char *name)
+ : SE(se), IVName(name), IVIncInsertLoop(0), CanonicalMode(true),
Builder(se.getContext(), TargetFolder(se.TD)) {}
/// clear - Erase the contents of the InsertedExpressions map so that users
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index 6df1693..d4354bb 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -158,6 +158,10 @@ namespace llvm {
return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
}
+ /// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
+ /// are lifetime markers.
+ bool onlyUsedByLifetimeMarkers(const Value *V);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h
index b02c249..3b953c0 100644
--- a/include/llvm/BasicBlock.h
+++ b/include/llvm/BasicBlock.h
@@ -138,6 +138,12 @@ public:
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
}
+ // Same as above, but also skip lifetime intrinsics.
+ Instruction* getFirstNonPHIOrDbgOrLifetime();
+ const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
+ return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
+ }
+
/// removeFromParent - This method unlinks 'this' from the containing
/// function, but does not delete it.
///
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index 779ef5f..0ca3ad1 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -375,10 +375,12 @@ public:
// Check that the block wasn't partially defined, and that the offset isn't
// bogus.
- if (AtEndOfStream() || NextChar+NumWords*4 > BitStream->getLastChar())
+ const unsigned char *const SkipTo = NextChar + NumWords*4;
+ if (AtEndOfStream() || SkipTo > BitStream->getLastChar() ||
+ SkipTo < BitStream->getFirstChar())
return true;
- NextChar += NumWords*4;
+ NextChar = SkipTo;
return false;
}
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
index c931261..098dd0b 100644
--- a/include/llvm/CodeGen/LinkAllCodegenComponents.h
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -39,8 +39,6 @@ namespace {
(void) llvm::createGreedyRegisterAllocator();
(void) llvm::createDefaultPBQPRegisterAllocator();
- (void) llvm::createSimpleRegisterCoalescer();
-
llvm::linkOcamlGC();
llvm::linkShadowStackGC();
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index f56c053..6e08f7b 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -345,7 +345,7 @@ public:
/// CreateMachineInstr - Allocate a new MachineInstr. Use this instead
/// of `new MachineInstr'.
///
- MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID,
+ MachineInstr *CreateMachineInstr(const MCInstrDesc &MCID,
DebugLoc DL,
bool NoImp = false);
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index c36dd69..788d149 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -17,7 +17,7 @@
#define LLVM_CODEGEN_MACHINEINSTR_H
#include "llvm/CodeGen/MachineOperand.h"
-#include "llvm/Target/TargetInstrDesc.h"
+#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Target/TargetOpcodes.h"
#include "llvm/ADT/ilist.h"
#include "llvm/ADT/ilist_node.h"
@@ -30,7 +30,6 @@ namespace llvm {
template <typename T> class SmallVectorImpl;
class AliasAnalysis;
-class TargetInstrDesc;
class TargetInstrInfo;
class TargetRegisterInfo;
class MachineFunction;
@@ -57,7 +56,7 @@ public:
// function frame setup code.
};
private:
- const TargetInstrDesc *TID; // Instruction descriptor.
+ const MCInstrDesc *MCID; // Instruction descriptor.
uint16_t NumImplicitOps; // Number of implicit operands (which
// are determined at construction time).
@@ -94,7 +93,7 @@ private:
MachineInstr(MachineFunction &, const MachineInstr &);
/// MachineInstr ctor - This constructor creates a dummy MachineInstr with
- /// TID NULL and no operands.
+ /// MCID NULL and no operands.
MachineInstr();
// The next two constructors have DebugLoc and non-DebugLoc versions;
@@ -103,25 +102,25 @@ private:
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
/// implicit operands. It reserves space for the number of operands specified
- /// by the TargetInstrDesc. The version with a DebugLoc should be preferred.
- explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false);
+ /// by the MCInstrDesc. The version with a DebugLoc should be preferred.
+ explicit MachineInstr(const MCInstrDesc &MCID, bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
/// block. The version with a DebugLoc should be preferred.
- MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID);
+ MachineInstr(MachineBasicBlock *MBB, const MCInstrDesc &MCID);
/// MachineInstr ctor - This constructor create a MachineInstr and add the
/// implicit operands. It reserves space for number of operands specified by
- /// TargetInstrDesc. An explicit DebugLoc is supplied.
- explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl,
+ /// MCInstrDesc. An explicit DebugLoc is supplied.
+ explicit MachineInstr(const MCInstrDesc &MCID, const DebugLoc dl,
bool NoImp = false);
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
/// the MachineInstr is created and added to the end of the specified basic
/// block.
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
- const TargetInstrDesc &TID);
+ const MCInstrDesc &MCID);
~MachineInstr();
@@ -183,11 +182,11 @@ public:
/// getDesc - Returns the target instruction descriptor of this
/// MachineInstr.
- const TargetInstrDesc &getDesc() const { return *TID; }
+ const MCInstrDesc &getDesc() const { return *MCID; }
/// getOpcode - Returns the opcode of this MachineInstr.
///
- int getOpcode() const { return TID->Opcode; }
+ int getOpcode() const { return MCID->Opcode; }
/// Access to explicit operands of the instruction.
///
@@ -279,6 +278,9 @@ public:
bool isCopy() const {
return getOpcode() == TargetOpcode::COPY;
}
+ bool isFullCopy() const {
+ return isCopy() && !getOperand(0).getSubReg() && !getOperand(1).getSubReg();
+ }
/// isCopyLike - Return true if the instruction behaves like a copy.
/// This does not include native copy instructions.
@@ -464,8 +466,8 @@ public:
/// hasUnmodeledSideEffects - Return true if this instruction has side
/// effects that are not modeled by mayLoad / mayStore, etc.
- /// For all instructions, the property is encoded in TargetInstrDesc::Flags
- /// (see TargetInstrDesc::hasUnmodeledSideEffects(). The only exception is
+ /// For all instructions, the property is encoded in MCInstrDesc::Flags
+ /// (see MCInstrDesc::hasUnmodeledSideEffects(). The only exception is
/// INLINEASM instruction, in which case the side effect property is encoded
/// in one of its operands (see InlineAsm::Extra_HasSideEffect).
///
@@ -497,7 +499,7 @@ public:
/// setDesc - Replace the instruction descriptor (thus opcode) of
/// the current instruction with a new one.
///
- void setDesc(const TargetInstrDesc &tid) { TID = &tid; }
+ void setDesc(const MCInstrDesc &tid) { MCID = &tid; }
/// setDebugLoc - Replace current source information with new such.
/// Avoid using this, the constructor argument is preferable.
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index c8183a3..b989027 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -22,7 +22,7 @@
namespace llvm {
-class TargetInstrDesc;
+class MCInstrDesc;
class MDNode;
namespace RegState {
@@ -77,6 +77,11 @@ public:
return *this;
}
+ const MachineInstrBuilder &addCImm(const ConstantInt *Val) const {
+ MI->addOperand(MachineOperand::CreateCImm(Val));
+ return *this;
+ }
+
const MachineInstrBuilder &addFPImm(const ConstantFP *Val) const {
MI->addOperand(MachineOperand::CreateFPImm(Val));
return *this;
@@ -175,8 +180,8 @@ public:
///
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL,
- const TargetInstrDesc &TID) {
- return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL));
+ const MCInstrDesc &MCID) {
+ return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL));
}
/// BuildMI - This version of the builder sets up the first operand as a
@@ -184,9 +189,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
///
inline MachineInstrBuilder BuildMI(MachineFunction &MF,
DebugLoc DL,
- const TargetInstrDesc &TID,
+ const MCInstrDesc &MCID,
unsigned DestReg) {
- return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL))
+ return MachineInstrBuilder(MF.CreateMachineInstr(MCID, DL))
.addReg(DestReg, RegState::Define);
}
@@ -197,9 +202,9 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF,
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
DebugLoc DL,
- const TargetInstrDesc &TID,
+ const MCInstrDesc &MCID,
unsigned DestReg) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
return MachineInstrBuilder(MI).addReg(DestReg, RegState::Define);
}
@@ -211,8 +216,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
MachineBasicBlock::iterator I,
DebugLoc DL,
- const TargetInstrDesc &TID) {
- MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL);
+ const MCInstrDesc &MCID) {
+ MachineInstr *MI = BB.getParent()->CreateMachineInstr(MCID, DL);
BB.insert(I, MI);
return MachineInstrBuilder(MI);
}
@@ -223,8 +228,8 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
///
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
DebugLoc DL,
- const TargetInstrDesc &TID) {
- return BuildMI(*BB, BB->end(), DL, TID);
+ const MCInstrDesc &MCID) {
+ return BuildMI(*BB, BB->end(), DL, MCID);
}
/// BuildMI - This version of the builder inserts the newly-built
@@ -233,9 +238,9 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
///
inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
DebugLoc DL,
- const TargetInstrDesc &TID,
+ const MCInstrDesc &MCID,
unsigned DestReg) {
- return BuildMI(*BB, BB->end(), DL, TID, DestReg);
+ return BuildMI(*BB, BB->end(), DL, MCID, DestReg);
}
inline unsigned getDefRegState(bool B) {
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index 140c6e8..fdef574 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -21,6 +21,7 @@ namespace llvm {
class BlockAddress;
class ConstantFP;
+class ConstantInt;
class GlobalValue;
class MachineBasicBlock;
class MachineInstr;
@@ -38,6 +39,7 @@ public:
enum MachineOperandType {
MO_Register, ///< Register operand.
MO_Immediate, ///< Immediate operand
+ MO_CImmediate, ///< Immediate >64bit operand
MO_FPImmediate, ///< Floating-point immediate operand
MO_MachineBasicBlock, ///< MachineBasicBlock reference
MO_FrameIndex, ///< Abstract Stack Frame Index
@@ -111,6 +113,7 @@ private:
union {
MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
const ConstantFP *CFP; // For MO_FPImmediate.
+ const ConstantInt *CI; // For MO_CImmediate. Integers > 64bit.
int64_t ImmVal; // For MO_Immediate.
const MDNode *MD; // For MO_Metadata.
MCSymbol *Sym; // For MO_MCSymbol
@@ -173,6 +176,8 @@ public:
bool isReg() const { return OpKind == MO_Register; }
/// isImm - Tests if this is a MO_Immediate operand.
bool isImm() const { return OpKind == MO_Immediate; }
+ /// isCImm - Test if t his is a MO_CImmediate operand.
+ bool isCImm() const { return OpKind == MO_CImmediate; }
/// isFPImm - Tests if this is a MO_FPImmediate operand.
bool isFPImm() const { return OpKind == MO_FPImmediate; }
/// isMBB - Tests if this is a MO_MachineBasicBlock operand.
@@ -333,6 +338,11 @@ public:
return Contents.ImmVal;
}
+ const ConstantInt *getCImm() const {
+ assert(isCImm() && "Wrong MachineOperand accessor");
+ return Contents.CI;
+ }
+
const ConstantFP *getFPImm() const {
assert(isFPImm() && "Wrong MachineOperand accessor");
return Contents.CFP;
@@ -440,6 +450,12 @@ public:
return Op;
}
+ static MachineOperand CreateCImm(const ConstantInt *CI) {
+ MachineOperand Op(MachineOperand::MO_CImmediate);
+ Op.Contents.CI = CI;
+ return Op;
+ }
+
static MachineOperand CreateFPImm(const ConstantFP *CFP) {
MachineOperand Op(MachineOperand::MO_FPImmediate);
Op.Contents.CFP = CFP;
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 74df8da..8754108 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -32,11 +32,6 @@ class MachineRegisterInfo {
IndexedMap<std::pair<const TargetRegisterClass*, MachineOperand*>,
VirtReg2IndexFunctor> VRegInfo;
- /// RegClassVRegMap - This vector acts as a map from TargetRegisterClass to
- /// virtual registers. For each target register class, it keeps a list of
- /// virtual registers belonging to the class.
- std::vector<unsigned> *RegClass2VRegMap;
-
/// RegAllocHints - This vector records register allocation hints for virtual
/// registers. For each virtual register, it keeps a register and hint type
/// pair making up the allocation hint. Hint type is target specific except
@@ -216,13 +211,6 @@ public:
///
unsigned getNumVirtRegs() const { return VRegInfo.size(); }
- /// getRegClassVirtRegs - Return the list of virtual registers of the given
- /// target register class.
- const std::vector<unsigned> &
- getRegClassVirtRegs(const TargetRegisterClass *RC) const {
- return RegClass2VRegMap[RC->getID()];
- }
-
/// setRegAllocationHint - Specify a register allocation hint for the
/// specified virtual register.
void setRegAllocationHint(unsigned Reg, unsigned Type, unsigned PrefReg) {
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 53aee7a..e7928cb 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -73,16 +73,9 @@ namespace llvm {
/// This pass is still in development
extern char &StrongPHIEliminationID;
- extern char &PreAllocSplittingID;
-
/// LiveStacks pass. An analysis keeping track of the liveness of stack slots.
extern char &LiveStacksID;
- /// SimpleRegisterCoalescing pass. Aggressively coalesces every register
- /// copy it can.
- ///
- extern char &SimpleRegisterCoalescingID;
-
/// TwoAddressInstruction pass - This pass reduces two-address instructions to
/// use two operands. This destroys SSA information but it is desired by
/// register allocators.
@@ -132,10 +125,10 @@ namespace llvm {
///
FunctionPass *createDefaultPBQPRegisterAllocator();
- /// SimpleRegisterCoalescing Pass - Coalesce all copies possible. Can run
+ /// RegisterCoalescer Pass - Coalesce all copies possible. Can run
/// independently of the register allocator.
///
- RegisterCoalescer *createSimpleRegisterCoalescer();
+ RegisterCoalescer *createRegisterCoalescer();
/// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
/// and eliminates abstract frame references.
diff --git a/include/llvm/CodeGen/RegisterCoalescer.h b/include/llvm/CodeGen/RegisterCoalescer.h
deleted file mode 100644
index af0b394..0000000
--- a/include/llvm/CodeGen/RegisterCoalescer.h
+++ /dev/null
@@ -1,244 +0,0 @@
-//===-- RegisterCoalescer.h - Register Coalescing Interface ------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains the abstract interface for register coalescers,
-// allowing them to interact with and query register allocators.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/IncludeFile.h"
-#include "llvm/CodeGen/LiveInterval.h"
-#include "llvm/ADT/SmallPtrSet.h"
-
-#ifndef LLVM_CODEGEN_REGISTER_COALESCER_H
-#define LLVM_CODEGEN_REGISTER_COALESCER_H
-
-namespace llvm {
-
- class MachineFunction;
- class RegallocQuery;
- class AnalysisUsage;
- class MachineInstr;
- class TargetRegisterInfo;
- class TargetRegisterClass;
- class TargetInstrInfo;
-
- /// An abstract interface for register coalescers. Coalescers must
- /// implement this interface to be part of the coalescer analysis
- /// group.
- class RegisterCoalescer {
- public:
- static char ID; // Class identification, replacement for typeinfo
- RegisterCoalescer() {}
- virtual ~RegisterCoalescer(); // We want to be subclassed
-
- /// Run the coalescer on this function, providing interference
- /// data to query. Return whether we removed any copies.
- virtual bool coalesceFunction(MachineFunction &mf,
- RegallocQuery &ifd) = 0;
-
- /// Reset state. Can be used to allow a coalescer run by
- /// PassManager to be run again by the register allocator.
- virtual void reset(MachineFunction &mf) {}
-
- /// Register allocators must call this from their own
- /// getAnalysisUsage to cover the case where the coalescer is not
- /// a Pass in the proper sense and isn't managed by PassManager.
- /// PassManager needs to know which analyses to make available and
- /// which to invalidate when running the register allocator or any
- /// pass that might call coalescing. The long-term solution is to
- /// allow hierarchies of PassManagers.
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {}
- };
-
- /// An abstract interface for register allocators to interact with
- /// coalescers
- ///
- /// Example:
- ///
- /// This is simply an example of how to use the RegallocQuery
- /// interface. It is not meant to be used in production.
- ///
- /// class LinearScanRegallocQuery : public RegallocQuery {
- /// private:
- /// const LiveIntervals \&li;
- ///
- /// public:
- /// LinearScanRegallocQuery(LiveIntervals &intervals)
- /// : li(intervals) {}
- ///
- /// /// This is pretty slow and conservative, but since linear scan
- /// /// allocation doesn't pre-compute interference information it's
- /// /// the best we can do. Coalescers are always free to ignore this
- /// /// and implement their own discovery strategy. See
- /// /// SimpleRegisterCoalescing for an example.
- /// void getInterferences(IntervalSet &interferences,
- /// const LiveInterval &a) const {
- /// for(LiveIntervals::const_iterator iv = li.begin(),
- /// ivend = li.end();
- /// iv != ivend;
- /// ++iv) {
- /// if (interfere(a, iv->second)) {
- /// interferences.insert(&iv->second);
- /// }
- /// }
- /// }
- ///
- /// /// This is *really* slow and stupid. See above.
- /// int getNumberOfInterferences(const LiveInterval &a) const {
- /// IntervalSet intervals;
- /// getInterferences(intervals, a);
- /// return intervals.size();
- /// }
- /// };
- ///
- /// In the allocator:
- ///
- /// RegisterCoalescer &coalescer = getAnalysis<RegisterCoalescer>();
- ///
- /// // We don't reset the coalescer so if it's already been run this
- /// // takes almost no time.
- /// LinearScanRegallocQuery ifd(*li_);
- /// coalescer.coalesceFunction(fn, ifd);
- ///
- class RegallocQuery {
- public:
- typedef SmallPtrSet<const LiveInterval *, 8> IntervalSet;
-
- virtual ~RegallocQuery() {}
-
- /// Return whether two live ranges interfere.
- virtual bool interfere(const LiveInterval &a,
- const LiveInterval &b) const {
- // A naive test
- return a.overlaps(b);
- }
-
- /// Return the set of intervals that interfere with this one.
- virtual void getInterferences(IntervalSet &interferences,
- const LiveInterval &a) const = 0;
-
- /// This can often be cheaper than actually returning the
- /// interferences.
- virtual int getNumberOfInterferences(const LiveInterval &a) const = 0;
-
- /// Make any data structure updates necessary to reflect
- /// coalescing or other modifications.
- virtual void updateDataForMerge(const LiveInterval &a,
- const LiveInterval &b,
- const MachineInstr &copy) {}
-
- /// Allow the register allocator to communicate when it doesn't
- /// want a copy coalesced. This may be due to assumptions made by
- /// the allocator about various invariants and so this question is
- /// a matter of legality, not performance. Performance decisions
- /// about which copies to coalesce should be made by the
- /// coalescer.
- virtual bool isLegalToCoalesce(const MachineInstr &inst) const {
- return true;
- }
- };
-
-
- /// CoalescerPair - A helper class for register coalescers. When deciding if
- /// two registers can be coalesced, CoalescerPair can determine if a copy
- /// instruction would become an identity copy after coalescing.
- class CoalescerPair {
- const TargetInstrInfo &tii_;
- const TargetRegisterInfo &tri_;
-
- /// dstReg_ - The register that will be left after coalescing. It can be a
- /// virtual or physical register.
- unsigned dstReg_;
-
- /// srcReg_ - the virtual register that will be coalesced into dstReg.
- unsigned srcReg_;
-
- /// subReg_ - The subregister index of srcReg in dstReg_. It is possible the
- /// coalesce srcReg_ into a subreg of the larger dstReg_ when dstReg_ is a
- /// virtual register.
- unsigned subIdx_;
-
- /// partial_ - True when the original copy was a partial subregister copy.
- bool partial_;
-
- /// crossClass_ - True when both regs are virtual, and newRC is constrained.
- bool crossClass_;
-
- /// flipped_ - True when DstReg and SrcReg are reversed from the oriignal copy
- /// instruction.
- bool flipped_;
-
- /// newRC_ - The register class of the coalesced register, or NULL if dstReg_
- /// is a physreg.
- const TargetRegisterClass *newRC_;
-
- /// compose - Compose subreg indices a and b, either may be 0.
- unsigned compose(unsigned, unsigned) const;
-
- /// isMoveInstr - Return true if MI is a move or subreg instruction.
- bool isMoveInstr(const MachineInstr *MI, unsigned &Src, unsigned &Dst,
- unsigned &SrcSub, unsigned &DstSub) const;
-
- public:
- CoalescerPair(const TargetInstrInfo &tii, const TargetRegisterInfo &tri)
- : tii_(tii), tri_(tri), dstReg_(0), srcReg_(0), subIdx_(0),
- partial_(false), crossClass_(false), flipped_(false), newRC_(0) {}
-
- /// setRegisters - set registers to match the copy instruction MI. Return
- /// false if MI is not a coalescable copy instruction.
- bool setRegisters(const MachineInstr*);
-
- /// flip - Swap srcReg_ and dstReg_. Return false if swapping is impossible
- /// because dstReg_ is a physical register, or subIdx_ is set.
- bool flip();
-
- /// isCoalescable - Return true if MI is a copy instruction that will become
- /// an identity copy after coalescing.
- bool isCoalescable(const MachineInstr*) const;
-
- /// isPhys - Return true if DstReg is a physical register.
- bool isPhys() const { return !newRC_; }
-
- /// isPartial - Return true if the original copy instruction did not copy the
- /// full register, but was a subreg operation.
- bool isPartial() const { return partial_; }
-
- /// isCrossClass - Return true if DstReg is virtual and NewRC is a smaller register class than DstReg's.
- bool isCrossClass() const { return crossClass_; }
-
- /// isFlipped - Return true when getSrcReg is the register being defined by
- /// the original copy instruction.
- bool isFlipped() const { return flipped_; }
-
- /// getDstReg - Return the register (virtual or physical) that will remain
- /// after coalescing.
- unsigned getDstReg() const { return dstReg_; }
-
- /// getSrcReg - Return the virtual register that will be coalesced away.
- unsigned getSrcReg() const { return srcReg_; }
-
- /// getSubIdx - Return the subregister index in DstReg that SrcReg will be
- /// coalesced into, or 0.
- unsigned getSubIdx() const { return subIdx_; }
-
- /// getNewRC - Return the register class of the coalesced register.
- const TargetRegisterClass *getNewRC() const { return newRC_; }
- };
-}
-
-// Because of the way .a files work, we must force the SimpleRC
-// implementation to be pulled in if the RegisterCoalescing header is
-// included. Otherwise we run the risk of RegisterCoalescing being
-// used, but the default implementation not being linked into the tool
-// that uses it.
-FORCE_DEFINING_FILE_TO_BE_LINKED(RegisterCoalescer)
-FORCE_DEFINING_FILE_TO_BE_LINKED(SimpleRegisterCoalescing)
-
-#endif
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 0657664..1bbc6c5 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -34,7 +34,7 @@ namespace llvm {
class ScheduleDAG;
class SDNode;
class TargetInstrInfo;
- class TargetInstrDesc;
+ class MCInstrDesc;
class TargetMachine;
class TargetRegisterClass;
template<class Graph> class GraphWriter;
@@ -507,9 +507,9 @@ namespace llvm {
virtual ~ScheduleDAG();
- /// getInstrDesc - Return the TargetInstrDesc of this SUnit.
+ /// getInstrDesc - Return the MCInstrDesc of this SUnit.
/// Return NULL for SDNodes without a machine opcode.
- const TargetInstrDesc *getInstrDesc(const SUnit *SU) const {
+ const MCInstrDesc *getInstrDesc(const SUnit *SU) const {
if (SU->isInstr()) return &SU->getInstr()->getDesc();
return getNodeDesc(SU->getNode());
}
@@ -579,8 +579,8 @@ namespace llvm {
void EmitPhysRegCopy(SUnit *SU, DenseMap<SUnit*, unsigned> &VRBaseMap);
private:
- // Return the TargetInstrDesc of this SDNode or NULL.
- const TargetInstrDesc *getNodeDesc(const SDNode *Node) const;
+ // Return the MCInstrDesc of this SDNode or NULL.
+ const MCInstrDesc *getNodeDesc(const SDNode *Node) const;
};
class SUnitIterator : public std::iterator<std::forward_iterator_tag,
diff --git a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
index 118df28..060e89a 100644
--- a/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
+++ b/include/llvm/CodeGen/ScoreboardHazardRecognizer.h
@@ -25,7 +25,6 @@
namespace llvm {
class InstrItineraryData;
-class TargetInstrDesc;
class ScheduleDAG;
class SUnit;
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
index ff59951..1afbb8a 100644
--- a/include/llvm/Constants.h
+++ b/include/llvm/Constants.h
@@ -387,6 +387,12 @@ public:
///
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;
+
/// isNullValue - Return true if this is the value that would be returned by
/// getNullValue. This always returns false because zero arrays are always
/// created as ConstantAggregateZero objects.
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 5efdcc9..dfd9246 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -65,6 +65,7 @@ void initializeArgPromotionPass(PassRegistry&);
void initializeBasicAliasAnalysisPass(PassRegistry&);
void initializeBasicCallGraphPass(PassRegistry&);
void initializeBlockExtractorPassPass(PassRegistry&);
+void initializeBlockFrequencyPass(PassRegistry&);
void initializeBlockPlacementPass(PassRegistry&);
void initializeBranchProbabilityInfoPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
@@ -176,7 +177,6 @@ void initializePostDomOnlyViewerPass(PassRegistry&);
void initializePostDomPrinterPass(PassRegistry&);
void initializePostDomViewerPass(PassRegistry&);
void initializePostDominatorTreePass(PassRegistry&);
-void initializePreAllocSplittingPass(PassRegistry&);
void initializePreVerifierPass(PassRegistry&);
void initializePrintDbgInfoPass(PassRegistry&);
void initializePrintFunctionPassPass(PassRegistry&);
@@ -197,7 +197,6 @@ void initializeRegionOnlyPrinterPass(PassRegistry&);
void initializeRegionOnlyViewerPass(PassRegistry&);
void initializeRegionPrinterPass(PassRegistry&);
void initializeRegionViewerPass(PassRegistry&);
-void initializeRegisterCoalescerAnalysisGroup(PassRegistry&);
void initializeRenderMachineFunctionPass(PassRegistry&);
void initializeSCCPPass(PassRegistry&);
void initializeSROA_DTPass(PassRegistry&);
@@ -205,7 +204,7 @@ void initializeSROA_SSAUpPass(PassRegistry&);
void initializeScalarEvolutionAliasAnalysisPass(PassRegistry&);
void initializeScalarEvolutionPass(PassRegistry&);
void initializeSimpleInlinerPass(PassRegistry&);
-void initializeSimpleRegisterCoalescingPass(PassRegistry&);
+void initializeRegisterCoalescerPass(PassRegistry&);
void initializeSimplifyLibCallsPass(PassRegistry&);
void initializeSingleLoopExtractorPass(PassRegistry&);
void initializeSinkingPass(PassRegistry&);
diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h
index 0d86086..ed5bf8b 100644
--- a/include/llvm/InlineAsm.h
+++ b/include/llvm/InlineAsm.h
@@ -188,25 +188,32 @@ public:
// in the backend.
enum {
+ // Fixed operands on an INLINEASM SDNode.
Op_InputChain = 0,
Op_AsmString = 1,
Op_MDNode = 2,
Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack
Op_FirstOperand = 4,
+ // Fixed operands on an INLINEASM MachineInstr.
MIOp_AsmString = 0,
MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack
MIOp_FirstOperand = 2,
+ // Interpretation of the MIOp_ExtraInfo bit field.
Extra_HasSideEffects = 1,
Extra_IsAlignStack = 2,
-
- Kind_RegUse = 1,
- Kind_RegDef = 2,
- Kind_Imm = 3,
- Kind_Mem = 4,
- Kind_RegDefEarlyClobber = 6,
-
+
+ // Inline asm operands map to multiple SDNode / MachineInstr operands.
+ // The first operand is an immediate describing the asm operand, the low
+ // bits is the kind:
+ Kind_RegUse = 1, // Input register, "r".
+ Kind_RegDef = 2, // Output register, "=r".
+ Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
+ Kind_Clobber = 4, // Clobbered register, "~r".
+ Kind_Imm = 5, // Immediate.
+ Kind_Mem = 6, // Memory operand, "m".
+
Flag_MatchingOperand = 0x80000000
};
@@ -233,7 +240,10 @@ public:
static bool isRegDefEarlyClobberKind(unsigned Flag) {
return getKind(Flag) == Kind_RegDefEarlyClobber;
}
-
+ static bool isClobberKind(unsigned Flag) {
+ return getKind(Flag) == Kind_Clobber;
+ }
+
/// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) {
diff --git a/include/llvm/Target/TargetInstrDesc.h b/include/llvm/MC/MCInstrDesc.h
index 6e20e8a..17d5fdc 100644
--- a/include/llvm/Target/TargetInstrDesc.h
+++ b/include/llvm/MC/MCInstrDesc.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
+//===-- llvm/Mc/McInstrDesc.h - Instruction Descriptors -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,26 +7,23 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the TargetOperandInfo and TargetInstrDesc classes, which
+// This file defines the MCOperandInfo and MCInstrDesc classes, which
// are used to describe target instructions and their operands.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_TARGETINSTRDESC_H
-#define LLVM_TARGET_TARGETINSTRDESC_H
+#ifndef LLVM_MC_MCINSTRDESC_H
+#define LLVM_MC_MCINSTRDESC_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
-class TargetRegisterClass;
-class TargetRegisterInfo;
-
//===----------------------------------------------------------------------===//
// Machine Operand Flags and Description
//===----------------------------------------------------------------------===//
-namespace TOI {
+namespace MCOI {
// Operand constraints
enum OperandConstraint {
TIED_TO = 0, // Must be allocated the same register as.
@@ -34,7 +31,7 @@ namespace TOI {
};
/// OperandFlags - These are flags set on operands, but should be considered
- /// private, all access should go through the TargetOperandInfo accessors.
+ /// private, all access should go through the MCOperandInfo accessors.
/// See the accessors for a description of what these are.
enum OperandFlags {
LookupPtrRegClass = 0,
@@ -43,21 +40,18 @@ namespace TOI {
};
}
-/// TargetOperandInfo - This holds information about one operand of a machine
+/// MCOperandInfo - This holds information about one operand of a machine
/// instruction, indicating the register class for register operands, etc.
///
-class TargetOperandInfo {
+class MCOperandInfo {
public:
/// RegClass - This specifies the register class enumeration of the operand
/// if the operand is a register. If isLookupPtrRegClass is set, then this is
/// an index that is passed to TargetRegisterInfo::getPointerRegClass(x) to
/// get a dynamic register class.
- ///
- /// NOTE: This member should be considered to be private, all access should go
- /// through "getRegClass(TRI)" below.
short RegClass;
- /// Flags - These are flags from the TOI::OperandFlags enum.
+ /// Flags - These are flags from the MCOI::OperandFlags enum.
unsigned short Flags;
/// Lower 16 bits are used to specify which constraints are set. The higher 16
@@ -65,23 +59,17 @@ public:
unsigned Constraints;
/// Currently no other information.
- /// getRegClass - Get the register class for the operand, handling resolution
- /// of "symbolic" pointer register classes etc. If this is not a register
- /// operand, this returns null.
- const TargetRegisterClass *getRegClass(const TargetRegisterInfo *TRI) const;
-
-
/// isLookupPtrRegClass - Set if this operand is a pointer value and it
/// requires a callback to look up its register class.
- bool isLookupPtrRegClass() const { return Flags&(1 <<TOI::LookupPtrRegClass);}
+ bool isLookupPtrRegClass() const { return Flags&(1 <<MCOI::LookupPtrRegClass);}
/// isPredicate - Set if this is one of the operands that made up of
/// the predicate operand that controls an isPredicable() instruction.
- bool isPredicate() const { return Flags & (1 << TOI::Predicate); }
+ bool isPredicate() const { return Flags & (1 << MCOI::Predicate); }
/// isOptionalDef - Set if this operand is a optional def.
///
- bool isOptionalDef() const { return Flags & (1 << TOI::OptionalDef); }
+ bool isOptionalDef() const { return Flags & (1 << MCOI::OptionalDef); }
};
@@ -89,11 +77,11 @@ public:
// Machine Instruction Flags and Description
//===----------------------------------------------------------------------===//
-/// TargetInstrDesc flags - These should be considered private to the
-/// implementation of the TargetInstrDesc class. Clients should use the
-/// predicate methods on TargetInstrDesc, not use these directly. These
-/// all correspond to bitfields in the TargetInstrDesc::Flags field.
-namespace TID {
+/// MCInstrDesc flags - These should be considered private to the
+/// implementation of the MCInstrDesc class. Clients should use the predicate
+/// methods on MCInstrDesc, not use these directly. These all correspond to
+/// bitfields in the MCInstrDesc::Flags field.
+namespace MCID {
enum {
Variadic = 0,
HasOptionalDef,
@@ -123,12 +111,12 @@ namespace TID {
};
}
-/// TargetInstrDesc - Describe properties that are true of each
-/// instruction in the target description file. This captures information about
-/// side effects, register use and many other things. There is one instance of
-/// this struct for each target instruction class, and the MachineInstr class
-/// points to this struct directly to describe itself.
-class TargetInstrDesc {
+/// MCInstrDesc - Describe properties that are true of each instruction in the
+/// target description file. This captures information about side effects,
+/// register use and many other things. There is one instance of this struct
+/// for each target instruction class, and the MachineInstr class points to
+/// this struct directly to describe itself.
+class MCInstrDesc {
public:
unsigned short Opcode; // The opcode number
unsigned short NumOperands; // Num of args (may be more if variable_ops)
@@ -139,13 +127,12 @@ public:
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 TargetRegisterClass **RCBarriers; // Reg classes completely "clobbered"
- const TargetOperandInfo *OpInfo; // 'NumOperands' entries about operands
+ const MCOperandInfo *OpInfo; // 'NumOperands' entries about operands
/// getOperandConstraint - Returns the value of the specific constraint if
/// it is set. Returns -1 if it is not set.
int getOperandConstraint(unsigned OpNum,
- TOI::OperandConstraint Constraint) const {
+ MCOI::OperandConstraint Constraint) const {
if (OpNum < NumOperands &&
(OpInfo[OpNum].Constraints & (1 << Constraint))) {
unsigned Pos = 16 + Constraint * 4;
@@ -154,12 +141,6 @@ public:
return -1;
}
- /// getRegClass - Returns the register class constraint for OpNum, or NULL.
- const TargetRegisterClass *getRegClass(unsigned OpNum,
- const TargetRegisterInfo *TRI) const {
- return OpNum < NumOperands ? OpInfo[OpNum].getRegClass(TRI) : 0;
- }
-
/// getOpcode - Return the opcode number for this descriptor.
unsigned getOpcode() const {
return Opcode;
@@ -193,13 +174,13 @@ public:
/// operands but before the implicit definitions and uses (if any are
/// present).
bool isVariadic() const {
- return Flags & (1 << TID::Variadic);
+ return Flags & (1 << MCID::Variadic);
}
/// hasOptionalDef - Set if this instruction has an optional definition, e.g.
/// ARM instructions which can set condition code if 's' bit is set.
bool hasOptionalDef() const {
- return Flags & (1 << TID::HasOptionalDef);
+ return Flags & (1 << MCID::HasOptionalDef);
}
/// getImplicitUses - Return a list of registers that are potentially
@@ -214,7 +195,7 @@ public:
const unsigned *getImplicitUses() const {
return ImplicitUses;
}
-
+
/// getNumImplicitUses - Return the number of implicit uses this instruction
/// has.
unsigned getNumImplicitUses() const {
@@ -223,8 +204,7 @@ public:
for (; ImplicitUses[i]; ++i) /*empty*/;
return i;
}
-
-
+
/// getImplicitDefs - Return a list of registers that are potentially
/// written by any instance of this machine instruction. For example, on X86,
/// many instructions implicitly set the flags register. In this case, they
@@ -266,17 +246,6 @@ public:
return false;
}
- /// getRegClassBarriers - Return a list of register classes that are
- /// completely clobbered by this machine instruction. For example, on X86
- /// the call instructions will completely clobber all the registers in the
- /// fp stack and XMM classes.
- ///
- /// This method returns null if the instruction doesn't completely clobber
- /// any register class.
- const TargetRegisterClass **getRegClassBarriers() const {
- return RCBarriers;
- }
-
/// getSchedClass - Return the scheduling class for this instruction. The
/// scheduling class is an index into the InstrItineraryData table. This
/// returns zero if there is no known scheduling information for the
@@ -287,18 +256,18 @@ public:
}
bool isReturn() const {
- return Flags & (1 << TID::Return);
+ return Flags & (1 << MCID::Return);
}
bool isCall() const {
- return Flags & (1 << TID::Call);
+ return Flags & (1 << MCID::Call);
}
/// isBarrier - Returns true if the specified instruction stops control flow
/// from executing the instruction immediately following it. Examples include
/// unconditional branches and return instructions.
bool isBarrier() const {
- return Flags & (1 << TID::Barrier);
+ return Flags & (1 << MCID::Barrier);
}
/// isTerminator - Returns true if this instruction part of the terminator for
@@ -308,7 +277,7 @@ public:
/// Various passes use this to insert code into the bottom of a basic block,
/// but before control flow occurs.
bool isTerminator() const {
- return Flags & (1 << TID::Terminator);
+ return Flags & (1 << MCID::Terminator);
}
/// isBranch - Returns true if this is a conditional, unconditional, or
@@ -316,13 +285,13 @@ public:
/// these cases, and the TargetInstrInfo::AnalyzeBranch method can be used to
/// get more information.
bool isBranch() const {
- return Flags & (1 << TID::Branch);
+ return Flags & (1 << MCID::Branch);
}
/// isIndirectBranch - Return true if this is an indirect branch, such as a
/// branch through a register.
bool isIndirectBranch() const {
- return Flags & (1 << TID::IndirectBranch);
+ return Flags & (1 << MCID::IndirectBranch);
}
/// isConditionalBranch - Return true if this is a branch which may fall
@@ -346,37 +315,37 @@ public:
/// values. There are various methods in TargetInstrInfo that can be used to
/// control and modify the predicate in this instruction.
bool isPredicable() const {
- return Flags & (1 << TID::Predicable);
+ return Flags & (1 << MCID::Predicable);
}
/// isCompare - Return true if this instruction is a comparison.
bool isCompare() const {
- return Flags & (1 << TID::Compare);
+ return Flags & (1 << MCID::Compare);
}
/// isMoveImmediate - Return true if this instruction is a move immediate
/// (including conditional moves) instruction.
bool isMoveImmediate() const {
- return Flags & (1 << TID::MoveImm);
+ return Flags & (1 << MCID::MoveImm);
}
/// isBitcast - Return true if this instruction is a bitcast instruction.
///
bool isBitcast() const {
- return Flags & (1 << TID::Bitcast);
+ return Flags & (1 << MCID::Bitcast);
}
/// isNotDuplicable - Return true if this instruction cannot be safely
/// duplicated. For example, if the instruction has a unique labels attached
/// to it, duplicating it would cause multiple definition errors.
bool isNotDuplicable() const {
- return Flags & (1 << TID::NotDuplicable);
+ return Flags & (1 << MCID::NotDuplicable);
}
/// hasDelaySlot - Returns true if the specified instruction has a delay slot
/// which must be filled by the code generator.
bool hasDelaySlot() const {
- return Flags & (1 << TID::DelaySlot);
+ return Flags & (1 << MCID::DelaySlot);
}
/// canFoldAsLoad - Return true for instructions that can be folded as
@@ -388,7 +357,7 @@ public:
/// This should only be set on instructions that return a value in their
/// only virtual register definition.
bool canFoldAsLoad() const {
- return Flags & (1 << TID::FoldableAsLoad);
+ return Flags & (1 << MCID::FoldableAsLoad);
}
//===--------------------------------------------------------------------===//
@@ -399,7 +368,7 @@ public:
/// Instructions with this flag set are not necessarily simple load
/// instructions, they may load a value and modify it, for example.
bool mayLoad() const {
- return Flags & (1 << TID::MayLoad);
+ return Flags & (1 << MCID::MayLoad);
}
@@ -408,7 +377,7 @@ public:
/// instructions, they may store a modified value based on their operands, or
/// may not actually modify anything, for example.
bool mayStore() const {
- return Flags & (1 << TID::MayStore);
+ return Flags & (1 << MCID::MayStore);
}
/// hasUnmodeledSideEffects - Return true if this instruction has side
@@ -425,7 +394,7 @@ public:
/// LLVM, etc.
///
bool hasUnmodeledSideEffects() const {
- return Flags & (1 << TID::UnmodeledSideEffects);
+ return Flags & (1 << MCID::UnmodeledSideEffects);
}
//===--------------------------------------------------------------------===//
@@ -443,7 +412,7 @@ public:
/// Also note that some instructions require non-trivial modification to
/// commute them.
bool isCommutable() const {
- return Flags & (1 << TID::Commutable);
+ return Flags & (1 << MCID::Commutable);
}
/// isConvertibleTo3Addr - Return true if this is a 2-address instruction
@@ -461,7 +430,7 @@ public:
/// instruction (e.g. shl reg, 4 on x86).
///
bool isConvertibleTo3Addr() const {
- return Flags & (1 << TID::ConvertibleTo3Addr);
+ return Flags & (1 << MCID::ConvertibleTo3Addr);
}
/// usesCustomInsertionHook - Return true if this instruction requires
@@ -473,7 +442,7 @@ public:
/// If this is true, the TargetLoweringInfo::InsertAtEndOfBasicBlock method
/// is used to insert this into the MachineBasicBlock.
bool usesCustomInsertionHook() const {
- return Flags & (1 << TID::UsesCustomInserter);
+ return Flags & (1 << MCID::UsesCustomInserter);
}
/// isRematerializable - Returns true if this instruction is a candidate for
@@ -481,7 +450,7 @@ public:
/// flag is set, the isReallyTriviallyReMaterializable() method is called to
/// verify the instruction is really rematable.
bool isRematerializable() const {
- return Flags & (1 << TID::Rematerializable);
+ return Flags & (1 << MCID::Rematerializable);
}
/// isAsCheapAsAMove - Returns true if this instruction has the same cost (or
@@ -491,7 +460,7 @@ public:
/// more than moving the instruction into the appropriate register. Note, we
/// are not marking copies from and to the same register class with this flag.
bool isAsCheapAsAMove() const {
- return Flags & (1 << TID::CheapAsAMove);
+ return Flags & (1 << MCID::CheapAsAMove);
}
/// hasExtraSrcRegAllocReq - Returns true if this instruction source operands
@@ -501,7 +470,7 @@ public:
/// Post-register allocation passes should not attempt to change allocations
/// for sources of instructions with this flag.
bool hasExtraSrcRegAllocReq() const {
- return Flags & (1 << TID::ExtraSrcRegAllocReq);
+ return Flags & (1 << MCID::ExtraSrcRegAllocReq);
}
/// hasExtraDefRegAllocReq - Returns true if this instruction def operands
@@ -511,7 +480,7 @@ public:
/// Post-register allocation passes should not attempt to change allocations
/// for definitions of instructions with this flag.
bool hasExtraDefRegAllocReq() const {
- return Flags & (1 << TID::ExtraDefRegAllocReq);
+ return Flags & (1 << MCID::ExtraDefRegAllocReq);
}
};
diff --git a/include/llvm/MC/MCInstrInfo.h b/include/llvm/MC/MCInstrInfo.h
new file mode 100644
index 0000000..a63e5fa
--- /dev/null
+++ b/include/llvm/MC/MCInstrInfo.h
@@ -0,0 +1,51 @@
+//===-- llvm/MC/MCInstrInfo.h - Target Instruction Info ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the target machine instruction set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCINSTRINFO_H
+#define LLVM_MC_MCINSTRINFO_H
+
+#include "llvm/MC/MCInstrDesc.h"
+#include <cassert>
+
+namespace llvm {
+
+//---------------------------------------------------------------------------
+///
+/// MCInstrInfo - Interface to description of machine instruction set
+///
+class MCInstrInfo {
+ const MCInstrDesc *Desc; // Raw array to allow static init'n
+ unsigned NumOpcodes; // Number of entries in the desc array
+
+public:
+ /// InitMCInstrInfo - Initialize MCInstrInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCInstrInfo(const MCInstrDesc *D, unsigned NO) {
+ Desc = D;
+ NumOpcodes = NO;
+ }
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// get - Return the machine instruction descriptor that corresponds to the
+ /// specified instruction opcode.
+ ///
+ const MCInstrDesc &get(unsigned Opcode) const {
+ assert(Opcode < NumOpcodes && "Invalid opcode!");
+ return Desc[Opcode];
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/MC/MCInstrItineraries.h
index 6011402..e942892 100644
--- a/include/llvm/Target/TargetInstrItineraries.h
+++ b/include/llvm/MC/MCInstrItineraries.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===//
+//===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
-#define LLVM_TARGET_TARGETINSTRITINERARIES_H
+#ifndef LLVM_MC_MCINSTRITINERARIES_H
+#define LLVM_MC_MCINSTRITINERARIES_H
#include <algorithm>
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index ec51031..9bb598f 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -10,11 +10,20 @@
#ifndef LLVM_MC_MCMACHOBJECTWRITER_H
#define LLVM_MC_MCMACHOBJECTWRITER_H
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/Object/MachOFormat.h"
#include "llvm/Support/DataTypes.h"
+#include <vector>
namespace llvm {
+class MCSectionData;
+class MachObjectWriter;
+
class MCMachObjectTargetWriter {
const unsigned Is64Bit : 1;
const uint32_t CPUType;
@@ -48,8 +57,191 @@ public:
}
/// @}
+
+ /// @name API
+ /// @{
+
+ virtual void RecordRelocation(MachObjectWriter *Writer,
+ const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target,
+ uint64_t &FixedValue) = 0;
+
+ /// @}
};
+class MachObjectWriter : public MCObjectWriter {
+ /// MachSymbolData - Helper struct for containing some precomputed information
+ /// on symbols.
+ struct MachSymbolData {
+ MCSymbolData *SymbolData;
+ uint64_t StringIndex;
+ uint8_t SectionIndex;
+
+ // Support lexicographic sorting.
+ bool operator<(const MachSymbolData &RHS) const;
+ };
+
+ /// The target specific Mach-O writer instance.
+ llvm::OwningPtr<MCMachObjectTargetWriter> TargetObjectWriter;
+
+ /// @name Relocation Data
+ /// @{
+
+ llvm::DenseMap<const MCSectionData*,
+ std::vector<object::macho::RelocationEntry> > Relocations;
+ llvm::DenseMap<const MCSectionData*, unsigned> IndirectSymBase;
+
+ /// @}
+ /// @name Symbol Table Data
+ /// @{
+
+ SmallString<256> StringTable;
+ std::vector<MachSymbolData> LocalSymbolData;
+ std::vector<MachSymbolData> ExternalSymbolData;
+ std::vector<MachSymbolData> UndefinedSymbolData;
+
+ /// @}
+
+public:
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
+ bool _IsLittleEndian)
+ : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
+ }
+
+ /// @name Utility Methods
+ /// @{
+
+ bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
+
+ SectionAddrMap SectionAddress;
+
+ SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
+
+ uint64_t getSectionAddress(const MCSectionData* SD) const {
+ return SectionAddress.lookup(SD);
+ }
+ uint64_t getSymbolAddress(const MCSymbolData* SD,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getFragmentAddress(const MCFragment *Fragment,
+ const MCAsmLayout &Layout) const;
+
+ uint64_t getPaddingSize(const MCSectionData *SD,
+ const MCAsmLayout &Layout) const;
+
+ bool doesSymbolRequireExternRelocation(const MCSymbolData *SD);
+
+ /// @}
+
+ /// @name Target Writer Proxy Accessors
+ /// @{
+
+ bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
+ bool isARM() const {
+ uint32_t CPUType = TargetObjectWriter->getCPUType() &
+ ~object::mach::CTFM_ArchMask;
+ return CPUType == object::mach::CTM_ARM;
+ }
+
+ /// @}
+
+ void WriteHeader(unsigned NumLoadCommands, unsigned LoadCommandsSize,
+ bool SubsectionsViaSymbols);
+
+ /// WriteSegmentLoadCommand - Write a segment load command.
+ ///
+ /// \arg NumSections - The number of sections in this segment.
+ /// \arg SectionDataSize - The total size of the sections.
+ void WriteSegmentLoadCommand(unsigned NumSections,
+ uint64_t VMSize,
+ uint64_t SectionDataStartOffset,
+ uint64_t SectionDataSize);
+
+ void WriteSection(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCSectionData &SD, uint64_t FileOffset,
+ uint64_t RelocationsStart, unsigned NumRelocations);
+
+ void WriteSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
+ uint32_t StringTableOffset,
+ uint32_t StringTableSize);
+
+ void WriteDysymtabLoadCommand(uint32_t FirstLocalSymbol,
+ uint32_t NumLocalSymbols,
+ uint32_t FirstExternalSymbol,
+ uint32_t NumExternalSymbols,
+ uint32_t FirstUndefinedSymbol,
+ uint32_t NumUndefinedSymbols,
+ uint32_t IndirectSymbolOffset,
+ uint32_t NumIndirectSymbols);
+
+ void WriteNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
+
+ // FIXME: We really need to improve the relocation validation. Basically, we
+ // want to implement a separate computation which evaluates the relocation
+ // entry as the linker would, and verifies that the resultant fixup value is
+ // exactly what the encoder wanted. This will catch several classes of
+ // problems:
+ //
+ // - Relocation entry bugs, the two algorithms are unlikely to have the same
+ // exact bug.
+ //
+ // - Relaxation issues, where we forget to relax something.
+ //
+ // - Input errors, where something cannot be correctly encoded. 'as' allows
+ // these through in many cases.
+
+ void addRelocation(const MCSectionData *SD,
+ object::macho::RelocationEntry &MRE) {
+ Relocations[SD].push_back(MRE);
+ }
+
+ void RecordScatteredRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ unsigned Log2Size,
+ uint64_t &FixedValue);
+
+ void RecordTLVPRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup, MCValue Target,
+ uint64_t &FixedValue);
+
+ void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout,
+ const MCFragment *Fragment, const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue);
+
+ void BindIndirectSymbols(MCAssembler &Asm);
+
+ /// ComputeSymbolTable - Compute the symbol table data
+ ///
+ /// \param StringTable [out] - The string table data.
+ /// \param StringIndexMap [out] - Map from symbol names to offsets in the
+ /// string table.
+ void ComputeSymbolTable(MCAssembler &Asm, SmallString<256> &StringTable,
+ std::vector<MachSymbolData> &LocalSymbolData,
+ std::vector<MachSymbolData> &ExternalSymbolData,
+ std::vector<MachSymbolData> &UndefinedSymbolData);
+
+ void computeSectionAddresses(const MCAssembler &Asm,
+ const MCAsmLayout &Layout);
+
+ void ExecutePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+ virtual bool IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
+ const MCSymbolData &DataA,
+ const MCFragment &FB,
+ bool InSet,
+ bool IsPCRel) const;
+
+ void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+};
+
+
/// \brief Construct a new Mach-O writer instance.
///
/// This routine takes ownership of the target writer subclass.
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
new file mode 100644
index 0000000..caf98bb
--- /dev/null
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -0,0 +1,129 @@
+//=== MC/MCRegisterInfo.h - Target Register Description ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCREGISTERINFO_H
+#define LLVM_MC_MCREGISTERINFO_H
+
+#include <cassert>
+
+namespace llvm {
+
+/// MCRegisterDesc - This record contains all of the information known about
+/// a particular register. The Overlaps field contains a pointer to a zero
+/// terminated array of registers that this register aliases, starting with
+/// itself. This is needed for architectures like X86 which have AL alias AX
+/// alias EAX. The SubRegs field is a zero terminated array of registers that
+/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
+/// AX. The SuperRegs field is a zero terminated array of registers that are
+/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
+/// of AX.
+///
+struct MCRegisterDesc {
+ const char *Name; // Printable name for the reg (for debugging)
+ const unsigned *Overlaps; // Overlapping registers, described above
+ const unsigned *SubRegs; // Sub-register set, described above
+ const unsigned *SuperRegs; // Super-register set, described above
+};
+
+/// MCRegisterInfo base class - We assume that the target defines a static
+/// array of MCRegisterDesc objects that represent all of the machine
+/// registers that the target has. As such, we simply have to track a pointer
+/// to this array so that we can turn register number into a register
+/// descriptor.
+///
+/// Note this class is designed to be a base class of TargetRegisterInfo, which
+/// is the interface used by codegen. However, specific targets *should never*
+/// specialize this class. MCRegisterInfo should only contain getters to access
+/// TableGen generated physical register data. It must not be extended with
+/// virtual methods.
+///
+class MCRegisterInfo {
+private:
+ const MCRegisterDesc *Desc; // Pointer to the descriptor array
+ unsigned NumRegs; // Number of entries in the array
+
+public:
+ /// InitMCRegisterInfo - Initialize MCRegisterInfo, called by TableGen
+ /// auto-generated routines. *DO NOT USE*.
+ void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR) {
+ Desc = D;
+ NumRegs = NR;
+ }
+
+ const MCRegisterDesc &operator[](unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to access record for invalid register number!");
+ return Desc[RegNo];
+ }
+
+ /// Provide a get method, equivalent to [], but more useful if we have a
+ /// pointer to this object.
+ ///
+ const MCRegisterDesc &get(unsigned RegNo) const {
+ return operator[](RegNo);
+ }
+
+ /// getAliasSet - Return the set of registers aliased by the specified
+ /// register, or a null list of there are none. The list returned is zero
+ /// terminated.
+ ///
+ const unsigned *getAliasSet(unsigned RegNo) const {
+ // The Overlaps set always begins with Reg itself.
+ return get(RegNo).Overlaps + 1;
+ }
+
+ /// getOverlaps - Return a list of registers that overlap Reg, including
+ /// itself. This is the same as the alias set except Reg is included in the
+ /// list.
+ /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
+ ///
+ const unsigned *getOverlaps(unsigned RegNo) const {
+ return get(RegNo).Overlaps;
+ }
+
+ /// getSubRegisters - Return the list of registers that are sub-registers of
+ /// the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
+ ///
+ const unsigned *getSubRegisters(unsigned RegNo) const {
+ return get(RegNo).SubRegs;
+ }
+
+ /// getSuperRegisters - Return the list of registers that are super-registers
+ /// of the specified register, or a null list of there are none. The list
+ /// returned is zero terminated and sorted according to super-sub register
+ /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
+ ///
+ const unsigned *getSuperRegisters(unsigned RegNo) const {
+ return get(RegNo).SuperRegs;
+ }
+
+ /// getName - Return the human-readable symbolic target-specific name for the
+ /// specified physical register.
+ const char *getName(unsigned RegNo) const {
+ return get(RegNo).Name;
+ }
+
+ /// getNumRegs - Return the number of registers this target has (useful for
+ /// sizing arrays holding per register information)
+ unsigned getNumRegs() const {
+ return NumRegs;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h
index 4213d9b..fccff03 100644
--- a/include/llvm/Target/SubtargetFeature.h
+++ b/include/llvm/MC/SubtargetFeature.h
@@ -1,4 +1,4 @@
-//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
+//===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,17 +15,16 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
-#define LLVM_TARGET_SUBTARGETFEATURE_H
+#ifndef LLVM_MC_SUBTARGETFEATURE_H
+#define LLVM_MC_SUBTARGETFEATURE_H
-#include <string>
#include <vector>
-#include <cstring>
#include "llvm/ADT/Triple.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
class raw_ostream;
+ class StringRef;
//===----------------------------------------------------------------------===//
///
@@ -75,32 +74,24 @@ struct SubtargetInfoKV {
class SubtargetFeatures {
std::vector<std::string> Features; // Subtarget features as a vector
public:
- explicit SubtargetFeatures(const std::string &Initial = std::string());
+ explicit SubtargetFeatures(const StringRef Initial = "");
/// Features string accessors.
std::string getString() const;
- void setString(const std::string &Initial);
-
- /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
- void setCPU(const std::string &String);
-
- /// Setting CPU string only if no string is set.
- void setCPUIfNone(const std::string &String);
-
- /// Returns current CPU string.
- const std::string & getCPU() const;
/// Adding Features.
- void AddFeature(const std::string &String, bool IsEnabled = true);
+ void AddFeature(const StringRef String, bool IsEnabled = true);
- /// Get feature bits.
- uint64_t getBits(const SubtargetFeatureKV *CPUTable,
- size_t CPUTableSize,
- const SubtargetFeatureKV *FeatureTable,
- size_t FeatureTableSize);
+ /// Get feature bits of a CPU.
+ uint64_t getFeatureBits(const StringRef CPU,
+ const SubtargetFeatureKV *CPUTable,
+ size_t CPUTableSize,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
- /// Get info pointer
- void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
+ /// Get scheduling itinerary of a CPU.
+ void *getItinerary(const StringRef CPU,
+ const SubtargetInfoKV *Table, size_t TableSize);
/// Print feature string.
void print(raw_ostream &OS) const;
@@ -110,8 +101,7 @@ public:
/// Retrieve a formatted string of the default features for the specified
/// target triple.
- void getDefaultSubtargetFeatures(const std::string &CPU,
- const Triple& Triple);
+ void getDefaultSubtargetFeatures(const Triple& Triple);
};
} // End namespace llvm
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
new file mode 100644
index 0000000..cd092fd
--- /dev/null
+++ b/include/llvm/Object/Binary.h
@@ -0,0 +1,67 @@
+//===- Binary.h - A generic binary file -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Binary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_BINARY_H
+#define LLVM_OBJECT_BINARY_H
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Object/Error.h"
+
+namespace llvm {
+
+class MemoryBuffer;
+class StringRef;
+
+namespace object {
+
+class Binary {
+private:
+ Binary(); // = delete
+ Binary(const Binary &other); // = delete
+
+ unsigned int TypeID;
+
+protected:
+ MemoryBuffer *Data;
+
+ Binary(unsigned int Type, MemoryBuffer *Source);
+
+ enum {
+ isArchive,
+
+ // Object and children.
+ isObject,
+ isCOFF,
+ isELF,
+ isMachO,
+ lastObject
+ };
+
+public:
+ virtual ~Binary();
+
+ StringRef getData() const;
+ StringRef getFileName() const;
+
+ // Cast methods.
+ unsigned int getType() const { return TypeID; }
+ static inline bool classof(const Binary *v) { return true; }
+};
+
+error_code createBinary(MemoryBuffer *Source, OwningPtr<Binary> &Result);
+error_code createBinary(StringRef Path, OwningPtr<Binary> &Result);
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h
new file mode 100644
index 0000000..6a5e0d9
--- /dev/null
+++ b/include/llvm/Object/COFF.h
@@ -0,0 +1,115 @@
+//===- COFF.h - COFF object file implementation -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the COFFObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_COFF_H
+#define LLVM_OBJECT_COFF_H
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/COFF.h"
+#include "llvm/Support/Endian.h"
+
+namespace llvm {
+namespace object {
+
+struct coff_file_header {
+ support::ulittle16_t Machine;
+ support::ulittle16_t NumberOfSections;
+ support::ulittle32_t TimeDateStamp;
+ support::ulittle32_t PointerToSymbolTable;
+ support::ulittle32_t NumberOfSymbols;
+ support::ulittle16_t SizeOfOptionalHeader;
+ support::ulittle16_t Characteristics;
+};
+
+struct coff_symbol {
+ struct StringTableOffset {
+ support::ulittle32_t Zeroes;
+ support::ulittle32_t Offset;
+ };
+
+ union {
+ char ShortName[8];
+ StringTableOffset Offset;
+ } Name;
+
+ support::ulittle32_t Value;
+ support::little16_t SectionNumber;
+
+ struct {
+ support::ulittle8_t BaseType;
+ support::ulittle8_t ComplexType;
+ } Type;
+
+ support::ulittle8_t StorageClass;
+ support::ulittle8_t NumberOfAuxSymbols;
+};
+
+struct coff_section {
+ char Name[8];
+ support::ulittle32_t VirtualSize;
+ support::ulittle32_t VirtualAddress;
+ support::ulittle32_t SizeOfRawData;
+ support::ulittle32_t PointerToRawData;
+ support::ulittle32_t PointerToRelocations;
+ support::ulittle32_t PointerToLinenumbers;
+ support::ulittle16_t NumberOfRelocations;
+ support::ulittle16_t NumberOfLinenumbers;
+ support::ulittle32_t Characteristics;
+};
+
+class COFFObjectFile : public ObjectFile {
+private:
+ const coff_file_header *Header;
+ const coff_section *SectionTable;
+ const coff_symbol *SymbolTable;
+ const char *StringTable;
+ uint32_t StringTableSize;
+
+ error_code getSection(int32_t index,
+ const coff_section *&Res) const;
+ error_code getString(uint32_t offset, StringRef &Res) const;
+
+ const coff_symbol *toSymb(DataRefImpl Symb) const;
+ const coff_section *toSec(DataRefImpl Sec) const;
+
+protected:
+ virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const;
+ virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const;
+ virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const;
+
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const;
+
+public:
+ COFFObjectFile(MemoryBuffer *Object, error_code &ec);
+ virtual symbol_iterator begin_symbols() const;
+ virtual symbol_iterator end_symbols() const;
+ virtual section_iterator begin_sections() const;
+ virtual section_iterator end_sections() const;
+
+ virtual uint8_t getBytesInAddress() const;
+ virtual StringRef getFileFormatName() const;
+ virtual unsigned getArch() const;
+};
+
+}
+}
+
+#endif
diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h
new file mode 100644
index 0000000..fbaf71c
--- /dev/null
+++ b/include/llvm/Object/Error.h
@@ -0,0 +1,50 @@
+//===- Error.h - system_error extensions for Object -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This declares a new error_category for the Object library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_ERROR_H
+#define LLVM_OBJECT_ERROR_H
+
+#include "llvm/Support/system_error.h"
+
+namespace llvm {
+namespace object {
+
+const error_category &object_category();
+
+struct object_error {
+enum _ {
+ success = 0,
+ invalid_file_type,
+ parse_failed,
+ unexpected_eof
+};
+ _ v_;
+
+ object_error(_ v) : v_(v) {}
+ explicit object_error(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+inline error_code make_error_code(object_error e) {
+ return error_code(static_cast<int>(e), object_category());
+}
+
+} // end namespace object.
+
+template <> struct is_error_code_enum<object::object_error> : true_type { };
+
+template <> struct is_error_code_enum<object::object_error::_> : true_type { };
+
+} // end namespace llvm.
+
+#endif
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index eee9d44..f083d3c 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -14,15 +14,14 @@
#ifndef LLVM_OBJECT_OBJECT_FILE_H
#define LLVM_OBJECT_OBJECT_FILE_H
+#include "llvm/Object/Binary.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
#include <cstring>
namespace llvm {
-
-class MemoryBuffer;
-class StringRef;
-
namespace object {
class ObjectFile;
@@ -31,7 +30,7 @@ union DataRefImpl {
struct {
uint32_t a, b;
} d;
- intptr_t p;
+ uintptr_t p;
};
static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
@@ -40,6 +39,19 @@ static bool operator ==(const DataRefImpl &a, const DataRefImpl &b) {
return std::memcmp(&a, &b, sizeof(DataRefImpl)) == 0;
}
+class RelocationRef {
+ DataRefImpl RelocationPimpl;
+ const ObjectFile *OwningObject;
+
+public:
+ RelocationRef() : OwningObject(NULL) { std::memset(&RelocationPimpl, 0, sizeof(RelocationPimpl)); }
+ RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner);
+
+ bool operator==(const RelocationRef &Other) const;
+
+ error_code getNext(RelocationRef &Result);
+};
+
/// SymbolRef - This is a value type class that represents a single symbol in
/// the list of symbols in the object file.
class SymbolRef {
@@ -47,23 +59,24 @@ class SymbolRef {
const ObjectFile *OwningObject;
public:
+ SymbolRef() : OwningObject(NULL) { std::memset(&SymbolPimpl, 0, sizeof(SymbolPimpl)); }
SymbolRef(DataRefImpl SymbolP, const ObjectFile *Owner);
bool operator==(const SymbolRef &Other) const;
- SymbolRef getNext() const;
+ error_code getNext(SymbolRef &Result) const;
- StringRef getName() const;
- uint64_t getAddress() const;
- uint64_t getSize() const;
+ error_code getName(StringRef &Result) const;
+ error_code getAddress(uint64_t &Result) const;
+ error_code getSize(uint64_t &Result) const;
/// Returns the ascii char that should be displayed in a symbol table dump via
/// nm for this symbol.
- char getNMTypeChar() const;
+ error_code getNMTypeChar(char &Result) const;
/// Returns true for symbols that are internal to the object file format such
/// as section symbols.
- bool isInternal() const;
+ error_code isInternal(bool &Result) const;
};
/// SectionRef - This is a value type class that represents a single section in
@@ -73,19 +86,20 @@ class SectionRef {
const ObjectFile *OwningObject;
public:
+ SectionRef() : OwningObject(NULL) { std::memset(&SectionPimpl, 0, sizeof(SectionPimpl)); }
SectionRef(DataRefImpl SectionP, const ObjectFile *Owner);
bool operator==(const SectionRef &Other) const;
- SectionRef getNext() const;
+ error_code getNext(SectionRef &Result) const;
- StringRef getName() const;
- uint64_t getAddress() const;
- uint64_t getSize() const;
- StringRef getContents() const;
+ error_code getName(StringRef &Result) const;
+ error_code getAddress(uint64_t &Result) const;
+ error_code getSize(uint64_t &Result) const;
+ error_code getContents(StringRef &Result) const;
// FIXME: Move to the normalization layer when it's created.
- bool isText() const;
+ error_code isText(bool &Result) const;
};
const uint64_t UnknownAddressOrSize = ~0ULL;
@@ -93,38 +107,42 @@ const uint64_t UnknownAddressOrSize = ~0ULL;
/// ObjectFile - This class is the base class for all object file types.
/// Concrete instances of this object are created by createObjectFile, which
/// figure out which type to create.
-class ObjectFile {
+class ObjectFile : public Binary {
private:
ObjectFile(); // = delete
ObjectFile(const ObjectFile &other); // = delete
protected:
- MemoryBuffer *MapFile;
- const uint8_t *base;
+ ObjectFile(unsigned int Type, MemoryBuffer *source, error_code &ec);
- ObjectFile(MemoryBuffer *Object);
+ const uint8_t *base() const {
+ return reinterpret_cast<const uint8_t *>(Data->getBufferStart());
+ }
// These functions are for SymbolRef to call internally. The main goal of
// this is to allow SymbolRef::SymbolPimpl to point directly to the symbol
// entry in the memory mapped object file. SymbolPimpl cannot contain any
// virtual functions because then it could not point into the memory mapped
// file.
+ //
+ // Implementations assume that the DataRefImpl is valid and has not been
+ // modified externally. It's UB otherwise.
friend class SymbolRef;
- virtual SymbolRef getSymbolNext(DataRefImpl Symb) const = 0;
- virtual StringRef getSymbolName(DataRefImpl Symb) const = 0;
- virtual uint64_t getSymbolAddress(DataRefImpl Symb) const = 0;
- virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0;
- virtual char getSymbolNMTypeChar(DataRefImpl Symb) const = 0;
- virtual bool isSymbolInternal(DataRefImpl Symb) const = 0;
+ virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const = 0;
+ virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const = 0;
+ virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const =0;
+ virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const = 0;
+ virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const = 0;
+ virtual error_code isSymbolInternal(DataRefImpl Symb, bool &Res) const = 0;
// Same as above for SectionRef.
friend class SectionRef;
- virtual SectionRef getSectionNext(DataRefImpl Sec) const = 0;
- virtual StringRef getSectionName(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0;
- virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0;
- virtual StringRef getSectionContents(DataRefImpl Sec) const = 0;
- virtual bool isSectionText(DataRefImpl Sec) const = 0;
+ virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const = 0;
+ virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0;
+ virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const =0;
+ virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const = 0;
+ virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res)const=0;
+ virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0;
public:
@@ -147,8 +165,12 @@ public:
return !(*this == other);
}
- content_iterator& operator++() { // Preincrement
- Current = Current.getNext();
+ content_iterator& increment(error_code &err) {
+ content_type next;
+ if (error_code ec = Current.getNext(next))
+ err = ec;
+ else
+ Current = next;
return *this;
}
};
@@ -156,8 +178,6 @@ public:
typedef content_iterator<SymbolRef> symbol_iterator;
typedef content_iterator<SectionRef> section_iterator;
- virtual ~ObjectFile();
-
virtual symbol_iterator begin_symbols() const = 0;
virtual symbol_iterator end_symbols() const = 0;
@@ -171,8 +191,6 @@ public:
virtual StringRef getFileFormatName() const = 0;
virtual /* Triple::ArchType */ unsigned getArch() const = 0;
- StringRef getFilename() const;
-
/// @returns Pointer to ObjectFile subclass to handle this type of object.
/// @param ObjectPath The path to the object file. ObjectPath.isObject must
/// return true.
@@ -180,12 +198,16 @@ public:
static ObjectFile *createObjectFile(StringRef ObjectPath);
static ObjectFile *createObjectFile(MemoryBuffer *Object);
-private:
+ static inline bool classof(const Binary *v) {
+ return v->getType() >= isObject &&
+ v->getType() < lastObject;
+ }
+ static inline bool classof(const ObjectFile *v) { return true; }
+
+public:
static ObjectFile *createCOFFObjectFile(MemoryBuffer *Object);
static ObjectFile *createELFObjectFile(MemoryBuffer *Object);
static ObjectFile *createMachOObjectFile(MemoryBuffer *Object);
- static ObjectFile *createArchiveObjectFile(MemoryBuffer *Object);
- static ObjectFile *createLibObjectFile(MemoryBuffer *Object);
};
// Inline function definitions.
@@ -197,28 +219,28 @@ inline bool SymbolRef::operator==(const SymbolRef &Other) const {
return SymbolPimpl == Other.SymbolPimpl;
}
-inline SymbolRef SymbolRef::getNext() const {
- return OwningObject->getSymbolNext(SymbolPimpl);
+inline error_code SymbolRef::getNext(SymbolRef &Result) const {
+ return OwningObject->getSymbolNext(SymbolPimpl, Result);
}
-inline StringRef SymbolRef::getName() const {
- return OwningObject->getSymbolName(SymbolPimpl);
+inline error_code SymbolRef::getName(StringRef &Result) const {
+ return OwningObject->getSymbolName(SymbolPimpl, Result);
}
-inline uint64_t SymbolRef::getAddress() const {
- return OwningObject->getSymbolAddress(SymbolPimpl);
+inline error_code SymbolRef::getAddress(uint64_t &Result) const {
+ return OwningObject->getSymbolAddress(SymbolPimpl, Result);
}
-inline uint64_t SymbolRef::getSize() const {
- return OwningObject->getSymbolSize(SymbolPimpl);
+inline error_code SymbolRef::getSize(uint64_t &Result) const {
+ return OwningObject->getSymbolSize(SymbolPimpl, Result);
}
-inline char SymbolRef::getNMTypeChar() const {
- return OwningObject->getSymbolNMTypeChar(SymbolPimpl);
+inline error_code SymbolRef::getNMTypeChar(char &Result) const {
+ return OwningObject->getSymbolNMTypeChar(SymbolPimpl, Result);
}
-inline bool SymbolRef::isInternal() const {
- return OwningObject->isSymbolInternal(SymbolPimpl);
+inline error_code SymbolRef::isInternal(bool &Result) const {
+ return OwningObject->isSymbolInternal(SymbolPimpl, Result);
}
@@ -232,28 +254,28 @@ inline bool SectionRef::operator==(const SectionRef &Other) const {
return SectionPimpl == Other.SectionPimpl;
}
-inline SectionRef SectionRef::getNext() const {
- return OwningObject->getSectionNext(SectionPimpl);
+inline error_code SectionRef::getNext(SectionRef &Result) const {
+ return OwningObject->getSectionNext(SectionPimpl, Result);
}
-inline StringRef SectionRef::getName() const {
- return OwningObject->getSectionName(SectionPimpl);
+inline error_code SectionRef::getName(StringRef &Result) const {
+ return OwningObject->getSectionName(SectionPimpl, Result);
}
-inline uint64_t SectionRef::getAddress() const {
- return OwningObject->getSectionAddress(SectionPimpl);
+inline error_code SectionRef::getAddress(uint64_t &Result) const {
+ return OwningObject->getSectionAddress(SectionPimpl, Result);
}
-inline uint64_t SectionRef::getSize() const {
- return OwningObject->getSectionSize(SectionPimpl);
+inline error_code SectionRef::getSize(uint64_t &Result) const {
+ return OwningObject->getSectionSize(SectionPimpl, Result);
}
-inline StringRef SectionRef::getContents() const {
- return OwningObject->getSectionContents(SectionPimpl);
+inline error_code SectionRef::getContents(StringRef &Result) const {
+ return OwningObject->getSectionContents(SectionPimpl, Result);
}
-inline bool SectionRef::isText() const {
- return OwningObject->isSectionText(SectionPimpl);
+inline error_code SectionRef::isText(bool &Result) const {
+ return OwningObject->isSectionText(SectionPimpl, Result);
}
} // end namespace object
diff --git a/include/llvm/Support/BranchProbability.h b/include/llvm/Support/BranchProbability.h
index 7ba6491..c66d224 100644
--- a/include/llvm/Support/BranchProbability.h
+++ b/include/llvm/Support/BranchProbability.h
@@ -18,13 +18,17 @@
namespace llvm {
-class raw_ostream;
+template<class BlockT, class FunctionT, class BranchProbInfoT>
+class BlockFrequencyImpl;
class BranchProbabilityInfo;
class MachineBranchProbabilityInfo;
class MachineBasicBlock;
+class raw_ostream;
// This class represents Branch Probability as a non-negative fraction.
class BranchProbability {
+ template<class BlockT, class FunctionT, class BranchProbInfoT>
+ friend class BlockFrequencyImpl;
friend class BranchProbabilityInfo;
friend class MachineBranchProbabilityInfo;
friend class MachineBasicBlock;
@@ -38,6 +42,10 @@ class BranchProbability {
BranchProbability(uint32_t n, uint32_t d);
public:
+
+ uint32_t getNumerator() const { return N; }
+ uint32_t getDenominator() const { return D; }
+
raw_ostream &print(raw_ostream &OS) const;
void dump() const;
diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h
index 6a7c277..9459280 100644
--- a/include/llvm/Support/IRBuilder.h
+++ b/include/llvm/Support/IRBuilder.h
@@ -82,7 +82,7 @@ public:
InsertPt = I;
SetCurrentDebugLocation(I->getDebugLoc());
}
-
+
/// SetInsertPoint - This specifies that created instructions should be
/// inserted at the specified point.
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
@@ -90,6 +90,19 @@ public:
InsertPt = IP;
}
+ /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and
+ /// specify that created instructions should be inserted at this point.
+ void SetInsertPoint(Use &U) {
+ Instruction *UseInst = cast<Instruction>(U.getUser());
+ if (PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
+ BasicBlock *PredBB = Phi->getIncomingBlock(U);
+ assert(U != PredBB->getTerminator() && "critical edge not split");
+ SetInsertPoint(PredBB, PredBB->getTerminator());
+ return;
+ }
+ SetInsertPoint(UseInst);
+ }
+
/// SetCurrentDebugLocation - Set location information used by debugging
/// information.
void SetCurrentDebugLocation(const DebugLoc &L) {
@@ -110,7 +123,7 @@ public:
/// getCurrentFunctionReturnType - Get the return type of the current function
/// that we're emitting into.
const Type *getCurrentFunctionReturnType() const;
-
+
/// InsertPoint - A saved insertion point.
class InsertPoint {
BasicBlock *Block;
@@ -198,7 +211,7 @@ public:
ConstantInt *getInt64(uint64_t C) {
return ConstantInt::get(getInt64Ty(), C);
}
-
+
/// getInt - Get a constant integer value.
ConstantInt *getInt(const APInt &AI) {
return ConstantInt::get(Context, AI);
@@ -263,7 +276,7 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
}
-
+
CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0);
@@ -274,7 +287,7 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemCpy(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
}
-
+
CallInst *CreateMemCpy(Value *Dst, Value *Src, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0);
@@ -285,9 +298,9 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
}
-
+
CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
- bool isVolatile = false, MDNode *TBAATag = 0);
+ bool isVolatile = false, MDNode *TBAATag = 0);
/// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
/// isn't i8* it will be converted.
@@ -341,7 +354,13 @@ public:
SetInsertPoint(IP);
SetCurrentDebugLocation(IP->getDebugLoc());
}
-
+
+ explicit IRBuilder(Use &U)
+ : IRBuilderBase(U->getContext()), Folder() {
+ SetInsertPoint(U);
+ SetCurrentDebugLocation(cast<Instruction>(U.getUser())->getDebugLoc());
+ }
+
IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
: IRBuilderBase(TheBB->getContext()), Folder(F) {
SetInsertPoint(TheBB, IP);
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index bc8be89..4d7116b 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -26,11 +26,19 @@ class SubRegIndex {
string Namespace = "";
}
+// RegAltNameIndex - The alternate name set to use for register operands of
+// this register class when printing.
+class RegAltNameIndex {
+ string Namespace = "";
+}
+def NoRegAltName : RegAltNameIndex;
+
// Register - You should define one instance of this class for each register
// in the target machine. String n will become the "name" of the register.
-class Register<string n> {
+class Register<string n, list<string> altNames = []> {
string Namespace = "";
string AsmName = n;
+ list<string> AltNames = altNames;
// Aliases - A list of registers that this register overlaps with. A read or
// modification of this register can potentially read or modify the aliased
@@ -48,6 +56,10 @@ class Register<string n> {
// SubRegs.
list<SubRegIndex> SubRegIndices = [];
+ // RegAltNameIndices - The alternate name indices which are valid for this
+ // register.
+ list<RegAltNameIndex> RegAltNameIndices = [];
+
// CompositeIndices - Specify subreg indices that don't correspond directly to
// a register in SubRegs and are not inherited. The following formats are
// supported:
@@ -92,7 +104,7 @@ class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
// registers by register allocators.
//
class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
- dag regList> {
+ dag regList, RegAltNameIndex idx = NoRegAltName> {
string Namespace = namespace;
// RegType - Specify the list ValueType of the registers in this register
@@ -124,6 +136,11 @@ class RegisterClass<string namespace, list<ValueType> regTypes, int alignment,
//
dag MemberList = regList;
+ // AltNameIndex - The alternate register name to use when printing operands
+ // of this register class. Every register in the register class must have
+ // a valid alternate name for the given index.
+ RegAltNameIndex altNameIndex = idx;
+
// SubRegClasses - Specify the register class of subregisters as a list of
// dags: (RegClass SubRegIndex, SubRegindex, ...)
list<dag> SubRegClasses = [];
@@ -466,6 +483,24 @@ class Operand<ValueType ty> {
AsmOperandClass ParserMatchClass = ImmAsmOperand;
}
+class RegisterOperand<RegisterClass regclass, string pm = "printOperand"> {
+ // RegClass - The register class of the operand.
+ RegisterClass RegClass = regclass;
+ // PrintMethod - The target method to call to print register operands of
+ // this type. The method normally will just use an alt-name index to look
+ // up the name to print. Default to the generic printOperand().
+ string PrintMethod = pm;
+ // ParserMatchClass - The "match class" that operands of this type fit
+ // in. Match classes are used to define the order in which instructions are
+ // match, to ensure that which instructions gets matched is deterministic.
+ //
+ // The target specific parser must be able to classify an parsed operand into
+ // a unique class, which does not partially overlap with any other classes. It
+ // can match a subset of some other class, in which case the AsmOperandClass
+ // should declare the other operand as one of its super classes.
+ AsmOperandClass ParserMatchClass;
+}
+
def i1imm : Operand<i1>;
def i8imm : Operand<i8>;
def i16imm : Operand<i16>;
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
index abaed81..1a417a1 100644
--- a/include/llvm/Target/TargetAsmInfo.h
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -106,6 +106,10 @@ public:
int getSEHRegNum(unsigned RegNum) const {
return TRI->getSEHRegNum(RegNum);
}
+
+ int getCompactUnwindRegNum(unsigned RegNum) const {
+ return TRI->getCompactUnwindRegNum(RegNum);
+ }
};
}
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 418f3fe..70969eb 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -14,7 +14,7 @@
#ifndef LLVM_TARGET_TARGETINSTRINFO_H
#define LLVM_TARGET_TARGETINSTRINFO_H
-#include "llvm/Target/TargetInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
namespace llvm {
@@ -40,25 +40,20 @@ template<class T> class SmallVectorImpl;
///
/// TargetInstrInfo - Interface to description of machine instruction set
///
-class TargetInstrInfo {
- const TargetInstrDesc *Descriptors; // Raw array to allow static init'n
- unsigned NumOpcodes; // Number of entries in the desc array
-
+class TargetInstrInfo : public MCInstrInfo {
TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
public:
- TargetInstrInfo(const TargetInstrDesc *desc, unsigned NumOpcodes);
+ TargetInstrInfo(const MCInstrDesc *desc, unsigned NumOpcodes,
+ int CallFrameSetupOpcode = -1,
+ int CallFrameDestroyOpcode = -1);
virtual ~TargetInstrInfo();
- unsigned getNumOpcodes() const { return NumOpcodes; }
-
- /// get - Return the machine instruction descriptor that corresponds to the
- /// specified instruction opcode.
- ///
- const TargetInstrDesc &get(unsigned Opcode) const {
- assert(Opcode < NumOpcodes && "Invalid opcode!");
- return Descriptors[Opcode];
- }
+ /// getRegClass - Givem a machine instruction descriptor, returns the register
+ /// class constraint for OpNum, or NULL.
+ const TargetRegisterClass *getRegClass(const MCInstrDesc &TID,
+ unsigned OpNum,
+ const TargetRegisterInfo *TRI) const;
/// isTriviallyReMaterializable - Return true if the instruction is trivially
/// rematerializable, meaning it has no side effects and requires no operands
@@ -93,6 +88,15 @@ private:
AliasAnalysis *AA) const;
public:
+ /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
+ /// frame setup/destroy instructions if they exist (-1 otherwise). Some
+ /// targets use pseudo instructions in order to abstract away the difference
+ /// between operating with a frame pointer and operating without, through the
+ /// use of these two instructions.
+ ///
+ int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
+ int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+
/// isCoalescableExtInstr - Return true if the instruction is a "coalescable"
/// extension instruction. That is, it's like a copy where it's legal for the
/// source to overlap the destination. e.g. X86::MOVSX64rr32. If this returns
@@ -663,6 +667,9 @@ public:
virtual
bool hasLowDefLatency(const InstrItineraryData *ItinData,
const MachineInstr *DefMI, unsigned DefIdx) const;
+
+private:
+ int CallFrameSetupOpcode, CallFrameDestroyOpcode;
};
/// TargetInstrInfoImpl - This is the default implementation of
@@ -671,8 +678,11 @@ public:
/// libcodegen, not in libtarget.
class TargetInstrInfoImpl : public TargetInstrInfo {
protected:
- TargetInstrInfoImpl(const TargetInstrDesc *desc, unsigned NumOpcodes)
- : TargetInstrInfo(desc, NumOpcodes) {}
+ TargetInstrInfoImpl(const MCInstrDesc *desc, unsigned NumOpcodes,
+ int CallFrameSetupOpcode = -1,
+ int CallFrameDestroyOpcode = -1)
+ : TargetInstrInfo(desc, NumOpcodes,
+ CallFrameSetupOpcode, CallFrameDestroyOpcode) {}
public:
virtual void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst,
MachineBasicBlock *NewDest) const;
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index c3f5f2b..f684163 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -1421,13 +1421,6 @@ public:
/// is for this target.
virtual ConstraintType getConstraintType(const std::string &Constraint) const;
- /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
- /// return a list of registers that can be used to satisfy the constraint.
- /// This should only be used for C_RegisterClass constraints.
- virtual std::vector<unsigned>
- getRegClassForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
-
/// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
/// {edx}), return the register number and the register class for the
/// register.
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 78f770c..6544ce2 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,29 +14,29 @@
#ifndef LLVM_TARGET_TARGETMACHINE_H
#define LLVM_TARGET_TARGETMACHINE_H
-#include "llvm/Target/TargetInstrItineraries.h"
#include <cassert>
#include <string>
namespace llvm {
-class Target;
+class InstrItineraryData;
+class JITCodeEmitter;
class MCAsmInfo;
+class MCContext;
+class Pass;
+class PassManager;
+class PassManagerBase;
+class Target;
class TargetData;
-class TargetSubtarget;
+class TargetELFWriterInfo;
+class TargetFrameLowering;
class TargetInstrInfo;
class TargetIntrinsicInfo;
class TargetJITInfo;
class TargetLowering;
-class TargetSelectionDAGInfo;
-class TargetFrameLowering;
-class JITCodeEmitter;
-class MCContext;
class TargetRegisterInfo;
-class PassManagerBase;
-class PassManager;
-class Pass;
-class TargetELFWriterInfo;
+class TargetSelectionDAGInfo;
+class TargetSubtarget;
class formatted_raw_ostream;
class raw_ostream;
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index beed039..55d50d9 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -133,8 +133,8 @@ namespace llvm {
/// as their parent function, etc.), using an alternate ABI if necessary.
extern bool GuaranteedTailCallOpt;
- /// StackAlignment - Override default stack alignment for target.
- extern unsigned StackAlignment;
+ /// StackAlignmentOverride - Override default stack alignment for target.
+ extern unsigned StackAlignmentOverride;
/// RealignStack - This flag indicates whether the stack should be
/// automatically realigned, if needed.
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 840b048..3f28f6c 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -16,6 +16,7 @@
#ifndef LLVM_TARGET_TARGETREGISTERINFO_H
#define LLVM_TARGET_TARGETREGISTERINFO_H
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/ADT/ArrayRef.h"
@@ -27,30 +28,10 @@ namespace llvm {
class BitVector;
class MachineFunction;
-class MachineMove;
class RegScavenger;
template<class T> class SmallVectorImpl;
class raw_ostream;
-/// TargetRegisterDesc - This record contains all of the information known about
-/// a particular register. The Overlaps field contains a pointer to a zero
-/// terminated array of registers that this register aliases, starting with
-/// itself. This is needed for architectures like X86 which have AL alias AX
-/// alias EAX. The SubRegs field is a zero terminated array of registers that
-/// are sub-registers of the specific register, e.g. AL, AH are sub-registers of
-/// AX. The SuperRegs field is a zero terminated array of registers that are
-/// super-registers of the specific register, e.g. RAX, EAX, are super-registers
-/// of AX.
-///
-struct TargetRegisterDesc {
- const char *Name; // Printable name for the reg (for debugging)
- const unsigned *Overlaps; // Overlapping registers, described above
- const unsigned *SubRegs; // Sub-register set, described above
- const unsigned *SuperRegs; // Super-register set, described above
- unsigned CostPerUse; // Extra cost of instructions using register.
- bool inAllocatableClass; // Register belongs to an allocatable regclass.
-};
-
class TargetRegisterClass {
public:
typedef const unsigned* iterator;
@@ -274,6 +255,12 @@ public:
bool isAllocatable() const { return Allocatable; }
};
+/// TargetRegisterInfoDesc - Extra information, not in MCRegisterDesc, about
+/// registers. These are used by codegen, not by MC.
+struct TargetRegisterInfoDesc {
+ unsigned CostPerUse; // Extra cost of instructions using register.
+ bool inAllocatableClass; // Register belongs to an allocatable regclass.
+};
/// TargetRegisterInfo base class - We assume that the target defines a static
/// array of TargetRegisterDesc objects that represent all of the machine
@@ -281,25 +268,19 @@ public:
/// to this array so that we can turn register number into a register
/// descriptor.
///
-class TargetRegisterInfo {
+class TargetRegisterInfo : public MCRegisterInfo {
public:
typedef const TargetRegisterClass * const * regclass_iterator;
private:
- const TargetRegisterDesc *Desc; // Pointer to the descriptor array
+ const TargetRegisterInfoDesc *InfoDesc; // Extra desc array for codegen
const char *const *SubRegIndexNames; // Names of subreg indexes.
- unsigned NumRegs; // Number of entries in the array
-
regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
- int CallFrameSetupOpcode, CallFrameDestroyOpcode;
-
protected:
- TargetRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
+ TargetRegisterInfo(const TargetRegisterInfoDesc *ID,
regclass_iterator RegClassBegin,
regclass_iterator RegClassEnd,
- const char *const *subregindexnames,
- int CallFrameSetupOpcode = -1,
- int CallFrameDestroyOpcode = -1);
+ const char *const *subregindexnames);
virtual ~TargetRegisterInfo();
public:
@@ -379,71 +360,16 @@ public:
BitVector getAllocatableSet(const MachineFunction &MF,
const TargetRegisterClass *RC = NULL) const;
- const TargetRegisterDesc &operator[](unsigned RegNo) const {
- assert(RegNo < NumRegs &&
- "Attempting to access record for invalid register number!");
- return Desc[RegNo];
- }
-
- /// Provide a get method, equivalent to [], but more useful if we have a
- /// pointer to this object.
- ///
- const TargetRegisterDesc &get(unsigned RegNo) const {
- return operator[](RegNo);
- }
-
- /// getAliasSet - Return the set of registers aliased by the specified
- /// register, or a null list of there are none. The list returned is zero
- /// terminated.
- ///
- const unsigned *getAliasSet(unsigned RegNo) const {
- // The Overlaps set always begins with Reg itself.
- return get(RegNo).Overlaps + 1;
- }
-
- /// getOverlaps - Return a list of registers that overlap Reg, including
- /// itself. This is the same as the alias set except Reg is included in the
- /// list.
- /// These are exactly the registers in { x | regsOverlap(x, Reg) }.
- ///
- const unsigned *getOverlaps(unsigned RegNo) const {
- return get(RegNo).Overlaps;
- }
-
- /// getSubRegisters - Return the list of registers that are sub-registers of
- /// the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::RAX's sub-register list is EAX, AX, AL, AH.
- ///
- const unsigned *getSubRegisters(unsigned RegNo) const {
- return get(RegNo).SubRegs;
- }
-
- /// getSuperRegisters - Return the list of registers that are super-registers
- /// of the specified register, or a null list of there are none. The list
- /// returned is zero terminated and sorted according to super-sub register
- /// relations. e.g. X86::AL's super-register list is AX, EAX, RAX.
- ///
- const unsigned *getSuperRegisters(unsigned RegNo) const {
- return get(RegNo).SuperRegs;
- }
-
- /// getName - Return the human-readable symbolic target-specific name for the
- /// specified physical register.
- const char *getName(unsigned RegNo) const {
- return get(RegNo).Name;
- }
-
/// getCostPerUse - Return the additional cost of using this register instead
/// of other registers in its class.
unsigned getCostPerUse(unsigned RegNo) const {
- return get(RegNo).CostPerUse;
+ return InfoDesc[RegNo].CostPerUse;
}
- /// getNumRegs - Return the number of registers this target has (useful for
- /// sizing arrays holding per register information)
- unsigned getNumRegs() const {
- return NumRegs;
+ /// isInAllocatableClass - Return true if the register is in the allocation
+ /// of any register class.
+ bool isInAllocatableClass(unsigned RegNo) const {
+ return InfoDesc[RegNo].inAllocatableClass;
}
/// getSubRegIndexName - Return the human-readable symbolic target-specific
@@ -566,7 +492,7 @@ public:
}
/// getRegClass - Returns the register class associated with the enumeration
- /// value. See class TargetOperandInfo.
+ /// value. See class MCOperandInfo.
const TargetRegisterClass *getRegClass(unsigned i) const {
assert(i < getNumRegClasses() && "Register Class ID out of range");
return RegClassBegin[i];
@@ -732,15 +658,6 @@ public:
return false; // Must return a value in order to compile with VS 2005
}
- /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
- /// frame setup/destroy instructions if they exist (-1 otherwise). Some
- /// targets use pseudo instructions in order to abstract away the difference
- /// between operating with a frame pointer and operating without, through the
- /// use of these two instructions.
- ///
- int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
- int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
-
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
/// code insertion to eliminate call frame setup and destroy pseudo
/// instructions (but only if the Target is using them). It is responsible
@@ -752,9 +669,6 @@ public:
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
- assert(getCallFrameSetupOpcode()== -1 && getCallFrameDestroyOpcode()== -1 &&
- "eliminateCallFramePseudoInstr must be implemented if using"
- " call frame setup/destroy pseudo instructions!");
assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
}
@@ -806,6 +720,12 @@ public:
virtual int getSEHRegNum(unsigned i) const {
return i;
}
+
+ /// getCompactUnwindRegNum - This function maps the register to the number for
+ /// compact unwind encoding. Return -1 if the register isn't valid.
+ virtual int getCompactUnwindRegNum(unsigned) const {
+ return -1;
+ }
};
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index a464822..8d44f66 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -33,6 +33,8 @@ namespace llvm {
class MCContext;
class MCDisassembler;
class MCInstPrinter;
+ class MCInstrInfo;
+ class MCRegisterInfo;
class MCStreamer;
class TargetAsmBackend;
class TargetAsmLexer;
@@ -64,9 +66,12 @@ namespace llvm {
typedef unsigned (*TripleMatchQualityFnTy)(const std::string &TT);
typedef MCAsmInfo *(*AsmInfoCtorFnTy)(const Target &T,
- StringRef TT);
+ StringRef TT);
+ typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
+ typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(void);
typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
const std::string &TT,
+ const std::string &CPU,
const std::string &Features);
typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
MCStreamer &Streamer);
@@ -120,8 +125,18 @@ namespace llvm {
/// HasJIT - Whether this target supports the JIT.
bool HasJIT;
+ /// AsmInfoCtorFn - Constructor function for this target's MCAsmInfo, if
+ /// registered.
AsmInfoCtorFnTy AsmInfoCtorFn;
+ /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
+ /// if registered.
+ MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
+
+ /// MCRegInfoCtorFn - Constructor function for this target's MCRegisterInfo,
+ /// if registered.
+ MCRegInfoCtorFnTy MCRegInfoCtorFn;
+
/// TargetMachineCtorFn - Construction function for this target's
/// TargetMachine, if registered.
TargetMachineCtorTy TargetMachineCtorFn;
@@ -231,6 +246,22 @@ namespace llvm {
return AsmInfoCtorFn(*this, Triple);
}
+ /// createMCInstrInfo - Create a MCInstrInfo implementation.
+ ///
+ MCInstrInfo *createMCInstrInfo() const {
+ if (!MCInstrInfoCtorFn)
+ return 0;
+ return MCInstrInfoCtorFn();
+ }
+
+ /// createMCRegInfo - Create a MCRegisterInfo implementation.
+ ///
+ MCRegisterInfo *createMCRegInfo() const {
+ if (!MCRegInfoCtorFn)
+ return 0;
+ return MCRegInfoCtorFn();
+ }
+
/// createTargetMachine - Create a target specific machine implementation
/// for the specified \arg Triple.
///
@@ -239,10 +270,11 @@ namespace llvm {
/// either the target triple from the module, or the target triple of the
/// host if that does not exist.
TargetMachine *createTargetMachine(const std::string &Triple,
+ const std::string &CPU,
const std::string &Features) const {
if (!TargetMachineCtorFn)
return 0;
- return TargetMachineCtorFn(*this, Triple, Features);
+ return TargetMachineCtorFn(*this, Triple, CPU, Features);
}
/// createAsmBackend - Create a target specific assembly parser.
@@ -444,6 +476,36 @@ namespace llvm {
T.AsmInfoCtorFn = Fn;
}
+ /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCInstrInfo for the target.
+ static void RegisterMCInstrInfo(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCInstrInfoCtorFn)
+ T.MCInstrInfoCtorFn = Fn;
+ }
+
+ /// RegisterMCRegInfo - Register a MCRegisterInfo implementation for the
+ /// given target.
+ ///
+ /// Clients are responsible for ensuring that registration doesn't occur
+ /// while another thread is attempting to access the registry. Typically
+ /// this is done by initializing all targets at program startup.
+ ///
+ /// @param T - The target being registered.
+ /// @param Fn - A function to construct a MCRegisterInfo for the target.
+ static void RegisterMCRegInfo(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ // Ignore duplicate registration.
+ if (!T.MCRegInfoCtorFn)
+ T.MCRegInfoCtorFn = Fn;
+ }
+
/// RegisterTargetMachine - Register a TargetMachine implementation for the
/// given target.
///
@@ -654,6 +716,71 @@ namespace llvm {
}
};
+ /// RegisterMCInstrInfo - Helper template for registering a target instruction
+ /// info implementation. This invokes the static "Create" method on the class
+ /// to actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfo<FooMCInstrInfo> X(TheFooTarget);
+ /// }
+ template<class MCInstrInfoImpl>
+ struct RegisterMCInstrInfo {
+ RegisterMCInstrInfo(Target &T) {
+ TargetRegistry::RegisterMCInstrInfo(T, &Allocator);
+ }
+ private:
+ static MCInstrInfo *Allocator() {
+ return new MCInstrInfoImpl();
+ }
+ };
+
+ /// RegisterMCInstrInfoFn - Helper template for registering a target
+ /// instruction info implementation. This invokes the specified function to
+ /// do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCInstrInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCInstrInfoFn {
+ RegisterMCInstrInfoFn(Target &T, Target::MCInstrInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCInstrInfo(T, Fn);
+ }
+ };
+
+ /// RegisterMCRegInfo - Helper template for registering a target register info
+ /// implementation. This invokes the static "Create" method on the class to
+ /// actually do the construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfo<FooMCRegInfo> X(TheFooTarget);
+ /// }
+ template<class MCRegisterInfoImpl>
+ struct RegisterMCRegInfo {
+ RegisterMCRegInfo(Target &T) {
+ TargetRegistry::RegisterMCRegInfo(T, &Allocator);
+ }
+ private:
+ static MCRegisterInfo *Allocator() {
+ return new MCRegisterInfoImpl();
+ }
+ };
+
+ /// RegisterMCRegInfoFn - Helper template for registering a target register
+ /// info implementation. This invokes the specified function to do the
+ /// construction. Usage:
+ ///
+ /// extern "C" void LLVMInitializeFooTarget() {
+ /// extern Target TheFooTarget;
+ /// RegisterMCRegInfoFn X(TheFooTarget, TheFunction);
+ /// }
+ struct RegisterMCRegInfoFn {
+ RegisterMCRegInfoFn(Target &T, Target::MCRegInfoCtorFnTy Fn) {
+ TargetRegistry::RegisterMCRegInfo(T, Fn);
+ }
+ };
/// RegisterTargetMachine - Helper template for registering a target machine
/// implementation, for use in the target machine initialization
@@ -671,8 +798,9 @@ namespace llvm {
private:
static TargetMachine *Allocator(const Target &T, const std::string &TT,
+ const std::string &CPU,
const std::string &FS) {
- return new TargetMachineImpl(T, TT, FS);
+ return new TargetMachineImpl(T, TT, CPU, FS);
}
};