aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
committerStephen Hines <srhines@google.com>2013-03-05 23:27:24 -0800
commit5adb136be579e8fff3734461580cb34d1d2983b8 (patch)
treebff1a422e9c9789df563aaf9a7e91e63e8ec0384 /include/llvm
parent227a4a4ade38716ba9eb3205f48b52910f3b955e (diff)
parentb3201c5cf1e183d840f7c99ff779d57f1549d8e5 (diff)
downloadexternal_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.zip
external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.gz
external_llvm-5adb136be579e8fff3734461580cb34d1d2983b8.tar.bz2
Merge commit 'b3201c5cf1e183d840f7c99ff779d57f1549d8e5' into merge_20130226
Conflicts: include/llvm/Support/ELF.h lib/Support/DeltaAlgorithm.cpp Change-Id: I24a4fbce62eb39d924efee3c687b55e1e17b30cd
Diffstat (limited to 'include/llvm')
-rw-r--r--include/llvm/ADT/APFloat.h12
-rw-r--r--include/llvm/ADT/APInt.h61
-rw-r--r--include/llvm/ADT/APSInt.h4
-rw-r--r--include/llvm/ADT/ArrayRef.h29
-rw-r--r--include/llvm/ADT/DenseMap.h19
-rw-r--r--include/llvm/ADT/ImmutableIntervalMap.h4
-rw-r--r--include/llvm/ADT/ImmutableList.h4
-rw-r--r--include/llvm/ADT/ImmutableMap.h15
-rw-r--r--include/llvm/ADT/ImmutableSet.h31
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h6
-rw-r--r--include/llvm/ADT/MapVector.h25
-rw-r--r--include/llvm/ADT/None.h27
-rw-r--r--include/llvm/ADT/NullablePtr.h4
-rw-r--r--include/llvm/ADT/Optional.h115
-rw-r--r--include/llvm/ADT/OwningPtr.h4
-rw-r--r--include/llvm/ADT/PriorityQueue.h4
-rw-r--r--include/llvm/ADT/SmallString.h2
-rw-r--r--include/llvm/ADT/SmallVector.h4
-rw-r--r--include/llvm/ADT/SparseMultiSet.h526
-rw-r--r--include/llvm/ADT/StringExtras.h11
-rw-r--r--include/llvm/ADT/StringMap.h6
-rw-r--r--include/llvm/ADT/StringRef.h8
-rw-r--r--include/llvm/ADT/Triple.h9
-rw-r--r--include/llvm/ADT/VariadicFunction.h6
-rw-r--r--include/llvm/ADT/ilist.h12
-rw-r--r--include/llvm/ADT/ilist_node.h4
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h9
-rw-r--r--include/llvm/Analysis/CallGraphSCCPass.h4
-rw-r--r--include/llvm/Analysis/CallPrinter.h27
-rw-r--r--include/llvm/Analysis/CodeMetrics.h137
-rw-r--r--include/llvm/Analysis/DOTGraphTraitsPass.h113
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h4
-rw-r--r--include/llvm/Analysis/InlineCost.h221
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h13
-rw-r--r--include/llvm/Analysis/Interval.h4
-rw-r--r--include/llvm/Analysis/IntervalIterator.h4
-rw-r--r--include/llvm/Analysis/IntervalPartition.h4
-rw-r--r--include/llvm/Analysis/LibCallAliasAnalysis.h4
-rw-r--r--include/llvm/Analysis/LoopInfo.h22
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h5
-rw-r--r--include/llvm/Analysis/LoopIterator.h5
-rw-r--r--include/llvm/Analysis/LoopPass.h5
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h2
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h78
-rw-r--r--include/llvm/Analysis/PathNumbering.h4
-rw-r--r--include/llvm/Analysis/PathProfileInfo.h4
-rw-r--r--include/llvm/Analysis/PostDominators.h4
-rw-r--r--include/llvm/Analysis/RegionInfo.h4
-rw-r--r--include/llvm/Analysis/RegionIterator.h4
-rw-r--r--include/llvm/Analysis/RegionPass.h4
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h8
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h149
-rw-r--r--include/llvm/Analysis/ScalarEvolutionNormalization.h4
-rw-r--r--include/llvm/Analysis/SparsePropagation.h6
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h136
-rw-r--r--include/llvm/Analysis/Trace.h2
-rw-r--r--include/llvm/Analysis/ValueTracking.h9
-rw-r--r--include/llvm/Assembly/PrintModulePass.h6
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h486
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h4
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h15
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h4
-rw-r--r--include/llvm/CodeGen/Analysis.h3
-rw-r--r--include/llvm/CodeGen/CommandFlags.h4
-rw-r--r--include/llvm/CodeGen/FastISel.h15
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h5
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h3
-rw-r--r--include/llvm/CodeGen/JITCodeEmitter.h3
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h4
-rw-r--r--include/llvm/CodeGen/LexicalScopes.h8
-rw-r--r--include/llvm/CodeGen/LiveInterval.h68
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h47
-rw-r--r--include/llvm/CodeGen/LiveIntervalUnion.h6
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h4
-rw-r--r--include/llvm/CodeGen/MachORelocation.h6
-rw-r--r--include/llvm/CodeGen/MachineCodeInfo.h4
-rw-r--r--include/llvm/CodeGen/MachineDominators.h68
-rw-r--r--include/llvm/CodeGen/MachineFunction.h14
-rw-r--r--include/llvm/CodeGen/MachineFunctionAnalysis.h6
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h4
-rw-r--r--include/llvm/CodeGen/MachineInstr.h18
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h7
-rw-r--r--include/llvm/CodeGen/MachineInstrBundle.h22
-rw-r--r--include/llvm/CodeGen/MachineLoopInfo.h4
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h1
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h21
-rw-r--r--include/llvm/CodeGen/MachineScheduler.h43
-rw-r--r--include/llvm/CodeGen/MachineTraceMetrics.h350
-rw-r--r--include/llvm/CodeGen/PBQP/Math.h2
-rw-r--r--include/llvm/CodeGen/Passes.h18
-rw-r--r--include/llvm/CodeGen/RegAllocRegistry.h4
-rw-r--r--include/llvm/CodeGen/RegisterClassInfo.h22
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h4
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h4
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h5
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h24
-rw-r--r--include/llvm/CodeGen/ScheduleDAGInstrs.h59
-rw-r--r--include/llvm/CodeGen/ScheduleDFS.h76
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h20
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h6
-rw-r--r--include/llvm/CodeGen/SlotIndexes.h35
-rw-r--r--include/llvm/CodeGen/TargetSchedule.h7
-rw-r--r--include/llvm/CodeGen/ValueTypes.h2
-rw-r--r--include/llvm/Config/config.h.cmake20
-rw-r--r--include/llvm/Config/config.h.in17
-rw-r--r--include/llvm/Config/llvm-config.h.cmake3
-rw-r--r--include/llvm/DIBuilder.h95
-rw-r--r--include/llvm/DebugInfo.h39
-rw-r--r--include/llvm/DebugInfo/DIContext.h24
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h4
-rw-r--r--include/llvm/ExecutionEngine/GenericValue.h4
-rw-r--r--include/llvm/ExecutionEngine/Interpreter.h4
-rw-r--r--include/llvm/ExecutionEngine/JIT.h4
-rw-r--r--include/llvm/ExecutionEngine/JITEventListener.h6
-rw-r--r--include/llvm/ExecutionEngine/JITMemoryManager.h4
-rw-r--r--include/llvm/ExecutionEngine/MCJIT.h4
-rw-r--r--include/llvm/ExecutionEngine/OProfileWrapper.h6
-rw-r--r--include/llvm/ExecutionEngine/ObjectImage.h2
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h4
-rw-r--r--include/llvm/ExecutionEngine/SectionMemoryManager.h4
-rw-r--r--include/llvm/GVMaterializer.h4
-rw-r--r--include/llvm/IR/Argument.h75
-rw-r--r--include/llvm/IR/Attributes.h455
-rw-r--r--include/llvm/IR/BasicBlock.h188
-rw-r--r--include/llvm/IR/CallingConv.h4
-rw-r--r--include/llvm/IR/Constant.h7
-rw-r--r--include/llvm/IR/Constants.h4
-rw-r--r--include/llvm/IR/DataLayout.h10
-rw-r--r--include/llvm/IR/DerivedTypes.h4
-rw-r--r--include/llvm/IR/Function.h60
-rw-r--r--include/llvm/IR/GlobalAlias.h4
-rw-r--r--include/llvm/IR/GlobalValue.h4
-rw-r--r--include/llvm/IR/GlobalVariable.h43
-rw-r--r--include/llvm/IR/IRBuilder.h265
-rw-r--r--include/llvm/IR/InlineAsm.h4
-rw-r--r--include/llvm/IR/InstrTypes.h6
-rw-r--r--include/llvm/IR/Instruction.h12
-rw-r--r--include/llvm/IR/Instructions.h22
-rw-r--r--include/llvm/IR/IntrinsicInst.h4
-rw-r--r--include/llvm/IR/Intrinsics.h6
-rw-r--r--include/llvm/IR/Intrinsics.td1
-rw-r--r--include/llvm/IR/IntrinsicsNVVM.td28
-rw-r--r--include/llvm/IR/LLVMContext.h50
-rw-r--r--include/llvm/IR/MDBuilder.h267
-rw-r--r--include/llvm/IR/Metadata.h46
-rw-r--r--include/llvm/IR/Module.h60
-rw-r--r--include/llvm/IR/OperandTraits.h4
-rw-r--r--include/llvm/IR/Operator.h8
-rw-r--r--include/llvm/IR/SymbolTableListTraits.h4
-rw-r--r--include/llvm/IR/Type.h18
-rw-r--r--include/llvm/IR/TypeBuilder.h4
-rw-r--r--include/llvm/IR/Use.h5
-rw-r--r--include/llvm/IR/User.h4
-rw-r--r--include/llvm/IR/Value.h4
-rw-r--r--include/llvm/IR/ValueSymbolTable.h4
-rw-r--r--include/llvm/InitializePasses.h8
-rw-r--r--include/llvm/LinkAllIR.h (renamed from include/llvm/LinkAllVMCore.h)6
-rw-r--r--include/llvm/LinkAllPasses.h5
-rw-r--r--include/llvm/Linker.h106
-rw-r--r--include/llvm/MC/MCAsmInfo.h17
-rw-r--r--include/llvm/MC/MCAsmInfoCOFF.h6
-rw-r--r--include/llvm/MC/MCAsmInfoDarwin.h6
-rw-r--r--include/llvm/MC/MCAsmLayout.h7
-rw-r--r--include/llvm/MC/MCAssembler.h118
-rw-r--r--include/llvm/MC/MCContext.h30
-rw-r--r--include/llvm/MC/MCDisassembler.h4
-rw-r--r--include/llvm/MC/MCDwarf.h27
-rw-r--r--include/llvm/MC/MCELF.h2
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h1
-rw-r--r--include/llvm/MC/MCELFStreamer.h26
-rw-r--r--include/llvm/MC/MCExpr.h2
-rw-r--r--include/llvm/MC/MCFixedLenDisassembler.h4
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h2
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h8
-rw-r--r--include/llvm/MC/MCObjectStreamer.h12
-rw-r--r--include/llvm/MC/MCObjectWriter.h12
-rw-r--r--include/llvm/MC/MCParser/AsmCond.h4
-rw-r--r--include/llvm/MC/MCParser/AsmLexer.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h4
-rw-r--r--include/llvm/MC/MCParser/MCAsmParser.h57
-rw-r--r--include/llvm/MC/MCParser/MCAsmParserExtension.h4
-rw-r--r--include/llvm/MC/MCParser/MCParsedAsmOperand.h8
-rw-r--r--include/llvm/MC/MCSchedule.h23
-rw-r--r--include/llvm/MC/MCStreamer.h43
-rw-r--r--include/llvm/MC/MCTargetAsmParser.h10
-rw-r--r--include/llvm/Object/Archive.h98
-rw-r--r--include/llvm/Object/Binary.h8
-rw-r--r--include/llvm/Object/ELF.h1252
-rw-r--r--include/llvm/Object/MachOFormat.h16
-rw-r--r--include/llvm/Object/MachOObject.h3
-rw-r--r--include/llvm/Object/ObjectFile.h4
-rw-r--r--include/llvm/Object/RelocVisitor.h73
-rw-r--r--include/llvm/Option/Arg.h4
-rw-r--r--include/llvm/Option/ArgList.h4
-rw-r--r--include/llvm/Option/OptSpecifier.h6
-rw-r--r--include/llvm/Option/OptTable.h4
-rw-r--r--include/llvm/Option/Option.h4
-rw-r--r--include/llvm/PassAnalysisSupport.h4
-rw-r--r--include/llvm/PassManagers.h7
-rw-r--r--include/llvm/PassSupport.h4
-rw-r--r--include/llvm/Support/AlignOf.h23
-rw-r--r--include/llvm/Support/ArrayRecycler.h4
-rw-r--r--include/llvm/Support/Atomic.h4
-rw-r--r--include/llvm/Support/COFF.h4
-rw-r--r--include/llvm/Support/Casting.h52
-rw-r--r--include/llvm/Support/CommandLine.h6
-rw-r--r--include/llvm/Support/Compiler.h106
-rw-r--r--include/llvm/Support/ConstantRange.h4
-rw-r--r--include/llvm/Support/ConvertUTF.h228
-rw-r--r--include/llvm/Support/DOTGraphTraits.h5
-rw-r--r--include/llvm/Support/DataExtractor.h20
-rw-r--r--include/llvm/Support/DataStream.h4
-rw-r--r--include/llvm/Support/DebugLoc.h2
-rw-r--r--include/llvm/Support/Dwarf.h13
-rw-r--r--include/llvm/Support/DynamicLibrary.h4
-rw-r--r--include/llvm/Support/ELF.h181
-rw-r--r--include/llvm/Support/Errno.h4
-rw-r--r--include/llvm/Support/ErrorOr.h488
-rw-r--r--include/llvm/Support/FEnv.h4
-rw-r--r--include/llvm/Support/FileSystem.h4
-rw-r--r--include/llvm/Support/GCOV.h4
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h4
-rw-r--r--include/llvm/Support/GraphWriter.h12
-rw-r--r--include/llvm/Support/Host.h8
-rw-r--r--include/llvm/Support/IncludeFile.h4
-rw-r--r--include/llvm/Support/IntegersSubset.h6
-rw-r--r--include/llvm/Support/IntegersSubsetMapping.h6
-rw-r--r--include/llvm/Support/LEB128.h4
-rw-r--r--include/llvm/Support/Locale.h6
-rw-r--r--include/llvm/Support/LockFileManager.h1
-rw-r--r--include/llvm/Support/MathExtras.h6
-rw-r--r--include/llvm/Support/Memory.h4
-rw-r--r--include/llvm/Support/MemoryObject.h4
-rw-r--r--include/llvm/Support/Mutex.h4
-rw-r--r--include/llvm/Support/PassNameParser.h4
-rw-r--r--include/llvm/Support/PathV1.h4
-rw-r--r--include/llvm/Support/Process.h4
-rw-r--r--include/llvm/Support/Program.h4
-rw-r--r--include/llvm/Support/RegistryParser.h6
-rw-r--r--include/llvm/Support/SMLoc.h4
-rw-r--r--include/llvm/Support/SaveAndRestore.h4
-rw-r--r--include/llvm/Support/Signals.h8
-rw-r--r--include/llvm/Support/Solaris.h4
-rw-r--r--include/llvm/Support/SourceMgr.h74
-rw-r--r--include/llvm/Support/StreamableMemoryObject.h4
-rw-r--r--include/llvm/Support/SwapByteOrder.h4
-rw-r--r--include/llvm/Support/ThreadLocal.h4
-rw-r--r--include/llvm/Support/Threading.h4
-rw-r--r--include/llvm/Support/TimeValue.h19
-rw-r--r--include/llvm/Support/Timer.h9
-rw-r--r--include/llvm/Support/ToolOutputFile.h4
-rw-r--r--include/llvm/Support/YAMLParser.h4
-rw-r--r--include/llvm/Support/YAMLTraits.h40
-rw-r--r--include/llvm/Support/raw_ostream.h1
-rw-r--r--include/llvm/Support/system_error.h4
-rw-r--r--include/llvm/Support/type_traits.h4
-rw-r--r--include/llvm/TableGen/Record.h35
-rw-r--r--include/llvm/TableGen/StringMatcher.h4
-rw-r--r--include/llvm/Target/CostTable.h64
-rw-r--r--include/llvm/Target/Mangler.h6
-rw-r--r--include/llvm/Target/Target.td5
-rw-r--r--include/llvm/Target/TargetFrameLowering.h19
-rw-r--r--include/llvm/Target/TargetLowering.h1255
-rw-r--r--include/llvm/Target/TargetMachine.h8
-rw-r--r--include/llvm/Target/TargetOptions.h8
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h22
-rw-r--r--include/llvm/Target/TargetSchedule.td1
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h4
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h4
-rw-r--r--include/llvm/Transforms/Instrumentation.h6
-rw-r--r--include/llvm/Transforms/ObjCARC.h49
-rw-r--r--include/llvm/Transforms/Scalar.h24
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h5
-rw-r--r--include/llvm/Transforms/Utils/BlackList.h58
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h4
-rw-r--r--include/llvm/Transforms/Utils/BypassSlowDivision.h4
-rw-r--r--include/llvm/Transforms/Utils/IntegerDivision.h18
-rw-r--r--include/llvm/Transforms/Utils/ModuleUtils.h6
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h4
-rw-r--r--include/llvm/Transforms/Vectorize.h3
281 files changed, 6929 insertions, 3622 deletions
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index 93d343a..14bcaef 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -97,8 +97,8 @@
nexttoward.
*/
-#ifndef LLVM_FLOAT_H
-#define LLVM_FLOAT_H
+#ifndef LLVM_ADT_APFLOAT_H
+#define LLVM_ADT_APFLOAT_H
// APInt contains static functions implementing bignum arithmetic.
#include "llvm/ADT/APInt.h"
@@ -184,9 +184,9 @@ namespace llvm {
APFloat(const fltSemantics &, integerPart);
APFloat(const fltSemantics &, fltCategory, bool negative);
APFloat(const fltSemantics &, uninitializedTag);
+ APFloat(const fltSemantics &, const APInt &);
explicit APFloat(double d);
explicit APFloat(float f);
- explicit APFloat(const APInt &, bool isIEEE = false);
APFloat(const APFloat &);
~APFloat();
@@ -300,7 +300,7 @@ namespace llvm {
/* The definition of equality is not straightforward for floating point,
so we won't use operator==. Use one of the following, or write
whatever it is you really mean. */
- // bool operator==(const APFloat &) const; // DO NOT IMPLEMENT
+ bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION;
/* IEEE comparison with another floating point number (NaNs
compare unordered, 0==-0). */
@@ -423,7 +423,7 @@ namespace llvm {
APInt convertQuadrupleAPFloatToAPInt() const;
APInt convertF80LongDoubleAPFloatToAPInt() const;
APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
- void initFromAPInt(const APInt& api, bool isIEEE = false);
+ void initFromAPInt(const fltSemantics *Sem, const APInt& api);
void initFromHalfAPInt(const APInt& api);
void initFromFloatAPInt(const APInt& api);
void initFromDoubleAPInt(const APInt& api);
@@ -463,4 +463,4 @@ namespace llvm {
hash_code hash_value(const APFloat &Arg);
} /* namespace llvm */
-#endif /* LLVM_FLOAT_H */
+#endif /* LLVM_ADT_APFLOAT_H */
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index 95cd23d..13b353c 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_APINT_H
-#define LLVM_APINT_H
+#ifndef LLVM_ADT_APINT_H
+#define LLVM_ADT_APINT_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Compiler.h"
@@ -505,6 +505,17 @@ public:
return getAllOnesValue(numBits).lshr(numBits - loBitsSet);
}
+ /// \brief Return a value containing V broadcasted over NewLen bits.
+ static APInt getSplat(unsigned NewLen, const APInt &V) {
+ assert(NewLen >= V.getBitWidth() && "Can't splat to smaller bit width!");
+
+ APInt Val = V.zextOrSelf(NewLen);
+ for (unsigned I = V.getBitWidth(); I < NewLen; I <<= 1)
+ Val |= Val << I;
+
+ return Val;
+ }
+
/// \brief Determine if two APInts have the same value, after zero-extending
/// one of them (if needed!) to ensure that the bit-widths match.
static bool isSameValue(const APInt &I1, const APInt &I2) {
@@ -799,16 +810,7 @@ public:
/// Signed divide this APInt by APInt RHS.
/// @brief Signed division function for APInt.
- APInt sdiv(const APInt &RHS) const {
- if (isNegative())
- if (RHS.isNegative())
- return (-(*this)).udiv(-RHS);
- else
- return -((-(*this)).udiv(RHS));
- else if (RHS.isNegative())
- return -(this->udiv(-RHS));
- return this->udiv(RHS);
- }
+ APInt sdiv(const APInt &RHS) const;
/// Perform an unsigned remainder operation on this APInt with RHS being the
/// divisor. Both this and RHS are treated as unsigned quantities for purposes
@@ -821,16 +823,7 @@ public:
/// Signed remainder operation on APInt.
/// @brief Function for signed remainder operation.
- APInt srem(const APInt &RHS) const {
- if (isNegative())
- if (RHS.isNegative())
- return -((-(*this)).urem(-RHS));
- else
- return -((-(*this)).urem(RHS));
- else if (RHS.isNegative())
- return this->urem(-RHS);
- return this->urem(RHS);
- }
+ APInt srem(const APInt &RHS) const;
/// Sometimes it is convenient to divide two APInt values and obtain both the
/// quotient and remainder. This function does both operations in the same
@@ -842,24 +835,9 @@ public:
APInt &Quotient, APInt &Remainder);
static void sdivrem(const APInt &LHS, const APInt &RHS,
- APInt &Quotient, APInt &Remainder) {
- if (LHS.isNegative()) {
- if (RHS.isNegative())
- APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
- else {
- APInt::udivrem(-LHS, RHS, Quotient, Remainder);
- Quotient = -Quotient;
- }
- Remainder = -Remainder;
- } else if (RHS.isNegative()) {
- APInt::udivrem(LHS, -RHS, Quotient, Remainder);
- Quotient = -Quotient;
- } else {
- APInt::udivrem(LHS, RHS, Quotient, Remainder);
- }
- }
-
-
+ APInt &Quotient, APInt &Remainder);
+
+
// Operations that return overflow indicators.
APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
@@ -1191,7 +1169,8 @@ public:
/// APInt. This is used in conjunction with getActiveData to extract the raw
/// value of the APInt.
unsigned getActiveWords() const {
- return whichWord(getActiveBits()-1) + 1;
+ unsigned numActiveBits = getActiveBits();
+ return numActiveBits ? whichWord(numActiveBits - 1) + 1 : 1;
}
/// Computes the minimum bit width for this APInt while considering it to be
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
index 4a5e7a3..42e1239 100644
--- a/include/llvm/ADT/APSInt.h
+++ b/include/llvm/ADT/APSInt.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_APSINT_H
-#define LLVM_APSINT_H
+#ifndef LLVM_ADT_APSINT_H
+#define LLVM_ADT_APSINT_H
#include "llvm/ADT/APInt.h"
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 1e35d62..c555c1c 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -33,6 +33,8 @@ namespace llvm {
typedef const T *const_iterator;
typedef size_t size_type;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
private:
/// The start of the array, in an external buffer.
const T *Data;
@@ -84,6 +86,9 @@ namespace llvm {
iterator begin() const { return Data; }
iterator end() const { return Data + Length; }
+ reverse_iterator rbegin() const { return reverse_iterator(end()); }
+ reverse_iterator rend() const { return reverse_iterator(begin()); }
+
/// empty - Check if the array is empty.
bool empty() const { return Length == 0; }
@@ -171,41 +176,41 @@ namespace llvm {
/// Construct an empty ArrayRef.
/*implicit*/ MutableArrayRef() : ArrayRef<T>() {}
-
+
/// Construct an MutableArrayRef from a single element.
/*implicit*/ MutableArrayRef(T &OneElt) : ArrayRef<T>(OneElt) {}
-
+
/// Construct an MutableArrayRef from a pointer and length.
/*implicit*/ MutableArrayRef(T *data, size_t length)
: ArrayRef<T>(data, length) {}
-
+
/// Construct an MutableArrayRef from a range.
MutableArrayRef(T *begin, T *end) : ArrayRef<T>(begin, end) {}
-
+
/// Construct an MutableArrayRef from a SmallVector.
/*implicit*/ MutableArrayRef(SmallVectorImpl<T> &Vec)
: ArrayRef<T>(Vec) {}
-
+
/// Construct a MutableArrayRef from a std::vector.
/*implicit*/ MutableArrayRef(std::vector<T> &Vec)
: ArrayRef<T>(Vec) {}
-
+
/// Construct an MutableArrayRef from a C array.
template <size_t N>
/*implicit*/ MutableArrayRef(T (&Arr)[N])
: ArrayRef<T>(Arr) {}
-
+
T *data() const { return const_cast<T*>(ArrayRef<T>::data()); }
iterator begin() const { return data(); }
iterator end() const { return data() + this->size(); }
-
+
/// front - Get the first element.
T &front() const {
assert(!this->empty());
return data()[0];
}
-
+
/// back - Get the last element.
T &back() const {
assert(!this->empty());
@@ -217,14 +222,14 @@ namespace llvm {
assert(N <= this->size() && "Invalid specifier");
return MutableArrayRef<T>(data()+N, this->size()-N);
}
-
+
/// slice(n, m) - Chop off the first N elements of the array, and keep M
/// elements in the array.
MutableArrayRef<T> slice(unsigned N, unsigned M) const {
assert(N+M <= this->size() && "Invalid specifier");
return MutableArrayRef<T>(data()+N, M);
}
-
+
/// @}
/// @name Operator Overloads
/// @{
@@ -301,5 +306,5 @@ namespace llvm {
static const bool value = true;
};
}
-
+
#endif
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 01f7e90..d410619 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -159,6 +159,24 @@ public:
return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
}
+#if LLVM_HAS_RVALUE_REFERENCES
+ // Inserts key,value pair into the map if the key isn't already in the map.
+ // If the key is already in the map, it returns false and doesn't update the
+ // value.
+ std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(KV.first, TheBucket))
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
+ false); // Already in map.
+
+ // Otherwise, insert the new element.
+ TheBucket = InsertIntoBucket(std::move(KV.first),
+ std::move(KV.second),
+ TheBucket);
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
+ }
+#endif
+
/// insert - Range insertion of pairs.
template<typename InputIt>
void insert(InputIt I, InputIt E) {
@@ -475,7 +493,6 @@ private:
if (KeyInfoT::isEqual(ThisBucket->first, EmptyKey)) {
// If we've already seen a tombstone while probing, fill it in instead
// of the empty bucket we eventually probed to.
- if (FoundTombstone) ThisBucket = FoundTombstone;
FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
return false;
}
diff --git a/include/llvm/ADT/ImmutableIntervalMap.h b/include/llvm/ADT/ImmutableIntervalMap.h
index fa7ccb9..6793c6b 100644
--- a/include/llvm/ADT/ImmutableIntervalMap.h
+++ b/include/llvm/ADT/ImmutableIntervalMap.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
-#define LLVM_ADT_IMMUTABLE_INTERVAL_MAP_H
+#ifndef LLVM_ADT_IMMUTABLEINTERVALMAP_H
+#define LLVM_ADT_IMMUTABLEINTERVALMAP_H
#include "llvm/ADT/ImmutableMap.h"
diff --git a/include/llvm/ADT/ImmutableList.h b/include/llvm/ADT/ImmutableList.h
index 998d785..7f0c239 100644
--- a/include/llvm/ADT/ImmutableList.h
+++ b/include/llvm/ADT/ImmutableList.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_IMLIST_H
-#define LLVM_ADT_IMLIST_H
+#ifndef LLVM_ADT_IMMUTABLELIST_H
+#define LLVM_ADT_IMMUTABLELIST_H
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Allocator.h"
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index f9baec2..a667479 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_IMMAP_H
-#define LLVM_ADT_IMMAP_H
+#ifndef LLVM_ADT_IMMUTABLEMAP_H
+#define LLVM_ADT_IMMUTABLEMAP_H
#include "llvm/ADT/ImmutableSet.h"
@@ -211,17 +211,22 @@ public:
friend class ImmutableMap;
public:
- value_type_ref operator*() const { return itr->getValue(); }
- value_type* operator->() const { return &itr->getValue(); }
+ typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type value_type;
+ typedef typename ImmutableMap<KeyT,ValT,ValInfo>::value_type_ref reference;
+ typedef typename iterator::value_type *pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ typename iterator::reference operator*() const { return itr->getValue(); }
+ typename iterator::pointer operator->() const { return &itr->getValue(); }
key_type_ref getKey() const { return itr->getValue().first; }
data_type_ref getData() const { return itr->getValue().second; }
-
iterator& operator++() { ++itr; return *this; }
iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
iterator& operator--() { --itr; return *this; }
iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+
bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
};
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 0982657..fbdf066 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_IMSET_H
-#define LLVM_ADT_IMSET_H
+#ifndef LLVM_ADT_IMMUTABLESET_H
+#define LLVM_ADT_IMMUTABLESET_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -1054,18 +1054,27 @@ public:
class iterator {
typename TreeTy::iterator itr;
+
+ iterator() {}
iterator(TreeTy* t) : itr(t) {}
friend class ImmutableSet<ValT,ValInfo>;
+
public:
- iterator() {}
- inline value_type_ref operator*() const { return itr->getValue(); }
- inline iterator& operator++() { ++itr; return *this; }
- inline iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
- inline iterator& operator--() { --itr; return *this; }
- inline iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
- inline bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
- inline bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
- inline value_type *operator->() const { return &(operator*()); }
+ typedef typename ImmutableSet<ValT,ValInfo>::value_type value_type;
+ typedef typename ImmutableSet<ValT,ValInfo>::value_type_ref reference;
+ typedef typename iterator::value_type *pointer;
+ typedef std::bidirectional_iterator_tag iterator_category;
+
+ typename iterator::reference operator*() const { return itr->getValue(); }
+ typename iterator::pointer operator->() const { return &(operator*()); }
+
+ iterator& operator++() { ++itr; return *this; }
+ iterator operator++(int) { iterator tmp(*this); ++itr; return tmp; }
+ iterator& operator--() { --itr; return *this; }
+ iterator operator--(int) { iterator tmp(*this); --itr; return tmp; }
+
+ bool operator==(const iterator& RHS) const { return RHS.itr == itr; }
+ bool operator!=(const iterator& RHS) const { return RHS.itr != itr; }
};
iterator begin() const { return iterator(Root); }
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 5849503..9e5ab02 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_INTRUSIVE_REF_CNT_PTR
-#define LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
+#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
@@ -240,4 +240,4 @@ namespace llvm {
} // end namespace llvm
-#endif // LLVM_ADT_INTRUSIVE_REF_CNT_PTR
+#endif // LLVM_ADT_INTRUSIVEREFCNTPTR_H
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index c34e32a..f6fcb08 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -19,6 +19,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
#include <vector>
namespace llvm {
@@ -63,6 +64,11 @@ public:
return Vector.empty();
}
+ std::pair<KeyT, ValueT> &front() { return Vector.front(); }
+ const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
+ std::pair<KeyT, ValueT> &back() { return Vector.back(); }
+ const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
+
void clear() {
Map.clear();
Vector.clear();
@@ -84,6 +90,18 @@ public:
return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
}
+ std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+ std::pair<KeyT, unsigned> Pair = std::make_pair(KV.first, 0);
+ std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
+ unsigned &I = Result.first->second;
+ if (Result.second) {
+ Vector.push_back(std::make_pair(KV.first, KV.second));
+ I = Vector.size() - 1;
+ return std::make_pair(llvm::prior(end()), true);
+ }
+ return std::make_pair(begin() + I, false);
+ }
+
unsigned count(const KeyT &Key) const {
typename MapType::const_iterator Pos = Map.find(Key);
return Pos == Map.end()? 0 : 1;
@@ -100,6 +118,13 @@ public:
return Pos == Map.end()? Vector.end() :
(Vector.begin() + Pos->second);
}
+
+ /// \brief Remove the last element from the vector.
+ void pop_back() {
+ typename MapType::iterator Pos = Map.find(Vector.back().first);
+ Map.erase(Pos);
+ Vector.pop_back();
+ }
};
}
diff --git a/include/llvm/ADT/None.h b/include/llvm/ADT/None.h
new file mode 100644
index 0000000..5793bd2
--- /dev/null
+++ b/include/llvm/ADT/None.h
@@ -0,0 +1,27 @@
+//===-- None.h - Simple null value for implicit construction ------*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides None, an enumerator for use in implicit constructors
+// of various (usually templated) types to make such construction more
+// terse.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_NONE_H
+#define LLVM_ADT_NONE_H
+
+namespace llvm {
+/// \brief A simple null object to allow implicit construction of Optional<T>
+/// and similar types without having to spell out the specialization's name.
+enum NoneType {
+ None
+};
+}
+
+#endif
diff --git a/include/llvm/ADT/NullablePtr.h b/include/llvm/ADT/NullablePtr.h
index a9c47a1..8ddfd5d 100644
--- a/include/llvm/ADT/NullablePtr.h
+++ b/include/llvm/ADT/NullablePtr.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_NULLABLE_PTR_H
-#define LLVM_ADT_NULLABLE_PTR_H
+#ifndef LLVM_ADT_NULLABLEPTR_H
+#define LLVM_ADT_NULLABLEPTR_H
#include <cassert>
#include <cstddef>
diff --git a/include/llvm/ADT/Optional.h b/include/llvm/ADT/Optional.h
index 06e5af0..81d73ed 100644
--- a/include/llvm/ADT/Optional.h
+++ b/include/llvm/ADT/Optional.h
@@ -13,10 +13,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_OPTIONAL
-#define LLVM_ADT_OPTIONAL
+#ifndef LLVM_ADT_OPTIONAL_H
+#define LLVM_ADT_OPTIONAL_H
+#include "llvm/ADT/None.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/AlignOf.h"
#include <cassert>
#if LLVM_HAS_RVALUE_REFERENCES
@@ -27,37 +29,102 @@ namespace llvm {
template<typename T>
class Optional {
- T x;
+ AlignedCharArrayUnion<T> storage;
bool hasVal;
public:
- explicit Optional() : x(), hasVal(false) {}
- Optional(const T &y) : x(y), hasVal(true) {}
+ Optional(NoneType) : hasVal(false) {}
+ explicit Optional() : hasVal(false) {}
+ Optional(const T &y) : hasVal(true) {
+ new (storage.buffer) T(y);
+ }
+ Optional(const Optional &O) : hasVal(O.hasVal) {
+ if (hasVal)
+ new (storage.buffer) T(*O);
+ }
#if LLVM_HAS_RVALUE_REFERENCES
- Optional(T &&y) : x(std::forward<T>(y)), hasVal(true) {}
+ Optional(T &&y) : hasVal(true) {
+ new (storage.buffer) T(std::forward<T>(y));
+ }
+ Optional(Optional<T> &&O) : hasVal(O) {
+ if (O) {
+ new (storage.buffer) T(std::move(*O));
+ O.reset();
+ }
+ }
+ Optional &operator=(T &&y) {
+ if (hasVal)
+ **this = std::move(y);
+ else {
+ new (storage.buffer) T(std::move(y));
+ hasVal = true;
+ }
+ return *this;
+ }
+ Optional &operator=(Optional &&O) {
+ if (!O)
+ reset();
+ else {
+ *this = std::move(*O);
+ O.reset();
+ }
+ return *this;
+ }
#endif
static inline Optional create(const T* y) {
return y ? Optional(*y) : Optional();
}
+ // FIXME: these assignments (& the equivalent const T&/const Optional& ctors)
+ // could be made more efficient by passing by value, possibly unifying them
+ // with the rvalue versions above - but this could place a different set of
+ // requirements (notably: the existence of a default ctor) when implemented
+ // in that way. Careful SFINAE to avoid such pitfalls would be required.
Optional &operator=(const T &y) {
- x = y;
- hasVal = true;
+ if (hasVal)
+ **this = y;
+ else {
+ new (storage.buffer) T(y);
+ hasVal = true;
+ }
+ return *this;
+ }
+
+ Optional &operator=(const Optional &O) {
+ if (!O)
+ reset();
+ else
+ *this = *O;
return *this;
}
-
- const T* getPointer() const { assert(hasVal); return &x; }
- const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
- operator bool() const { return hasVal; }
+ void reset() {
+ if (hasVal) {
+ (**this).~T();
+ hasVal = false;
+ }
+ }
+
+ ~Optional() {
+ reset();
+ }
+
+ const T* getPointer() const { assert(hasVal); return reinterpret_cast<const T*>(storage.buffer); }
+ T* getPointer() { assert(hasVal); return reinterpret_cast<T*>(storage.buffer); }
+ const T& getValue() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+ T& getValue() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+
+ LLVM_EXPLICIT operator bool() const { return hasVal; }
bool hasValue() const { return hasVal; }
const T* operator->() const { return getPointer(); }
- const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return x; }
+ T* operator->() { return getPointer(); }
+ const T& operator*() const LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
+ T& operator*() LLVM_LVALUE_FUNCTION { assert(hasVal); return *getPointer(); }
#if LLVM_HAS_RVALUE_REFERENCE_THIS
- T&& getValue() && { assert(hasVal); return std::move(x); }
- T&& operator*() && { assert(hasVal); return std::move(x); }
+ T&& getValue() && { assert(hasVal); return std::move(*getPointer()); }
+ T&& operator*() && { assert(hasVal); return std::move(*getPointer()); }
#endif
};
@@ -75,11 +142,17 @@ template <typename T>
struct simplify_type<Optional<T> >
: public simplify_type<const Optional<T> > {};
+template <typename T> struct isPodLike;
+template <typename T> struct isPodLike<Optional<T> > {
+ // An Optional<T> is pod-like if T is.
+ static const bool value = isPodLike<T>::value;
+};
+
/// \brief Poison comparison between two \c Optional objects. Clients needs to
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator==(const Optional<T> &X, const Optional<U> &Y);
@@ -88,7 +161,7 @@ void operator==(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator!=(const Optional<T> &X, const Optional<U> &Y);
@@ -97,7 +170,7 @@ void operator!=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator<(const Optional<T> &X, const Optional<U> &Y);
@@ -106,7 +179,7 @@ void operator<(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator<=(const Optional<T> &X, const Optional<U> &Y);
@@ -115,7 +188,7 @@ void operator<=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator>=(const Optional<T> &X, const Optional<U> &Y);
@@ -124,7 +197,7 @@ void operator>=(const Optional<T> &X, const Optional<U> &Y);
/// explicitly compare the underlying values and account for empty \c Optional
/// objects.
///
-/// This routine will never be defined. It returns \c void to help diagnose
+/// This routine will never be defined. It returns \c void to help diagnose
/// errors at compile time.
template<typename T, typename U>
void operator>(const Optional<T> &X, const Optional<U> &Y);
diff --git a/include/llvm/ADT/OwningPtr.h b/include/llvm/ADT/OwningPtr.h
index ea22991..86f9fee 100644
--- a/include/llvm/ADT/OwningPtr.h
+++ b/include/llvm/ADT/OwningPtr.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_OWNING_PTR_H
-#define LLVM_ADT_OWNING_PTR_H
+#ifndef LLVM_ADT_OWNINGPTR_H
+#define LLVM_ADT_OWNINGPTR_H
#include "llvm/Support/Compiler.h"
#include <cassert>
diff --git a/include/llvm/ADT/PriorityQueue.h b/include/llvm/ADT/PriorityQueue.h
index bf8a687..827d0b3 100644
--- a/include/llvm/ADT/PriorityQueue.h
+++ b/include/llvm/ADT/PriorityQueue.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_PRIORITY_QUEUE_H
-#define LLVM_ADT_PRIORITY_QUEUE_H
+#ifndef LLVM_ADT_PRIORITYQUEUE_H
+#define LLVM_ADT_PRIORITYQUEUE_H
#include <algorithm>
#include <queue>
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
index 8da99d1..2cfb5b9 100644
--- a/include/llvm/ADT/SmallString.h
+++ b/include/llvm/ADT/SmallString.h
@@ -77,7 +77,7 @@ public:
void append(in_iter S, in_iter E) {
SmallVectorImpl<char>::append(S, E);
}
-
+
void append(size_t NumInputs, char Elt) {
SmallVectorImpl<char>::append(NumInputs, Elt);
}
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 951e574..9167f87 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -145,16 +145,20 @@ public:
}
reference front() {
+ assert(!empty());
return begin()[0];
}
const_reference front() const {
+ assert(!empty());
return begin()[0];
}
reference back() {
+ assert(!empty());
return end()[-1];
}
const_reference back() const {
+ assert(!empty());
return end()[-1];
}
};
diff --git a/include/llvm/ADT/SparseMultiSet.h b/include/llvm/ADT/SparseMultiSet.h
new file mode 100644
index 0000000..7f2a6f7
--- /dev/null
+++ b/include/llvm/ADT/SparseMultiSet.h
@@ -0,0 +1,526 @@
+//===--- llvm/ADT/SparseMultiSet.h - Sparse multiset ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SparseMultiSet class, which adds multiset behavior to
+// the SparseSet.
+//
+// A sparse multiset holds a small number of objects identified by integer keys
+// from a moderately sized universe. The sparse multiset uses more memory than
+// other containers in order to provide faster operations. Any key can map to
+// multiple values. A SparseMultiSetNode class is provided, which serves as a
+// convenient base class for the contents of a SparseMultiSet.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SPARSEMULTISET_H
+#define LLVM_ADT_SPARSEMULTISET_H
+
+#include "llvm/ADT/SparseSet.h"
+
+namespace llvm {
+
+/// Fast multiset implementation for objects that can be identified by small
+/// unsigned keys.
+///
+/// SparseMultiSet allocates memory proportional to the size of the key
+/// universe, so it is not recommended for building composite data structures.
+/// It is useful for algorithms that require a single set with fast operations.
+///
+/// Compared to DenseSet and DenseMap, SparseMultiSet provides constant-time
+/// fast clear() as fast as a vector. The find(), insert(), and erase()
+/// operations are all constant time, and typically faster than a hash table.
+/// The iteration order doesn't depend on numerical key values, it only depends
+/// on the order of insert() and erase() operations. Iteration order is the
+/// insertion order. Iteration is only provided over elements of equivalent
+/// keys, but iterators are bidirectional.
+///
+/// Compared to BitVector, SparseMultiSet<unsigned> uses 8x-40x more memory, but
+/// offers constant-time clear() and size() operations as well as fast iteration
+/// independent on the size of the universe.
+///
+/// SparseMultiSet contains a dense vector holding all the objects and a sparse
+/// array holding indexes into the dense vector. Most of the memory is used by
+/// the sparse array which is the size of the key universe. The SparseT template
+/// parameter provides a space/speed tradeoff for sets holding many elements.
+///
+/// When SparseT is uint32_t, find() only touches up to 3 cache lines, but the
+/// sparse array uses 4 x Universe bytes.
+///
+/// When SparseT is uint8_t (the default), find() touches up to 3+[N/256] cache
+/// lines, but the sparse array is 4x smaller. N is the number of elements in
+/// the set.
+///
+/// For sets that may grow to thousands of elements, SparseT should be set to
+/// uint16_t or uint32_t.
+///
+/// Multiset behavior is provided by providing doubly linked lists for values
+/// that are inlined in the dense vector. SparseMultiSet is a good choice when
+/// one desires a growable number of entries per key, as it will retain the
+/// SparseSet algorithmic properties despite being growable. Thus, it is often a
+/// better choice than a SparseSet of growable containers or a vector of
+/// vectors. SparseMultiSet also keeps iterators valid after erasure (provided
+/// the iterators don't point to the element erased), allowing for more
+/// intuitive and fast removal.
+///
+/// @tparam ValueT The type of objects in the set.
+/// @tparam KeyFunctorT A functor that computes an unsigned index from KeyT.
+/// @tparam SparseT An unsigned integer type. See above.
+///
+template<typename ValueT,
+ typename KeyFunctorT = llvm::identity<unsigned>,
+ typename SparseT = uint8_t>
+class SparseMultiSet {
+ /// The actual data that's stored, as a doubly-linked list implemented via
+ /// indices into the DenseVector. The doubly linked list is implemented
+ /// circular in Prev indices, and INVALID-terminated in Next indices. This
+ /// provides efficient access to list tails. These nodes can also be
+ /// tombstones, in which case they are actually nodes in a single-linked
+ /// freelist of recyclable slots.
+ struct SMSNode {
+ static const unsigned INVALID = ~0U;
+
+ ValueT Data;
+ unsigned Prev;
+ unsigned Next;
+
+ SMSNode(ValueT D, unsigned P, unsigned N) : Data(D), Prev(P), Next(N) { }
+
+ /// List tails have invalid Nexts.
+ bool isTail() const {
+ return Next == INVALID;
+ }
+
+ /// Whether this node is a tombstone node, and thus is in our freelist.
+ bool isTombstone() const {
+ return Prev == INVALID;
+ }
+
+ /// Since the list is circular in Prev, all non-tombstone nodes have a valid
+ /// Prev.
+ bool isValid() const { return Prev != INVALID; }
+ };
+
+ typedef typename KeyFunctorT::argument_type KeyT;
+ typedef SmallVector<SMSNode, 8> DenseT;
+ DenseT Dense;
+ SparseT *Sparse;
+ unsigned Universe;
+ KeyFunctorT KeyIndexOf;
+ SparseSetValFunctor<KeyT, ValueT, KeyFunctorT> ValIndexOf;
+
+ /// We have a built-in recycler for reusing tombstone slots. This recycler
+ /// puts a singly-linked free list into tombstone slots, allowing us quick
+ /// erasure, iterator preservation, and dense size.
+ unsigned FreelistIdx;
+ unsigned NumFree;
+
+ unsigned sparseIndex(const ValueT &Val) const {
+ assert(ValIndexOf(Val) < Universe &&
+ "Invalid key in set. Did object mutate?");
+ return ValIndexOf(Val);
+ }
+ unsigned sparseIndex(const SMSNode &N) const { return sparseIndex(N.Data); }
+
+ // Disable copy construction and assignment.
+ // This data structure is not meant to be used that way.
+ SparseMultiSet(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
+ SparseMultiSet &operator=(const SparseMultiSet&) LLVM_DELETED_FUNCTION;
+
+ /// Whether the given entry is the head of the list. List heads's previous
+ /// pointers are to the tail of the list, allowing for efficient access to the
+ /// list tail. D must be a valid entry node.
+ bool isHead(const SMSNode &D) const {
+ assert(D.isValid() && "Invalid node for head");
+ return Dense[D.Prev].isTail();
+ }
+
+ /// Whether the given entry is a singleton entry, i.e. the only entry with
+ /// that key.
+ bool isSingleton(const SMSNode &N) const {
+ assert(N.isValid() && "Invalid node for singleton");
+ // Is N its own predecessor?
+ return &Dense[N.Prev] == &N;
+ }
+
+ /// Add in the given SMSNode. Uses a free entry in our freelist if
+ /// available. Returns the index of the added node.
+ unsigned addValue(const ValueT& V, unsigned Prev, unsigned Next) {
+ if (NumFree == 0) {
+ Dense.push_back(SMSNode(V, Prev, Next));
+ return Dense.size() - 1;
+ }
+
+ // Peel off a free slot
+ unsigned Idx = FreelistIdx;
+ unsigned NextFree = Dense[Idx].Next;
+ assert(Dense[Idx].isTombstone() && "Non-tombstone free?");
+
+ Dense[Idx] = SMSNode(V, Prev, Next);
+ FreelistIdx = NextFree;
+ --NumFree;
+ return Idx;
+ }
+
+ /// Make the current index a new tombstone. Pushes it onto the freelist.
+ void makeTombstone(unsigned Idx) {
+ Dense[Idx].Prev = SMSNode::INVALID;
+ Dense[Idx].Next = FreelistIdx;
+ FreelistIdx = Idx;
+ ++NumFree;
+ }
+
+public:
+ typedef ValueT value_type;
+ typedef ValueT &reference;
+ typedef const ValueT &const_reference;
+ typedef ValueT *pointer;
+ typedef const ValueT *const_pointer;
+
+ SparseMultiSet()
+ : Sparse(0), Universe(0), FreelistIdx(SMSNode::INVALID), NumFree(0) { }
+
+ ~SparseMultiSet() { free(Sparse); }
+
+ /// Set the universe size which determines the largest key the set can hold.
+ /// The universe must be sized before any elements can be added.
+ ///
+ /// @param U Universe size. All object keys must be less than U.
+ ///
+ void setUniverse(unsigned U) {
+ // It's not hard to resize the universe on a non-empty set, but it doesn't
+ // seem like a likely use case, so we can add that code when we need it.
+ assert(empty() && "Can only resize universe on an empty map");
+ // Hysteresis prevents needless reallocations.
+ if (U >= Universe/4 && U <= Universe)
+ return;
+ free(Sparse);
+ // The Sparse array doesn't actually need to be initialized, so malloc
+ // would be enough here, but that will cause tools like valgrind to
+ // complain about branching on uninitialized data.
+ Sparse = reinterpret_cast<SparseT*>(calloc(U, sizeof(SparseT)));
+ Universe = U;
+ }
+
+ /// Our iterators are iterators over the collection of objects that share a
+ /// key.
+ template<typename SMSPtrTy>
+ class iterator_base : public std::iterator<std::bidirectional_iterator_tag,
+ ValueT> {
+ friend class SparseMultiSet;
+ SMSPtrTy SMS;
+ unsigned Idx;
+ unsigned SparseIdx;
+
+ iterator_base(SMSPtrTy P, unsigned I, unsigned SI)
+ : SMS(P), Idx(I), SparseIdx(SI) { }
+
+ /// Whether our iterator has fallen outside our dense vector.
+ bool isEnd() const {
+ if (Idx == SMSNode::INVALID)
+ return true;
+
+ assert(Idx < SMS->Dense.size() && "Out of range, non-INVALID Idx?");
+ return false;
+ }
+
+ /// Whether our iterator is properly keyed, i.e. the SparseIdx is valid
+ bool isKeyed() const { return SparseIdx < SMS->Universe; }
+
+ unsigned Prev() const { return SMS->Dense[Idx].Prev; }
+ unsigned Next() const { return SMS->Dense[Idx].Next; }
+
+ void setPrev(unsigned P) { SMS->Dense[Idx].Prev = P; }
+ void setNext(unsigned N) { SMS->Dense[Idx].Next = N; }
+
+ public:
+ typedef std::iterator<std::bidirectional_iterator_tag, ValueT> super;
+ typedef typename super::value_type value_type;
+ typedef typename super::difference_type difference_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ iterator_base(const iterator_base &RHS)
+ : SMS(RHS.SMS), Idx(RHS.Idx), SparseIdx(RHS.SparseIdx) { }
+
+ const iterator_base &operator=(const iterator_base &RHS) {
+ SMS = RHS.SMS;
+ Idx = RHS.Idx;
+ SparseIdx = RHS.SparseIdx;
+ return *this;
+ }
+
+ reference operator*() const {
+ assert(isKeyed() && SMS->sparseIndex(SMS->Dense[Idx].Data) == SparseIdx &&
+ "Dereferencing iterator of invalid key or index");
+
+ return SMS->Dense[Idx].Data;
+ }
+ pointer operator->() const { return &operator*(); }
+
+ /// Comparison operators
+ bool operator==(const iterator_base &RHS) const {
+ // end compares equal
+ if (SMS == RHS.SMS && Idx == RHS.Idx) {
+ assert((isEnd() || SparseIdx == RHS.SparseIdx) &&
+ "Same dense entry, but different keys?");
+ return true;
+ }
+
+ return false;
+ }
+
+ bool operator!=(const iterator_base &RHS) const {
+ return !operator==(RHS);
+ }
+
+ /// Increment and decrement operators
+ iterator_base &operator--() { // predecrement - Back up
+ assert(isKeyed() && "Decrementing an invalid iterator");
+ assert((isEnd() || !SMS->isHead(SMS->Dense[Idx])) &&
+ "Decrementing head of list");
+
+ // If we're at the end, then issue a new find()
+ if (isEnd())
+ Idx = SMS->findIndex(SparseIdx).Prev();
+ else
+ Idx = Prev();
+
+ return *this;
+ }
+ iterator_base &operator++() { // preincrement - Advance
+ assert(!isEnd() && isKeyed() && "Incrementing an invalid/end iterator");
+ Idx = Next();
+ return *this;
+ }
+ iterator_base operator--(int) { // postdecrement
+ iterator_base I(*this);
+ --*this;
+ return I;
+ }
+ iterator_base operator++(int) { // postincrement
+ iterator_base I(*this);
+ ++*this;
+ return I;
+ }
+ };
+ typedef iterator_base<SparseMultiSet *> iterator;
+ typedef iterator_base<const SparseMultiSet *> const_iterator;
+
+ // Convenience types
+ typedef std::pair<iterator, iterator> RangePair;
+
+ /// Returns an iterator past this container. Note that such an iterator cannot
+ /// be decremented, but will compare equal to other end iterators.
+ iterator end() { return iterator(this, SMSNode::INVALID, SMSNode::INVALID); }
+ const_iterator end() const {
+ return const_iterator(this, SMSNode::INVALID, SMSNode::INVALID);
+ }
+
+ /// Returns true if the set is empty.
+ ///
+ /// This is not the same as BitVector::empty().
+ ///
+ bool empty() const { return size() == 0; }
+
+ /// Returns the number of elements in the set.
+ ///
+ /// This is not the same as BitVector::size() which returns the size of the
+ /// universe.
+ ///
+ unsigned size() const {
+ assert(NumFree <= Dense.size() && "Out-of-bounds free entries");
+ return Dense.size() - NumFree;
+ }
+
+ /// Clears the set. This is a very fast constant time operation.
+ ///
+ void clear() {
+ // Sparse does not need to be cleared, see find().
+ Dense.clear();
+ NumFree = 0;
+ FreelistIdx = SMSNode::INVALID;
+ }
+
+ /// Find an element by its index.
+ ///
+ /// @param Idx A valid index to find.
+ /// @returns An iterator to the element identified by key, or end().
+ ///
+ iterator findIndex(unsigned Idx) {
+ assert(Idx < Universe && "Key out of range");
+ assert(std::numeric_limits<SparseT>::is_integer &&
+ !std::numeric_limits<SparseT>::is_signed &&
+ "SparseT must be an unsigned integer type");
+ const unsigned Stride = std::numeric_limits<SparseT>::max() + 1u;
+ for (unsigned i = Sparse[Idx], e = Dense.size(); i < e; i += Stride) {
+ const unsigned FoundIdx = sparseIndex(Dense[i]);
+ // Check that we're pointing at the correct entry and that it is the head
+ // of a valid list.
+ if (Idx == FoundIdx && Dense[i].isValid() && isHead(Dense[i]))
+ return iterator(this, i, Idx);
+ // Stride is 0 when SparseT >= unsigned. We don't need to loop.
+ if (!Stride)
+ break;
+ }
+ return end();
+ }
+
+ /// Find an element by its key.
+ ///
+ /// @param Key A valid key to find.
+ /// @returns An iterator to the element identified by key, or end().
+ ///
+ iterator find(const KeyT &Key) {
+ return findIndex(KeyIndexOf(Key));
+ }
+
+ const_iterator find(const KeyT &Key) const {
+ iterator I = const_cast<SparseMultiSet*>(this)->findIndex(KeyIndexOf(Key));
+ return const_iterator(I.SMS, I.Idx, KeyIndexOf(Key));
+ }
+
+ /// Returns the number of elements identified by Key. This will be linear in
+ /// the number of elements of that key.
+ unsigned count(const KeyT &Key) const {
+ unsigned Ret = 0;
+ for (const_iterator It = find(Key); It != end(); ++It)
+ ++Ret;
+
+ return Ret;
+ }
+
+ /// Returns true if this set contains an element identified by Key.
+ bool contains(const KeyT &Key) const {
+ return find(Key) != end();
+ }
+
+ /// Return the head and tail of the subset's list, otherwise returns end().
+ iterator getHead(const KeyT &Key) { return find(Key); }
+ iterator getTail(const KeyT &Key) {
+ iterator I = find(Key);
+ if (I != end())
+ I = iterator(this, I.Prev(), KeyIndexOf(Key));
+ return I;
+ }
+
+ /// The bounds of the range of items sharing Key K. First member is the head
+ /// of the list, and the second member is a decrementable end iterator for
+ /// that key.
+ RangePair equal_range(const KeyT &K) {
+ iterator B = find(K);
+ iterator E = iterator(this, SMSNode::INVALID, B.SparseIdx);
+ return make_pair(B, E);
+ }
+
+ /// Insert a new element at the tail of the subset list. Returns an iterator
+ /// to the newly added entry.
+ iterator insert(const ValueT &Val) {
+ unsigned Idx = sparseIndex(Val);
+ iterator I = findIndex(Idx);
+
+ unsigned NodeIdx = addValue(Val, SMSNode::INVALID, SMSNode::INVALID);
+
+ if (I == end()) {
+ // Make a singleton list
+ Sparse[Idx] = NodeIdx;
+ Dense[NodeIdx].Prev = NodeIdx;
+ return iterator(this, NodeIdx, Idx);
+ }
+
+ // Stick it at the end.
+ unsigned HeadIdx = I.Idx;
+ unsigned TailIdx = I.Prev();
+ Dense[TailIdx].Next = NodeIdx;
+ Dense[HeadIdx].Prev = NodeIdx;
+ Dense[NodeIdx].Prev = TailIdx;
+
+ return iterator(this, NodeIdx, Idx);
+ }
+
+ /// Erases an existing element identified by a valid iterator.
+ ///
+ /// This invalidates iterators pointing at the same entry, but erase() returns
+ /// an iterator pointing to the next element in the subset's list. This makes
+ /// it possible to erase selected elements while iterating over the subset:
+ ///
+ /// tie(I, E) = Set.equal_range(Key);
+ /// while (I != E)
+ /// if (test(*I))
+ /// I = Set.erase(I);
+ /// else
+ /// ++I;
+ ///
+ /// Note that if the last element in the subset list is erased, this will
+ /// return an end iterator which can be decremented to get the new tail (if it
+ /// exists):
+ ///
+ /// tie(B, I) = Set.equal_range(Key);
+ /// for (bool isBegin = B == I; !isBegin; /* empty */) {
+ /// isBegin = (--I) == B;
+ /// if (test(I))
+ /// break;
+ /// I = erase(I);
+ /// }
+ iterator erase(iterator I) {
+ assert(I.isKeyed() && !I.isEnd() && !Dense[I.Idx].isTombstone() &&
+ "erasing invalid/end/tombstone iterator");
+
+ // First, unlink the node from its list. Then swap the node out with the
+ // dense vector's last entry
+ iterator NextI = unlink(Dense[I.Idx]);
+
+ // Put in a tombstone.
+ makeTombstone(I.Idx);
+
+ return NextI;
+ }
+
+ /// Erase all elements with the given key. This invalidates all
+ /// iterators of that key.
+ void eraseAll(const KeyT &K) {
+ for (iterator I = find(K); I != end(); /* empty */)
+ I = erase(I);
+ }
+
+private:
+ /// Unlink the node from its list. Returns the next node in the list.
+ iterator unlink(const SMSNode &N) {
+ if (isSingleton(N)) {
+ // Singleton is already unlinked
+ assert(N.Next == SMSNode::INVALID && "Singleton has next?");
+ return iterator(this, SMSNode::INVALID, ValIndexOf(N.Data));
+ }
+
+ if (isHead(N)) {
+ // If we're the head, then update the sparse array and our next.
+ Sparse[sparseIndex(N)] = N.Next;
+ Dense[N.Next].Prev = N.Prev;
+ return iterator(this, N.Next, ValIndexOf(N.Data));
+ }
+
+ if (N.isTail()) {
+ // If we're the tail, then update our head and our previous.
+ findIndex(sparseIndex(N)).setPrev(N.Prev);
+ Dense[N.Prev].Next = N.Next;
+
+ // Give back an end iterator that can be decremented
+ iterator I(this, N.Prev, ValIndexOf(N.Data));
+ return ++I;
+ }
+
+ // Otherwise, just drop us
+ Dense[N.Next].Prev = N.Prev;
+ Dense[N.Prev].Next = N.Next;
+ return iterator(this, N.Next, ValIndexOf(N.Data));
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
index 9503e0f..d2887c5 100644
--- a/include/llvm/ADT/StringExtras.h
+++ b/include/llvm/ADT/StringExtras.h
@@ -27,6 +27,17 @@ static inline char hexdigit(unsigned X, bool LowerCase = false) {
return X < 10 ? '0' + X : HexChar + X - 10;
}
+/// Interpret the given character \p C as a hexadecimal digit and return its
+/// value.
+///
+/// If \p C is not a valid hex digit, -1U is returned.
+static inline unsigned hexDigitValue(char C) {
+ if (C >= '0' && C <= '9') return C-'0';
+ if (C >= 'a' && C <= 'f') return C-'a'+10U;
+ if (C >= 'A' && C <= 'F') return C-'A'+10U;
+ return -1U;
+}
+
/// utohex_buffer - Emit the specified number into the buffer specified by
/// BufferEnd, returning a pointer to the start of the string. This can be used
/// like this: (note that the buffer must be large enough to handle any number):
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
index 0d68d11..d01437b 100644
--- a/include/llvm/ADT/StringMap.h
+++ b/include/llvm/ADT/StringMap.h
@@ -237,6 +237,10 @@ public:
explicit StringMap(AllocatorTy A)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))), Allocator(A) {}
+ StringMap(unsigned InitialSize, AllocatorTy A)
+ : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))),
+ Allocator(A) {}
+
StringMap(const StringMap &RHS)
: StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
assert(RHS.empty() &&
@@ -334,8 +338,8 @@ public:
StringMapEntryBase *&Bucket = TheTable[I];
if (Bucket && Bucket != getTombstoneVal()) {
static_cast<MapEntryTy*>(Bucket)->Destroy(Allocator);
- Bucket = 0;
}
+ Bucket = 0;
}
NumItems = 0;
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 0e93f51..224855e 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -57,14 +57,14 @@ namespace llvm {
// integer works around this bug.
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
static size_t max(size_t a, size_t b) { return a > b ? a : b; }
-
+
// Workaround memcmp issue with null pointers (undefined behavior)
// by providing a specialized version
static int compareMemory(const char *Lhs, const char *Rhs, size_t Length) {
if (Length == 0) { return 0; }
return ::memcmp(Lhs,Rhs,Length);
}
-
+
public:
/// @name Constructors
/// @{
@@ -387,7 +387,7 @@ namespace llvm {
Start = min(Start, Length);
return StringRef(Data + Start, min(N, Length - Start));
}
-
+
/// Return a StringRef equal to 'this' but with the first \p N elements
/// dropped.
StringRef drop_front(unsigned N = 1) const {
@@ -535,7 +535,7 @@ namespace llvm {
return LHS.compare(RHS) != -1;
}
- inline std::string &operator+=(std::string &buffer, llvm::StringRef string) {
+ inline std::string &operator+=(std::string &buffer, StringRef string) {
return buffer.append(string.data(), string.size());
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 49d9f68..8fac222 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -44,6 +44,7 @@ public:
UnknownArch,
arm, // ARM; arm, armv.*, xscale
+ aarch64, // AArch64: aarch64
hexagon, // Hexagon: hexagon
mips, // MIPS: mips, mipsallegrex
mipsel, // MIPSEL: mipsel, mipsallegrexel
@@ -111,6 +112,7 @@ public:
GNU,
GNUEABI,
GNUEABIHF,
+ GNUX32,
EABI,
MachO,
Android,
@@ -295,9 +297,14 @@ public:
return getOS() == Triple::Darwin || getOS() == Triple::MacOSX;
}
+ /// Is this an iOS triple.
+ bool isiOS() const {
+ return getOS() == Triple::IOS;
+ }
+
/// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
bool isOSDarwin() const {
- return isMacOSX() || getOS() == Triple::IOS;
+ return isMacOSX() || isiOS();
}
/// \brief Tests for either Cygwin or MinGW OS
diff --git a/include/llvm/ADT/VariadicFunction.h b/include/llvm/ADT/VariadicFunction.h
index a7f83a6..0497aa7 100644
--- a/include/llvm/ADT/VariadicFunction.h
+++ b/include/llvm/ADT/VariadicFunction.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_VARIADIC_FUNCTION_H
-#define LLVM_ADT_VARIADIC_FUNCTION_H
+#ifndef LLVM_ADT_VARIADICFUNCTION_H
+#define LLVM_ADT_VARIADICFUNCTION_H
#include "llvm/ADT/ArrayRef.h"
@@ -328,4 +328,4 @@ struct VariadicFunction3 {
} // end namespace llvm
-#endif // LLVM_ADT_VARIADIC_FUNCTION_H
+#endif // LLVM_ADT_VARIADICFUNCTION_H
diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h
index 20cdae3..aeb7848 100644
--- a/include/llvm/ADT/ilist.h
+++ b/include/llvm/ADT/ilist.h
@@ -234,17 +234,17 @@ public:
pointer getNodePtrUnchecked() const { return NodePtr; }
};
-// do not implement. this is to catch errors when people try to use
-// them as random access iterators
+// These are to catch errors when people try to use them as random access
+// iterators.
template<typename T>
-void operator-(int, ilist_iterator<T>);
+void operator-(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
template<typename T>
-void operator-(ilist_iterator<T>,int);
+void operator-(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
template<typename T>
-void operator+(int, ilist_iterator<T>);
+void operator+(int, ilist_iterator<T>) LLVM_DELETED_FUNCTION;
template<typename T>
-void operator+(ilist_iterator<T>,int);
+void operator+(ilist_iterator<T>,int) LLVM_DELETED_FUNCTION;
// operator!=/operator== - Allow mixed comparisons without dereferencing
// the iterator, which could very likely be pointing to end().
diff --git a/include/llvm/ADT/ilist_node.h b/include/llvm/ADT/ilist_node.h
index f008003..0361244 100644
--- a/include/llvm/ADT/ilist_node.h
+++ b/include/llvm/ADT/ilist_node.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_ILIST_NODE_H
-#define LLVM_ADT_ILIST_NODE_H
+#ifndef LLVM_ADT_ILISTNODE_H
+#define LLVM_ADT_ILISTNODE_H
namespace llvm {
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 3ce4732..d703f21 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -34,8 +34,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
-#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
+#ifndef LLVM_ANALYSIS_ALIASANALYSIS_H
+#define LLVM_ANALYSIS_ALIASANALYSIS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/CallSite.h"
@@ -593,11 +593,6 @@ bool isNoAliasCall(const Value *V);
///
bool isIdentifiedObject(const Value *V);
-/// isKnownNonNull - Return true if this pointer couldn't possibly be null by
-/// its definition. This returns true for allocas, non-extern-weak globals and
-/// byval arguments.
-bool isKnownNonNull(const Value *V);
-
} // End llvm namespace
#endif
diff --git a/include/llvm/Analysis/CallGraphSCCPass.h b/include/llvm/Analysis/CallGraphSCCPass.h
index 4446777..e609dac 100644
--- a/include/llvm/Analysis/CallGraphSCCPass.h
+++ b/include/llvm/Analysis/CallGraphSCCPass.h
@@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
-#define LLVM_CALL_GRAPH_SCC_PASS_H
+#ifndef LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
+#define LLVM_ANALYSIS_CALLGRAPHSCCPASS_H
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Pass.h"
diff --git a/include/llvm/Analysis/CallPrinter.h b/include/llvm/Analysis/CallPrinter.h
new file mode 100644
index 0000000..5f5d160
--- /dev/null
+++ b/include/llvm/Analysis/CallPrinter.h
@@ -0,0 +1,27 @@
+//===-- CallPrinter.h - Call graph printer external 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 defines external functions that can be called to explicitly
+// instantiate the call graph printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CALLPRINTER_H
+#define LLVM_ANALYSIS_CALLPRINTER_H
+
+namespace llvm {
+
+ class ModulePass;
+
+ ModulePass *createCallGraphViewerPass();
+ ModulePass *createCallGraphPrinterPass();
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Analysis/CodeMetrics.h b/include/llvm/Analysis/CodeMetrics.h
index 35eabec..086934d 100644
--- a/include/llvm/Analysis/CodeMetrics.h
+++ b/include/llvm/Analysis/CodeMetrics.h
@@ -19,80 +19,75 @@
#include "llvm/Support/CallSite.h"
namespace llvm {
- class BasicBlock;
- class Function;
- class Instruction;
- class DataLayout;
- class Value;
+class BasicBlock;
+class Function;
+class Instruction;
+class DataLayout;
+class TargetTransformInfo;
+class Value;
+
+/// \brief Check whether a call will lower to something small.
+///
+/// This tests checks whether this callsite will lower to something
+/// significantly cheaper than a traditional call, often a single
+/// instruction. Note that if isInstructionFree(CS.getInstruction()) would
+/// return true, so will this function.
+bool callIsSmall(ImmutableCallSite CS);
+
+/// \brief Utility to calculate the size and a few similar metrics for a set
+/// of basic blocks.
+struct CodeMetrics {
+ /// \brief True if this function contains a call to setjmp or other functions
+ /// with attribute "returns twice" without having the attribute itself.
+ bool exposesReturnsTwice;
+
+ /// \brief True if this function calls itself.
+ bool isRecursive;
+
+ /// \brief True if this function cannot be duplicated.
+ ///
+ /// True if this function contains one or more indirect branches, or it contains
+ /// one or more 'noduplicate' instructions.
+ bool notDuplicatable;
+
+ /// \brief True if this function calls alloca (in the C sense).
+ bool usesDynamicAlloca;
+
+ /// \brief Number of instructions in the analyzed blocks.
+ unsigned NumInsts;
- /// \brief Check whether an instruction is likely to be "free" when lowered.
- bool isInstructionFree(const Instruction *I, const DataLayout *TD = 0);
+ /// \brief Number of analyzed blocks.
+ unsigned NumBlocks;
- /// \brief Check whether a call will lower to something small.
+ /// \brief Keeps track of basic block code size estimates.
+ DenseMap<const BasicBlock *, unsigned> NumBBInsts;
+
+ /// \brief Keep track of the number of calls to 'big' functions.
+ unsigned NumCalls;
+
+ /// \brief The number of calls to internal functions with a single caller.
///
- /// This tests checks whether this callsite will lower to something
- /// significantly cheaper than a traditional call, often a single
- /// instruction. Note that if isInstructionFree(CS.getInstruction()) would
- /// return true, so will this function.
- bool callIsSmall(ImmutableCallSite CS);
-
- /// \brief Utility to calculate the size and a few similar metrics for a set
- /// of basic blocks.
- struct CodeMetrics {
- /// \brief True if this function contains a call to setjmp or other functions
- /// with attribute "returns twice" without having the attribute itself.
- bool exposesReturnsTwice;
-
- /// \brief True if this function calls itself.
- bool isRecursive;
-
- /// \brief True if this function cannot be duplicated.
- ///
- /// True if this function contains one or more indirect branches, or it contains
- /// one or more 'noduplicate' instructions.
- bool notDuplicatable;
-
- /// \brief True if this function calls alloca (in the C sense).
- bool usesDynamicAlloca;
-
- /// \brief Number of instructions in the analyzed blocks.
- unsigned NumInsts;
-
- /// \brief Number of analyzed blocks.
- unsigned NumBlocks;
-
- /// \brief Keeps track of basic block code size estimates.
- DenseMap<const BasicBlock *, unsigned> NumBBInsts;
-
- /// \brief Keep track of the number of calls to 'big' functions.
- unsigned NumCalls;
-
- /// \brief The number of calls to internal functions with a single caller.
- ///
- /// These are likely targets for future inlining, likely exposed by
- /// interleaved devirtualization.
- unsigned NumInlineCandidates;
-
- /// \brief How many instructions produce vector values.
- ///
- /// The inliner is more aggressive with inlining vector kernels.
- unsigned NumVectorInsts;
-
- /// \brief How many 'ret' instructions the blocks contain.
- unsigned NumRets;
-
- CodeMetrics() : exposesReturnsTwice(false), isRecursive(false),
- notDuplicatable(false), usesDynamicAlloca(false),
- NumInsts(0), NumBlocks(0), NumCalls(0),
- NumInlineCandidates(0), NumVectorInsts(0),
- NumRets(0) {}
-
- /// \brief Add information about a block to the current state.
- void analyzeBasicBlock(const BasicBlock *BB, const DataLayout *TD = 0);
-
- /// \brief Add information about a function to the current state.
- void analyzeFunction(Function *F, const DataLayout *TD = 0);
- };
+ /// These are likely targets for future inlining, likely exposed by
+ /// interleaved devirtualization.
+ unsigned NumInlineCandidates;
+
+ /// \brief How many instructions produce vector values.
+ ///
+ /// The inliner is more aggressive with inlining vector kernels.
+ unsigned NumVectorInsts;
+
+ /// \brief How many 'ret' instructions the blocks contain.
+ unsigned NumRets;
+
+ CodeMetrics()
+ : exposesReturnsTwice(false), isRecursive(false), notDuplicatable(false),
+ usesDynamicAlloca(false), NumInsts(0), NumBlocks(0), NumCalls(0),
+ NumInlineCandidates(0), NumVectorInsts(0), NumRets(0) {}
+
+ /// \brief Add information about a block to the current state.
+ void analyzeBasicBlock(const BasicBlock *BB, const TargetTransformInfo &TTI);
+};
+
}
#endif
diff --git a/include/llvm/Analysis/DOTGraphTraitsPass.h b/include/llvm/Analysis/DOTGraphTraitsPass.h
index bd8c4a1..0fc1c2d 100644
--- a/include/llvm/Analysis/DOTGraphTraitsPass.h
+++ b/include/llvm/Analysis/DOTGraphTraitsPass.h
@@ -11,27 +11,25 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
-#define LLVM_ANALYSIS_DOT_GRAPHTRAITS_PASS_H
+#ifndef LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
+#define LLVM_ANALYSIS_DOTGRAPHTRAITSPASS_H
#include "llvm/Analysis/CFGPrinter.h"
#include "llvm/Pass.h"
namespace llvm {
-template <class Analysis, bool Simple>
-struct DOTGraphTraitsViewer : public FunctionPass {
- std::string Name;
- DOTGraphTraitsViewer(std::string GraphName, char &ID) : FunctionPass(ID) {
- Name = GraphName;
- }
+template <class Analysis, bool Simple>
+class DOTGraphTraitsViewer : public FunctionPass {
+public:
+ DOTGraphTraitsViewer(StringRef GraphName, char &ID)
+ : FunctionPass(ID), Name(GraphName) {}
virtual bool runOnFunction(Function &F) {
- Analysis *Graph;
- std::string Title, GraphName;
- Graph = &getAnalysis<Analysis>();
- GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- Title = GraphName + " for '" + F.getName().str() + "' function";
+ Analysis *Graph = &getAnalysis<Analysis>();
+ std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
ViewGraph(Graph, Name, Simple, Title);
return false;
@@ -41,36 +39,92 @@ struct DOTGraphTraitsViewer : public FunctionPass {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
+
+private:
+ std::string Name;
};
template <class Analysis, bool Simple>
-struct DOTGraphTraitsPrinter : public FunctionPass {
+class DOTGraphTraitsPrinter : public FunctionPass {
+public:
+ DOTGraphTraitsPrinter(StringRef GraphName, char &ID)
+ : FunctionPass(ID), Name(GraphName) {}
+
+ virtual bool runOnFunction(Function &F) {
+ Analysis *Graph = &getAnalysis<Analysis>();
+ std::string Filename = Name + "." + F.getName().str() + ".dot";
+ std::string ErrorInfo;
+
+ errs() << "Writing '" << Filename << "'...";
+
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo);
+ std::string GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
+ std::string Title = GraphName + " for '" + F.getName().str() + "' function";
+
+ if (ErrorInfo.empty())
+ WriteGraph(File, Graph, Simple, Title);
+ else
+ errs() << " error opening file for writing!";
+ errs() << "\n";
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+private:
std::string Name;
+};
+
+template <class Analysis, bool Simple>
+class DOTGraphTraitsModuleViewer : public ModulePass {
+public:
+ DOTGraphTraitsModuleViewer(StringRef GraphName, char &ID)
+ : ModulePass(ID), Name(GraphName) {}
+
+ virtual bool runOnModule(Module &M) {
+ Analysis *Graph = &getAnalysis<Analysis>();
+ std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- DOTGraphTraitsPrinter(std::string GraphName, char &ID)
- : FunctionPass(ID) {
- Name = GraphName;
+ ViewGraph(Graph, Name, Simple, Title);
+
+ return false;
}
- virtual bool runOnFunction(Function &F) {
- Analysis *Graph;
- std::string Filename = Name + "." + F.getName().str() + ".dot";
- errs() << "Writing '" << Filename << "'...";
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<Analysis>();
+ }
+private:
+ std::string Name;
+};
+
+template <class Analysis, bool Simple>
+class DOTGraphTraitsModulePrinter : public ModulePass {
+public:
+ DOTGraphTraitsModulePrinter(StringRef GraphName, char &ID)
+ : ModulePass(ID), Name(GraphName) {}
+
+ virtual bool runOnModule(Module &M) {
+ Analysis *Graph = &getAnalysis<Analysis>();
+ std::string Filename = Name + ".dot";
std::string ErrorInfo;
- raw_fd_ostream File(Filename.c_str(), ErrorInfo);
- Graph = &getAnalysis<Analysis>();
- std::string Title, GraphName;
- GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph);
- Title = GraphName + " for '" + F.getName().str() + "' function";
+ errs() << "Writing '" << Filename << "'...";
+
+ raw_fd_ostream File(Filename.c_str(), ErrorInfo);
+ std::string Title = DOTGraphTraits<Analysis*>::getGraphName(Graph);
if (ErrorInfo.empty())
WriteGraph(File, Graph, Simple, Title);
else
errs() << " error opening file for writing!";
errs() << "\n";
+
return false;
}
@@ -78,6 +132,11 @@ struct DOTGraphTraitsPrinter : public FunctionPass {
AU.setPreservesAll();
AU.addRequired<Analysis>();
}
+
+private:
+ std::string Name;
};
-}
+
+} // end namespace llvm
+
#endif
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index f49efd9..d0ead39 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -244,8 +244,8 @@ namespace llvm {
/// DependenceAnalysis - This class is the main dependence-analysis driver.
///
class DependenceAnalysis : public FunctionPass {
- void operator=(const DependenceAnalysis &); // do not implement
- DependenceAnalysis(const DependenceAnalysis &); // do not implement
+ void operator=(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
+ DependenceAnalysis(const DependenceAnalysis &) LLVM_DELETED_FUNCTION;
public:
/// depends - Tests for a dependence between the Src and Dst instructions.
/// Returns NULL if no dependence; otherwise, returns a Dependence (or a
diff --git a/include/llvm/Analysis/InlineCost.h b/include/llvm/Analysis/InlineCost.h
index 42e329e..bc7924e 100644
--- a/include/llvm/Analysis/InlineCost.h
+++ b/include/llvm/Analysis/InlineCost.h
@@ -14,125 +14,130 @@
#ifndef LLVM_ANALYSIS_INLINECOST_H
#define LLVM_ANALYSIS_INLINECOST_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/ValueMap.h"
#include "llvm/Analysis/CodeMetrics.h"
-#include "llvm/IR/Function.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
#include <cassert>
#include <climits>
-#include <vector>
namespace llvm {
+class CallSite;
+class DataLayout;
+class Function;
+class TargetTransformInfo;
+
+namespace InlineConstants {
+ // Various magic constants used to adjust heuristics.
+ const int InstrCost = 5;
+ const int IndirectCallThreshold = 100;
+ const int CallPenalty = 25;
+ const int LastCallToStaticBonus = -15000;
+ const int ColdccPenalty = 2000;
+ const int NoreturnPenalty = 10000;
+ /// Do not inline functions which allocate this many bytes on the stack
+ /// when the caller is recursive.
+ const unsigned TotalAllocaSizeRecursiveCaller = 1024;
+}
+
+/// \brief Represents the cost of inlining a function.
+///
+/// This supports special values for functions which should "always" or
+/// "never" be inlined. Otherwise, the cost represents a unitless amount;
+/// smaller values increase the likelihood of the function being inlined.
+///
+/// Objects of this type also provide the adjusted threshold for inlining
+/// based on the information available for a particular callsite. They can be
+/// directly tested to determine if inlining should occur given the cost and
+/// threshold for this cost metric.
+class InlineCost {
+ enum SentinelValues {
+ AlwaysInlineCost = INT_MIN,
+ NeverInlineCost = INT_MAX
+ };
+
+ /// \brief The estimated cost of inlining this callsite.
+ const int Cost;
+
+ /// \brief The adjusted threshold against which this cost was computed.
+ const int Threshold;
+
+ // Trivial constructor, interesting logic in the factory functions below.
+ InlineCost(int Cost, int Threshold) : Cost(Cost), Threshold(Threshold) {}
+
+public:
+ static InlineCost get(int Cost, int Threshold) {
+ assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
+ assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
+ return InlineCost(Cost, Threshold);
+ }
+ static InlineCost getAlways() {
+ return InlineCost(AlwaysInlineCost, 0);
+ }
+ static InlineCost getNever() {
+ return InlineCost(NeverInlineCost, 0);
+ }
- class CallSite;
- class DataLayout;
-
- namespace InlineConstants {
- // Various magic constants used to adjust heuristics.
- const int InstrCost = 5;
- const int IndirectCallThreshold = 100;
- const int CallPenalty = 25;
- const int LastCallToStaticBonus = -15000;
- const int ColdccPenalty = 2000;
- const int NoreturnPenalty = 10000;
- /// Do not inline functions which allocate this many bytes on the stack
- /// when the caller is recursive.
- const unsigned TotalAllocaSizeRecursiveCaller = 1024;
+ /// \brief Test whether the inline cost is low enough for inlining.
+ operator bool() const {
+ return Cost < Threshold;
}
- /// \brief Represents the cost of inlining a function.
+ bool isAlways() const { return Cost == AlwaysInlineCost; }
+ bool isNever() const { return Cost == NeverInlineCost; }
+ bool isVariable() const { return !isAlways() && !isNever(); }
+
+ /// \brief Get the inline cost estimate.
+ /// It is an error to call this on an "always" or "never" InlineCost.
+ int getCost() const {
+ assert(isVariable() && "Invalid access of InlineCost");
+ return Cost;
+ }
+
+ /// \brief Get the cost delta from the threshold for inlining.
+ /// Only valid if the cost is of the variable kind. Returns a negative
+ /// value if the cost is too high to inline.
+ int getCostDelta() const { return Threshold - getCost(); }
+};
+
+/// \brief Cost analyzer used by inliner.
+class InlineCostAnalysis : public CallGraphSCCPass {
+ const DataLayout *TD;
+ const TargetTransformInfo *TTI;
+
+public:
+ static char ID;
+
+ InlineCostAnalysis();
+ ~InlineCostAnalysis();
+
+ // Pass interface implementation.
+ void getAnalysisUsage(AnalysisUsage &AU) const;
+ bool runOnSCC(CallGraphSCC &SCC);
+
+ /// \brief Get an InlineCost object representing the cost of inlining this
+ /// callsite.
///
- /// This supports special values for functions which should "always" or
- /// "never" be inlined. Otherwise, the cost represents a unitless amount;
- /// smaller values increase the likelihood of the function being inlined.
+ /// Note that threshold is passed into this function. Only costs below the
+ /// threshold are computed with any accuracy. The threshold can be used to
+ /// bound the computation necessary to determine whether the cost is
+ /// sufficiently low to warrant inlining.
///
- /// Objects of this type also provide the adjusted threshold for inlining
- /// based on the information available for a particular callsite. They can be
- /// directly tested to determine if inlining should occur given the cost and
- /// threshold for this cost metric.
- class InlineCost {
- enum SentinelValues {
- AlwaysInlineCost = INT_MIN,
- NeverInlineCost = INT_MAX
- };
-
- /// \brief The estimated cost of inlining this callsite.
- const int Cost;
-
- /// \brief The adjusted threshold against which this cost was computed.
- const int Threshold;
-
- // Trivial constructor, interesting logic in the factory functions below.
- InlineCost(int Cost, int Threshold)
- : Cost(Cost), Threshold(Threshold) {}
-
- public:
- static InlineCost get(int Cost, int Threshold) {
- assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value");
- assert(Cost < NeverInlineCost && "Cost crosses sentinel value");
- return InlineCost(Cost, Threshold);
- }
- static InlineCost getAlways() {
- return InlineCost(AlwaysInlineCost, 0);
- }
- static InlineCost getNever() {
- return InlineCost(NeverInlineCost, 0);
- }
-
- /// \brief Test whether the inline cost is low enough for inlining.
- operator bool() const {
- return Cost < Threshold;
- }
-
- bool isAlways() const { return Cost == AlwaysInlineCost; }
- bool isNever() const { return Cost == NeverInlineCost; }
- bool isVariable() const { return !isAlways() && !isNever(); }
-
- /// \brief Get the inline cost estimate.
- /// It is an error to call this on an "always" or "never" InlineCost.
- int getCost() const {
- assert(isVariable() && "Invalid access of InlineCost");
- return Cost;
- }
-
- /// \brief Get the cost delta from the threshold for inlining.
- /// Only valid if the cost is of the variable kind. Returns a negative
- /// value if the cost is too high to inline.
- int getCostDelta() const { return Threshold - getCost(); }
- };
+ /// Also note that calling this function *dynamically* computes the cost of
+ /// inlining the callsite. It is an expensive, heavyweight call.
+ InlineCost getInlineCost(CallSite CS, int Threshold);
+
+ /// \brief Get an InlineCost with the callee explicitly specified.
+ /// This allows you to calculate the cost of inlining a function via a
+ /// pointer. This behaves exactly as the version with no explicit callee
+ /// parameter in all other respects.
+ //
+ // Note: This is used by out-of-tree passes, please do not remove without
+ // adding a replacement API.
+ InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
+
+ /// \brief Minimal filter to detect invalid constructs for inlining.
+ bool isInlineViable(Function &Callee);
+};
- /// InlineCostAnalyzer - Cost analyzer used by inliner.
- class InlineCostAnalyzer {
- // DataLayout if available, or null.
- const DataLayout *TD;
-
- public:
- InlineCostAnalyzer(): TD(0) {}
-
- void setDataLayout(const DataLayout *TData) { TD = TData; }
-
- /// \brief Get an InlineCost object representing the cost of inlining this
- /// callsite.
- ///
- /// Note that threshold is passed into this function. Only costs below the
- /// threshold are computed with any accuracy. The threshold can be used to
- /// bound the computation necessary to determine whether the cost is
- /// sufficiently low to warrant inlining.
- InlineCost getInlineCost(CallSite CS, int Threshold);
-
- /// \brief Get an InlineCost with the callee explicitly specified.
- /// This allows you to calculate the cost of inlining a function via a
- /// pointer. This behaves exactly as the version with no explicit callee
- /// parameter in all other respects.
- //
- // Note: This is used by out-of-tree passes, please do not remove without
- // adding a replacement API.
- InlineCost getInlineCost(CallSite CS, Function *Callee, int Threshold);
-
- /// \brief Minimal filter to detect invalid constructs for inlining.
- bool isInlineViable(Function &Callee);
- };
}
#endif
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index b653e79..d760a4c 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -14,6 +14,19 @@
// ("and i32 %x, %x" -> "%x"). If the simplification is also an instruction
// then it dominates the original instruction.
//
+// These routines implicitly resolve undef uses. The easiest way to be safe when
+// using these routines to obtain simplified values for existing instructions is
+// to always replace all uses of the instructions with the resulting simplified
+// values. This will prevent other code from seeing the same undef uses and
+// resolving them to different values.
+//
+// These routines are designed to tolerate moderately incomplete IR, such as
+// instructions that are not connected to basic blocks yet. However, they do
+// require that all the IR that they encounter be valid. In particular, they
+// require that all non-constant values be defined in the same function, and the
+// same call context of that function (and not split between caller and callee
+// contexts of a directly recursive call, for example).
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_ANALYSIS_INSTRUCTIONSIMPLIFY_H
diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h
index ca8ad73..5ce1260 100644
--- a/include/llvm/Analysis/Interval.h
+++ b/include/llvm/Analysis/Interval.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INTERVAL_H
-#define LLVM_INTERVAL_H
+#ifndef LLVM_ANALYSIS_INTERVAL_H
+#define LLVM_ANALYSIS_INTERVAL_H
#include "llvm/ADT/GraphTraits.h"
#include <vector>
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
index bd9ab20..333f289 100644
--- a/include/llvm/Analysis/IntervalIterator.h
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -30,8 +30,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INTERVAL_ITERATOR_H
-#define LLVM_INTERVAL_ITERATOR_H
+#ifndef LLVM_ANALYSIS_INTERVALITERATOR_H
+#define LLVM_ANALYSIS_INTERVALITERATOR_H
#include "llvm/Analysis/IntervalPartition.h"
#include "llvm/IR/Function.h"
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
index bce84be..8cade58 100644
--- a/include/llvm/Analysis/IntervalPartition.h
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INTERVAL_PARTITION_H
-#define LLVM_INTERVAL_PARTITION_H
+#ifndef LLVM_ANALYSIS_INTERVALPARTITION_H
+#define LLVM_ANALYSIS_INTERVALPARTITION_H
#include "llvm/Analysis/Interval.h"
#include "llvm/Pass.h"
diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h
index 243234b..c01b210 100644
--- a/include/llvm/Analysis/LibCallAliasAnalysis.h
+++ b/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_LIBCALL_AA_H
-#define LLVM_ANALYSIS_LIBCALL_AA_H
+#ifndef LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
+#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Pass.h"
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 830754d..a20e065 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -27,21 +27,17 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_LOOP_INFO_H
-#define LLVM_ANALYSIS_LOOP_INFO_H
+#ifndef LLVM_ANALYSIS_LOOPINFO_H
+#define LLVM_ANALYSIS_LOOPINFO_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/Dominators.h"
#include "llvm/Pass.h"
-#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <map>
namespace llvm {
@@ -381,6 +377,20 @@ public:
/// isSafeToClone - Return true if the loop body is safe to clone in practice.
bool isSafeToClone() const;
+ /// Returns true if the loop is annotated parallel.
+ ///
+ /// A parallel loop can be assumed to not contain any dependencies between
+ /// iterations by the compiler. That is, any loop-carried dependency checking
+ /// can be skipped completely when parallelizing the loop on the target
+ /// machine. Thus, if the parallel loop information originates from the
+ /// programmer, e.g. via the OpenMP parallel for pragma, it is the
+ /// programmer's responsibility to ensure there are no loop-carried
+ /// dependencies. The final execution order of the instructions across
+ /// iterations is not guaranteed, thus, the end result might or might not
+ /// implement actual concurrent execution of instructions across multiple
+ /// iterations.
+ bool isAnnotatedParallel() const;
+
/// hasDedicatedExits - Return true if no exit block for the loop
/// has a predecessor that is outside the loop.
bool hasDedicatedExits() const;
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 4b8e4c9..5485f3c 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_LOOP_INFO_IMPL_H
-#define LLVM_ANALYSIS_LOOP_INFO_IMPL_H
+#ifndef LLVM_ANALYSIS_LOOPINFOIMPL_H
+#define LLVM_ANALYSIS_LOOPINFOIMPL_H
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/LoopInfo.h"
namespace llvm {
diff --git a/include/llvm/Analysis/LoopIterator.h b/include/llvm/Analysis/LoopIterator.h
index 68f25f7..e3dd963 100644
--- a/include/llvm/Analysis/LoopIterator.h
+++ b/include/llvm/Analysis/LoopIterator.h
@@ -21,10 +21,9 @@
// reachable from the loop header.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_LOOP_ITERATOR_H
-#define LLVM_ANALYSIS_LOOP_ITERATOR_H
+#ifndef LLVM_ANALYSIS_LOOPITERATOR_H
+#define LLVM_ANALYSIS_LOOPITERATOR_H
-#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/Analysis/LoopInfo.h"
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
index f78472a..5767c19 100644
--- a/include/llvm/Analysis/LoopPass.h
+++ b/include/llvm/Analysis/LoopPass.h
@@ -12,11 +12,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LOOP_PASS_H
-#define LLVM_LOOP_PASS_H
+#ifndef LLVM_ANALYSIS_LOOPPASS_H
+#define LLVM_ANALYSIS_LOOPPASS_H
#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/IR/Function.h"
#include "llvm/Pass.h"
#include "llvm/PassManagers.h"
#include <deque>
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index f2c564f..f07658f 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -158,7 +158,7 @@ class ObjectSizeOffsetVisitor
bool RoundToAlign;
unsigned IntTyBits;
APInt Zero;
- SmallPtrSet<Value*, 8> SeenInsts;
+ SmallPtrSet<Instruction *, 8> SeenInsts;
APInt align(APInt Size, uint64_t Align);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index b954840..b87f886 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
-#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
+#ifndef LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
+#define LLVM_ANALYSIS_MEMORYDEPENDENCEANALYSIS_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
@@ -34,14 +34,14 @@ namespace llvm {
class PredIteratorCache;
class DominatorTree;
class PHITransAddr;
-
+
/// MemDepResult - A memory dependence query can return one of three different
/// answers, described below.
class MemDepResult {
enum DepType {
/// Invalid - Clients of MemDep never see this.
Invalid = 0,
-
+
/// Clobber - This is a dependence on the specified instruction which
/// clobbers the desired value. The pointer member of the MemDepResult
/// pair holds the instruction that clobbers the memory. For example,
@@ -72,7 +72,7 @@ namespace llvm {
/// and no intervening clobbers. No validation is done that the
/// operands to the calls are the same.
Def,
-
+
/// Other - This marker indicates that the query has no known dependency
/// in the specified block. More detailed state info is encoded in the
/// upper part of the pair (i.e. the Instruction*)
@@ -99,7 +99,7 @@ namespace llvm {
explicit MemDepResult(PairTy V) : Value(V) {}
public:
MemDepResult() : Value(0, Invalid) {}
-
+
/// get methods: These are static ctor methods for creating various
/// MemDepResult kinds.
static MemDepResult getDef(Instruction *Inst) {
@@ -130,7 +130,7 @@ namespace llvm {
/// isDef - Return true if this MemDepResult represents a query that is
/// an instruction definition dependency.
bool isDef() const { return Value.getInt() == Def; }
-
+
/// isNonLocal - Return true if this MemDepResult represents a query that
/// is transparent to the start of the block, but where a non-local hasn't
/// been done.
@@ -145,7 +145,7 @@ namespace llvm {
return Value.getInt() == Other
&& Value.getPointer() == reinterpret_cast<Instruction*>(NonFuncLocal);
}
-
+
/// isUnknown - Return true if this MemDepResult represents a query which
/// cannot and/or will not be computed.
bool isUnknown() const {
@@ -159,7 +159,7 @@ namespace llvm {
if (Value.getInt() == Other) return NULL;
return Value.getPointer();
}
-
+
bool operator==(const MemDepResult &M) const { return Value == M.Value; }
bool operator!=(const MemDepResult &M) const { return Value != M.Value; }
bool operator<(const MemDepResult &M) const { return Value < M.Value; }
@@ -175,11 +175,11 @@ namespace llvm {
/// In a default-constructed MemDepResult object, the type will be Dirty
/// and the instruction pointer will be null.
///
-
+
/// isDirty - Return true if this is a MemDepResult in its dirty/invalid.
/// state.
bool isDirty() const { return Value.getInt() == Invalid; }
-
+
static MemDepResult getDirty(Instruction *Inst) {
return MemDepResult(PairTy(Inst, Invalid));
}
@@ -199,16 +199,16 @@ namespace llvm {
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return BB; }
-
+
void setResult(const MemDepResult &R) { Result = R; }
const MemDepResult &getResult() const { return Result; }
-
+
bool operator<(const NonLocalDepEntry &RHS) const {
return BB < RHS.BB;
}
};
-
+
/// NonLocalDepResult - This is a result from a NonLocal dependence query.
/// For each BasicBlock (the BB entry) it keeps a MemDepResult and the
/// (potentially phi translated) address that was live in the block.
@@ -218,17 +218,17 @@ namespace llvm {
public:
NonLocalDepResult(BasicBlock *bb, MemDepResult result, Value *address)
: Entry(bb, result), Address(address) {}
-
+
// BB is the sort key, it can't be changed.
BasicBlock *getBB() const { return Entry.getBB(); }
-
+
void setResult(const MemDepResult &R, Value *Addr) {
Entry.setResult(R);
Address = Addr;
}
-
+
const MemDepResult &getResult() const { return Entry.getResult(); }
-
+
/// getAddress - Return the address of this pointer in this block. This can
/// be different than the address queried for the non-local result because
/// of phi translation. This returns null if the address was not available
@@ -238,7 +238,7 @@ namespace llvm {
/// The address is always null for a non-local 'call' dependence.
Value *getAddress() const { return Address; }
};
-
+
/// MemoryDependenceAnalysis - This is an analysis that determines, for a
/// given memory operation, what preceding memory operations it depends on.
/// It builds on alias analysis information, and tries to provide a lazy,
@@ -297,30 +297,30 @@ namespace llvm {
CachedNonLocalPointerInfo NonLocalPointerDeps;
// A map from instructions to their non-local pointer dependencies.
- typedef DenseMap<Instruction*,
+ typedef DenseMap<Instruction*,
SmallPtrSet<ValueIsLoadPair, 4> > ReverseNonLocalPtrDepTy;
ReverseNonLocalPtrDepTy ReverseNonLocalPtrDeps;
-
+
/// PerInstNLInfo - This is the instruction we keep for each cached access
/// that we have for an instruction. The pointer is an owning pointer and
/// the bool indicates whether we have any dirty bits in the set.
typedef std::pair<NonLocalDepInfo, bool> PerInstNLInfo;
-
+
// A map from instructions to their non-local dependencies.
typedef DenseMap<Instruction*, PerInstNLInfo> NonLocalDepMapType;
-
+
NonLocalDepMapType NonLocalDeps;
-
+
// A reverse mapping from dependencies to the dependees. This is
// used when removing instructions to keep the cache coherent.
typedef DenseMap<Instruction*,
SmallPtrSet<Instruction*, 4> > ReverseDepMapType;
ReverseDepMapType ReverseLocalDeps;
-
+
// A reverse mapping from dependencies to the non-local dependees.
ReverseDepMapType ReverseNonLocalDeps;
-
+
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
DataLayout *TD;
@@ -333,15 +333,15 @@ namespace llvm {
/// Pass Implementation stuff. This doesn't do any analysis eagerly.
bool runOnFunction(Function &);
-
+
/// Clean up memory in between runs
void releaseMemory();
-
+
/// getAnalysisUsage - Does not modify anything. It uses Value Numbering
/// and Alias Analysis.
///
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-
+
/// getDependency - Return the instruction on which a memory operation
/// depends. See the class comment for more details. It is illegal to call
/// this on non-memory instructions.
@@ -360,8 +360,8 @@ namespace llvm {
/// removed. Clients must copy this data if they want it around longer than
/// that.
const NonLocalDepInfo &getNonLocalCallDependency(CallSite QueryCS);
-
-
+
+
/// getNonLocalPointerDependency - Perform a full dependency query for an
/// access to the specified (non-volatile) memory location, returning the
/// set of instructions that either define or clobber the value.
@@ -374,7 +374,7 @@ namespace llvm {
/// removeInstruction - Remove an instruction from the dependence analysis,
/// updating the dependence of instructions that previously depended on it.
void removeInstruction(Instruction *InstToRemove);
-
+
/// invalidateCachedPointerInfo - This method is used to invalidate cached
/// information about the specified pointer, because it may be too
/// conservative in memdep. This is an optional call that can be used when
@@ -387,7 +387,7 @@ namespace llvm {
/// This needs to be done when the CFG changes, e.g., due to splitting
/// critical edges.
void invalidateCachedPredecessors();
-
+
/// getPointerDependencyFrom - Return the instruction on which a memory
/// location depends. If isLoad is true, this routine ignores may-aliases
/// with read-only operations. If isLoad is false, this routine ignores
@@ -396,11 +396,11 @@ namespace llvm {
/// Note that this is an uncached query, and thus may be inefficient.
///
MemDepResult getPointerDependencyFrom(const AliasAnalysis::Location &Loc,
- bool isLoad,
+ bool isLoad,
BasicBlock::iterator ScanIt,
BasicBlock *BB);
-
-
+
+
/// getLoadLoadClobberFullWidthSize - This is a little bit of analysis that
/// looks at a memory location for a load (specified by MemLocBase, Offs,
/// and Size) and compares it against a load. If the specified load could
@@ -413,7 +413,7 @@ namespace llvm {
unsigned MemLocSize,
const LoadInst *LI,
const DataLayout &TD);
-
+
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
BasicBlock::iterator ScanIt,
@@ -430,11 +430,11 @@ namespace llvm {
unsigned NumSortedEntries);
void RemoveCachedNonLocalPointerDependencies(ValueIsLoadPair P);
-
+
/// verifyRemoved - Verify that the specified instruction does not occur
/// in our internal data structures.
void verifyRemoved(Instruction *Inst) const;
-
+
};
} // End llvm namespace
diff --git a/include/llvm/Analysis/PathNumbering.h b/include/llvm/Analysis/PathNumbering.h
index 86b1520..400a37d 100644
--- a/include/llvm/Analysis/PathNumbering.h
+++ b/include/llvm/Analysis/PathNumbering.h
@@ -23,8 +23,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PATH_NUMBERING_H
-#define LLVM_PATH_NUMBERING_H
+#ifndef LLVM_ANALYSIS_PATHNUMBERING_H
+#define LLVM_ANALYSIS_PATHNUMBERING_H
#include "llvm/Analysis/ProfileInfoTypes.h"
#include "llvm/IR/BasicBlock.h"
diff --git a/include/llvm/Analysis/PathProfileInfo.h b/include/llvm/Analysis/PathProfileInfo.h
index 8684f41..4fce16e 100644
--- a/include/llvm/Analysis/PathProfileInfo.h
+++ b/include/llvm/Analysis/PathProfileInfo.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PATHPROFILEINFO_H
-#define LLVM_PATHPROFILEINFO_H
+#ifndef LLVM_ANALYSIS_PATHPROFILEINFO_H
+#define LLVM_ANALYSIS_PATHPROFILEINFO_H
#include "llvm/Analysis/PathNumbering.h"
#include "llvm/IR/BasicBlock.h"
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index 0eddb91..d082297 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
-#define LLVM_ANALYSIS_POST_DOMINATORS_H
+#ifndef LLVM_ANALYSIS_POSTDOMINATORS_H
+#define LLVM_ANALYSIS_POSTDOMINATORS_H
#include "llvm/Analysis/Dominators.h"
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 48d7ee6..69cc293 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_REGION_INFO_H
-#define LLVM_ANALYSIS_REGION_INFO_H
+#ifndef LLVM_ANALYSIS_REGIONINFO_H
+#define LLVM_ANALYSIS_REGIONINFO_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Analysis/DominanceFrontier.h"
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index bcff227..8fd4263 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
// This file defines the iterators to iterate over the elements of a Region.
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_REGION_ITERATOR_H
-#define LLVM_ANALYSIS_REGION_ITERATOR_H
+#ifndef LLVM_ANALYSIS_REGIONITERATOR_H
+#define LLVM_ANALYSIS_REGIONITERATOR_H
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
diff --git a/include/llvm/Analysis/RegionPass.h b/include/llvm/Analysis/RegionPass.h
index 54f96d6..0690ac5 100644
--- a/include/llvm/Analysis/RegionPass.h
+++ b/include/llvm/Analysis/RegionPass.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_REGION_PASS_H
-#define LLVM_REGION_PASS_H
+#ifndef LLVM_ANALYSIS_REGIONPASS_H
+#define LLVM_ANALYSIS_REGIONPASS_H
#include "llvm/Analysis/RegionInfo.h"
#include "llvm/IR/Function.h"
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index ea45aff..00779fc 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
-#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPANDER_H
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
@@ -40,8 +40,10 @@ namespace llvm {
// 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 caches Values for reuse, so must track RAUW.
+ std::map<std::pair<const SCEV *, Instruction *>, TrackingVH<Value> >
InsertedExpressions;
+ // InsertedValues only flags inserted instructions so needs no RAUW.
std::set<AssertingVH<Value> > InsertedValues;
std::set<AssertingVH<Value> > InsertedPostIncValues;
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
index b74cb33..eac9113 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpressions.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
-#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONEXPRESSIONS_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/ScalarEvolution.h"
@@ -548,6 +548,151 @@ namespace llvm {
SCEVTraversal<SV> T(Visitor);
T.visitAll(Root);
}
+
+ /// The SCEVRewriter takes a scalar evolution expression and copies all its
+ /// components. The result after a rewrite is an identical SCEV.
+ struct SCEVRewriter
+ : public SCEVVisitor<SCEVRewriter, const SCEV*> {
+ public:
+ SCEVRewriter(ScalarEvolution &S) : SE(S) {}
+
+ virtual ~SCEVRewriter() {}
+
+ virtual const SCEV *visitConstant(const SCEVConstant *Constant) {
+ return Constant;
+ }
+
+ virtual const SCEV *visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+ const SCEV *Operand = visit(Expr->getOperand());
+ return SE.getTruncateExpr(Operand, Expr->getType());
+ }
+
+ virtual const SCEV *visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+ const SCEV *Operand = visit(Expr->getOperand());
+ return SE.getZeroExtendExpr(Operand, Expr->getType());
+ }
+
+ virtual const SCEV *visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+ const SCEV *Operand = visit(Expr->getOperand());
+ return SE.getSignExtendExpr(Operand, Expr->getType());
+ }
+
+ virtual const SCEV *visitAddExpr(const SCEVAddExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+ return SE.getAddExpr(Operands);
+ }
+
+ virtual const SCEV *visitMulExpr(const SCEVMulExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+ return SE.getMulExpr(Operands);
+ }
+
+ virtual const SCEV *visitUDivExpr(const SCEVUDivExpr *Expr) {
+ return SE.getUDivExpr(visit(Expr->getLHS()), visit(Expr->getRHS()));
+ }
+
+ virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+ return SE.getAddRecExpr(Operands, Expr->getLoop(),
+ Expr->getNoWrapFlags());
+ }
+
+ virtual const SCEV *visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+ return SE.getSMaxExpr(Operands);
+ }
+
+ virtual const SCEV *visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+ return SE.getUMaxExpr(Operands);
+ }
+
+ virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+ return Expr;
+ }
+
+ virtual const SCEV *visitCouldNotCompute(const SCEVCouldNotCompute *Expr) {
+ return Expr;
+ }
+
+ protected:
+ ScalarEvolution &SE;
+ };
+
+ typedef DenseMap<const Value*, Value*> ValueToValueMap;
+
+ /// The SCEVParameterRewriter takes a scalar evolution expression and updates
+ /// the SCEVUnknown components following the Map (Value -> Value).
+ struct SCEVParameterRewriter: public SCEVRewriter {
+ public:
+ static const SCEV *rewrite(const SCEV *Scev, ScalarEvolution &SE,
+ ValueToValueMap &Map) {
+ SCEVParameterRewriter Rewriter(SE, Map);
+ return Rewriter.visit(Scev);
+ }
+ SCEVParameterRewriter(ScalarEvolution &S, ValueToValueMap &M)
+ : SCEVRewriter(S), Map(M) {}
+
+ virtual const SCEV *visitUnknown(const SCEVUnknown *Expr) {
+ Value *V = Expr->getValue();
+ if (Map.count(V))
+ return SE.getUnknown(Map[V]);
+ return Expr;
+ }
+
+ private:
+ ValueToValueMap &Map;
+ };
+
+ typedef DenseMap<const Loop*, const SCEV*> LoopToScevMapT;
+
+ /// The SCEVApplyRewriter takes a scalar evolution expression and applies
+ /// the Map (Loop -> SCEV) to all AddRecExprs.
+ struct SCEVApplyRewriter: public SCEVRewriter {
+ public:
+ static const SCEV *rewrite(const SCEV *Scev, LoopToScevMapT &Map,
+ ScalarEvolution &SE) {
+ SCEVApplyRewriter Rewriter(SE, Map);
+ return Rewriter.visit(Scev);
+ }
+ SCEVApplyRewriter(ScalarEvolution &S, LoopToScevMapT &M)
+ : SCEVRewriter(S), Map(M) {}
+
+ virtual const SCEV *visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+ SmallVector<const SCEV *, 2> Operands;
+ for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+ Operands.push_back(visit(Expr->getOperand(i)));
+
+ const Loop *L = Expr->getLoop();
+ const SCEV *Res = SE.getAddRecExpr(Operands, L, Expr->getNoWrapFlags());
+
+ if (0 == Map.count(L))
+ return Res;
+
+ const SCEVAddRecExpr *Rec = (const SCEVAddRecExpr *) Res;
+ return Rec->evaluateAtIteration(Map[L], SE);
+ }
+
+ private:
+ LoopToScevMapT &Map;
+ };
+
+/// Applies the Map (Loop -> SCEV) to the given Scev.
+static inline const SCEV *apply(const SCEV *Scev, LoopToScevMapT &Map,
+ ScalarEvolution &SE) {
+ return SCEVApplyRewriter::rewrite(Scev, Map, SE);
+}
+
}
#endif
diff --git a/include/llvm/Analysis/ScalarEvolutionNormalization.h b/include/llvm/Analysis/ScalarEvolutionNormalization.h
index 342e5937..7c6423a 100644
--- a/include/llvm/Analysis/ScalarEvolutionNormalization.h
+++ b/include/llvm/Analysis/ScalarEvolutionNormalization.h
@@ -33,8 +33,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
-#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTIONNORMALIZATION_H
#include "llvm/ADT/SmallPtrSet.h"
diff --git a/include/llvm/Analysis/SparsePropagation.h b/include/llvm/Analysis/SparsePropagation.h
index 604e306..76c8ccf 100644
--- a/include/llvm/Analysis/SparsePropagation.h
+++ b/include/llvm/Analysis/SparsePropagation.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_SPARSE_PROPAGATION_H
-#define LLVM_ANALYSIS_SPARSE_PROPAGATION_H
+#ifndef LLVM_ANALYSIS_SPARSEPROPAGATION_H
+#define LLVM_ANALYSIS_SPARSEPROPAGATION_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -203,4 +203,4 @@ private:
} // end namespace llvm
-#endif // LLVM_ANALYSIS_SPARSE_PROPAGATION_H
+#endif // LLVM_ANALYSIS_SPARSEPROPAGATION_H
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index ddf615f..e1331a1 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -19,9 +19,10 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_TARGET_TRANSFORM_INTERFACE
-#define LLVM_ANALYSIS_TARGET_TRANSFORM_INTERFACE
+#ifndef LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
+#define LLVM_ANALYSIS_TARGETTRANSFORMINFO_H
+#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
@@ -67,6 +68,123 @@ public:
/// This class is intended to be subclassed by real implementations.
virtual ~TargetTransformInfo() = 0;
+ /// \name Generic Target Information
+ /// @{
+
+ /// \brief Underlying constants for 'cost' values in this interface.
+ ///
+ /// Many APIs in this interface return a cost. This enum defines the
+ /// fundamental values that should be used to interpret (and produce) those
+ /// costs. The costs are returned as an unsigned rather than a member of this
+ /// enumeration because it is expected that the cost of one IR instruction
+ /// may have a multiplicative factor to it or otherwise won't fit dircetly
+ /// into the enum. Moreover, it is common to sum or average costs which works
+ /// better as simple integral values. Thus this enum only provides constants.
+ ///
+ /// Note that these costs should usually reflect the intersection of code-size
+ /// cost and execution cost. A free instruction is typically one that folds
+ /// into another instruction. For example, reg-to-reg moves can often be
+ /// skipped by renaming the registers in the CPU, but they still are encoded
+ /// and thus wouldn't be considered 'free' here.
+ enum TargetCostConstants {
+ TCC_Free = 0, ///< Expected to fold away in lowering.
+ TCC_Basic = 1, ///< The cost of a typical 'add' instruction.
+ TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86.
+ };
+
+ /// \brief Estimate the cost of a specific operation when lowered.
+ ///
+ /// Note that this is designed to work on an arbitrary synthetic opcode, and
+ /// thus work for hypothetical queries before an instruction has even been
+ /// formed. However, this does *not* work for GEPs, and must not be called
+ /// for a GEP instruction. Instead, use the dedicated getGEPCost interface as
+ /// analyzing a GEP's cost required more information.
+ ///
+ /// Typically only the result type is required, and the operand type can be
+ /// omitted. However, if the opcode is one of the cast instructions, the
+ /// operand type is required.
+ ///
+ /// The returned cost is defined in terms of \c TargetCostConstants, see its
+ /// comments for a detailed explanation of the cost values.
+ virtual unsigned getOperationCost(unsigned Opcode, Type *Ty,
+ Type *OpTy = 0) const;
+
+ /// \brief Estimate the cost of a GEP operation when lowered.
+ ///
+ /// The contract for this function is the same as \c getOperationCost except
+ /// that it supports an interface that provides extra information specific to
+ /// the GEP operation.
+ virtual unsigned getGEPCost(const Value *Ptr,
+ ArrayRef<const Value *> Operands) const;
+
+ /// \brief Estimate the cost of a function call when lowered.
+ ///
+ /// The contract for this is the same as \c getOperationCost except that it
+ /// supports an interface that provides extra information specific to call
+ /// instructions.
+ ///
+ /// This is the most basic query for estimating call cost: it only knows the
+ /// function type and (potentially) the number of arguments at the call site.
+ /// The latter is only interesting for varargs function types.
+ virtual unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const;
+
+ /// \brief Estimate the cost of calling a specific function when lowered.
+ ///
+ /// This overload adds the ability to reason about the particular function
+ /// being called in the event it is a library call with special lowering.
+ virtual unsigned getCallCost(const Function *F, int NumArgs = -1) const;
+
+ /// \brief Estimate the cost of calling a specific function when lowered.
+ ///
+ /// This overload allows specifying a set of candidate argument values.
+ virtual unsigned getCallCost(const Function *F,
+ ArrayRef<const Value *> Arguments) const;
+
+ /// \brief Estimate the cost of an intrinsic when lowered.
+ ///
+ /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
+ virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<Type *> ParamTys) const;
+
+ /// \brief Estimate the cost of an intrinsic when lowered.
+ ///
+ /// Mirrors the \c getCallCost method but uses an intrinsic identifier.
+ virtual unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy,
+ ArrayRef<const Value *> Arguments) const;
+
+ /// \brief Estimate the cost of a given IR user when lowered.
+ ///
+ /// This can estimate the cost of either a ConstantExpr or Instruction when
+ /// lowered. It has two primary advantages over the \c getOperationCost and
+ /// \c getGEPCost above, and one significant disadvantage: it can only be
+ /// used when the IR construct has already been formed.
+ ///
+ /// The advantages are that it can inspect the SSA use graph to reason more
+ /// accurately about the cost. For example, all-constant-GEPs can often be
+ /// folded into a load or other instruction, but if they are used in some
+ /// other context they may not be folded. This routine can distinguish such
+ /// cases.
+ ///
+ /// The returned cost is defined in terms of \c TargetCostConstants, see its
+ /// comments for a detailed explanation of the cost values.
+ virtual unsigned getUserCost(const User *U) const;
+
+ /// \brief Test whether calls to a function lower to actual program function
+ /// calls.
+ ///
+ /// The idea is to test whether the program is likely to require a 'call'
+ /// instruction or equivalent in order to call the given function.
+ ///
+ /// FIXME: It's not clear that this is a good or useful query API. Client's
+ /// should probably move to simpler cost metrics using the above.
+ /// Alternatively, we could split the cost interface into distinct code-size
+ /// and execution-speed costs. This would allow modelling the core of this
+ /// query more accurately as the a call is a single small instruction, but
+ /// incurs significant execution cost.
+ virtual bool isLoweredToCall(const Function *F) const;
+
+ /// @}
+
/// \name Scalar Target Information
/// @{
@@ -148,6 +266,14 @@ public:
/// set to false, it returns the number of scalar registers.
virtual unsigned getNumberOfRegisters(bool Vector) const;
+ /// \return The width of the largest scalar or vector register type.
+ virtual unsigned getRegisterBitWidth(bool Vector) const;
+
+ /// \return The maximum unroll factor that the vectorizer should try to
+ /// perform for this target. This number depends on the level of parallelism
+ /// and the number of execution units in the CPU.
+ virtual unsigned getMaximumUnrollFactor() const;
+
/// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc.
virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const;
@@ -188,6 +314,12 @@ public:
/// split during legalization. Zero is returned when the answer is unknown.
virtual unsigned getNumberOfParts(Type *Tp) const;
+ /// \returns The cost of the address computation. For most targets this can be
+ /// merged into the instruction indexing mode. Some targets might want to
+ /// distinguish between address computation for memory operations on vector
+ /// types and scalar types. Such targets should override this function.
+ virtual unsigned getAddressComputationCost(Type *Ty) const;
+
/// @}
/// Analysis group identification.
diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h
index 26947fe..bedd654 100644
--- a/include/llvm/Analysis/Trace.h
+++ b/include/llvm/Analysis/Trace.h
@@ -116,4 +116,4 @@ public:
} // end namespace llvm
-#endif // TRACE_H
+#endif // LLVM_ANALYSIS_TRACE_H
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index 875c47d..3775ec9 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -117,10 +117,10 @@ namespace llvm {
/// it can be expressed as a base pointer plus a constant offset. Return the
/// base and offset to the caller.
Value *GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset,
- const DataLayout &TD);
+ const DataLayout *TD);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
- const DataLayout &TD) {
+ const DataLayout *TD) {
return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
}
@@ -183,6 +183,11 @@ namespace llvm {
bool isSafeToSpeculativelyExecute(const Value *V,
const DataLayout *TD = 0);
+ /// isKnownNonNull - Return true if this pointer couldn't possibly be null by
+ /// its definition. This returns true for allocas, non-extern-weak globals
+ /// and byval arguments.
+ bool isKnownNonNull(const Value *V);
+
} // end namespace llvm
#endif
diff --git a/include/llvm/Assembly/PrintModulePass.h b/include/llvm/Assembly/PrintModulePass.h
index 239fbcc..02b9bd9 100644
--- a/include/llvm/Assembly/PrintModulePass.h
+++ b/include/llvm/Assembly/PrintModulePass.h
@@ -23,6 +23,7 @@
namespace llvm {
class FunctionPass;
class ModulePass;
+ class BasicBlockPass;
class raw_ostream;
/// createPrintModulePass - Create and return a pass that writes the
@@ -37,6 +38,11 @@ namespace llvm {
raw_ostream *OS,
bool DeleteStream=false);
+ /// createPrintBasicBlockPass - Create and return a pass that writes the
+ /// BB to the specified raw_ostream.
+ BasicBlockPass *createPrintBasicBlockPass(raw_ostream *OS,
+ bool DeleteStream=false,
+ const std::string &Banner = "");
} // End llvm namespace
#endif
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index 5b60f72..2d2976c 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef BITSTREAM_READER_H
-#define BITSTREAM_READER_H
+#ifndef LLVM_BITCODE_BITSTREAMREADER_H
+#define LLVM_BITCODE_BITSTREAMREADER_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/BitCodes.h"
@@ -27,6 +27,11 @@ namespace llvm {
class Deserializer;
+/// BitstreamReader - This class is used to read from an LLVM bitcode stream,
+/// maintaining information that is global to decoding the entire file. While
+/// a file is being read, multiple cursors can be independently advanced or
+/// skipped around within the file. These are represented by the
+/// BitstreamCursor class.
class BitstreamReader {
public:
/// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
@@ -119,20 +124,63 @@ public:
BlockInfoRecords.back().BlockID = BlockID;
return BlockInfoRecords.back();
}
+};
+
+/// BitstreamEntry - When advancing through a bitstream cursor, each advance can
+/// discover a few different kinds of entries:
+/// Error - Malformed bitcode was found.
+/// EndBlock - We've reached the end of the current block, (or the end of the
+/// file, which is treated like a series of EndBlock records.
+/// SubBlock - This is the start of a new subblock of a specific ID.
+/// Record - This is a record with a specific AbbrevID.
+///
+struct BitstreamEntry {
+ enum {
+ Error,
+ EndBlock,
+ SubBlock,
+ Record
+ } Kind;
+
+ unsigned ID;
+
+ static BitstreamEntry getError() {
+ BitstreamEntry E; E.Kind = Error; return E;
+ }
+ static BitstreamEntry getEndBlock() {
+ BitstreamEntry E; E.Kind = EndBlock; return E;
+ }
+ static BitstreamEntry getSubBlock(unsigned ID) {
+ BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E;
+ }
+ static BitstreamEntry getRecord(unsigned AbbrevID) {
+ BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E;
+ }
};
+/// BitstreamCursor - This represents a position within a bitcode file. There
+/// may be multiple independent cursors reading within one bitstream, each
+/// maintaining their own local state.
+///
+/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not
+/// be passed by value.
class BitstreamCursor {
friend class Deserializer;
BitstreamReader *BitStream;
size_t NextChar;
- /// CurWord - This is the current data we have pulled from the stream but have
- /// not returned to the client.
- uint32_t CurWord;
+
+ /// CurWord/word_t - This is the current data we have pulled from the stream
+ /// but have not returned to the client. This is specifically and
+ /// intentionally defined to follow the word size of the host machine for
+ /// efficiency. We use word_t in places that are aware of this to make it
+ /// perfectly explicit what is going on.
+ typedef uint32_t word_t;
+ word_t CurWord;
/// BitsInCurWord - This is the number of bits in CurWord that are valid. This
- /// is always from [0...31] inclusive.
+ /// is always from [0...31/63] inclusive (depending on word size).
unsigned BitsInCurWord;
// CurCodeSize - This is the declared size of code values used for the current
@@ -151,6 +199,7 @@ class BitstreamCursor {
/// BlockScope - This tracks the codesize of parent blocks.
SmallVector<Block, 8> BlockScope;
+
public:
BitstreamCursor() : BitStream(0), NextChar(0) {
}
@@ -179,53 +228,10 @@ public:
freeState();
}
- void operator=(const BitstreamCursor &RHS) {
- freeState();
-
- BitStream = RHS.BitStream;
- NextChar = RHS.NextChar;
- CurWord = RHS.CurWord;
- BitsInCurWord = RHS.BitsInCurWord;
- CurCodeSize = RHS.CurCodeSize;
-
- // Copy abbreviations, and bump ref counts.
- CurAbbrevs = RHS.CurAbbrevs;
- for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
- i != e; ++i)
- CurAbbrevs[i]->addRef();
-
- // Copy block scope and bump ref counts.
- BlockScope = RHS.BlockScope;
- for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
- S != e; ++S) {
- std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
- for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
- i != e; ++i)
- Abbrevs[i]->addRef();
- }
- }
-
- void freeState() {
- // Free all the Abbrevs.
- for (unsigned i = 0, e = static_cast<unsigned>(CurAbbrevs.size());
- i != e; ++i)
- CurAbbrevs[i]->dropRef();
- CurAbbrevs.clear();
-
- // Free all the Abbrevs in the block scope.
- for (unsigned S = 0, e = static_cast<unsigned>(BlockScope.size());
- S != e; ++S) {
- std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
- for (unsigned i = 0, e = static_cast<unsigned>(Abbrevs.size());
- i != e; ++i)
- Abbrevs[i]->dropRef();
- }
- BlockScope.clear();
- }
-
- /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
- unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
+ void operator=(const BitstreamCursor &RHS);
+ void freeState();
+
bool isEndPos(size_t pos) {
return BitStream->getBitcodeBytes().isObjectEnd(static_cast<uint64_t>(pos));
}
@@ -236,26 +242,19 @@ public:
static_cast<uint64_t>(pos - 1));
}
- unsigned char getByte(size_t pos) {
- uint8_t byte = -1;
- BitStream->getBitcodeBytes().readByte(pos, &byte);
- return byte;
- }
-
uint32_t getWord(size_t pos) {
- uint8_t buf[sizeof(uint32_t)];
- memset(buf, 0xFF, sizeof(buf));
- BitStream->getBitcodeBytes().readBytes(pos,
- sizeof(buf),
- buf,
- NULL);
+ uint8_t buf[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
+ BitStream->getBitcodeBytes().readBytes(pos, sizeof(buf), buf, NULL);
return *reinterpret_cast<support::ulittle32_t *>(buf);
}
bool AtEndOfStream() {
- return isEndPos(NextChar) && BitsInCurWord == 0;
+ return BitsInCurWord == 0 && isEndPos(NextChar);
}
+ /// getAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
+ unsigned getAbbrevIDWidth() const { return CurCodeSize; }
+
/// GetCurrentBitNo - Return the bit # of the bit we are reading.
uint64_t GetCurrentBitNo() const {
return NextChar*CHAR_BIT - BitsInCurWord;
@@ -268,11 +267,64 @@ public:
return BitStream;
}
+ /// Flags that modify the behavior of advance().
+ enum {
+ /// AF_DontPopBlockAtEnd - If this flag is used, the advance() method does
+ /// not automatically pop the block scope when the end of a block is
+ /// reached.
+ AF_DontPopBlockAtEnd = 1,
+
+ /// AF_DontAutoprocessAbbrevs - If this flag is used, abbrev entries are
+ /// returned just like normal records.
+ AF_DontAutoprocessAbbrevs = 2
+ };
+
+ /// advance - Advance the current bitstream, returning the next entry in the
+ /// stream.
+ BitstreamEntry advance(unsigned Flags = 0) {
+ while (1) {
+ unsigned Code = ReadCode();
+ if (Code == bitc::END_BLOCK) {
+ // Pop the end of the block unless Flags tells us not to.
+ if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd())
+ return BitstreamEntry::getError();
+ return BitstreamEntry::getEndBlock();
+ }
+
+ if (Code == bitc::ENTER_SUBBLOCK)
+ return BitstreamEntry::getSubBlock(ReadSubBlockID());
+
+ if (Code == bitc::DEFINE_ABBREV &&
+ !(Flags & AF_DontAutoprocessAbbrevs)) {
+ // We read and accumulate abbrev's, the client can't do anything with
+ // them anyway.
+ ReadAbbrevRecord();
+ continue;
+ }
+
+ return BitstreamEntry::getRecord(Code);
+ }
+ }
+
+ /// advanceSkippingSubblocks - This is a convenience function for clients that
+ /// don't expect any subblocks. This just skips over them automatically.
+ BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) {
+ while (1) {
+ // If we found a normal entry, return it.
+ BitstreamEntry Entry = advance(Flags);
+ if (Entry.Kind != BitstreamEntry::SubBlock)
+ return Entry;
+
+ // If we found a sub-block, just skip over it and check the next entry.
+ if (SkipBlock())
+ return BitstreamEntry::getError();
+ }
+ }
/// JumpToBit - Reset the stream to the specified bit number.
void JumpToBit(uint64_t BitNo) {
- uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
- uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
+ uintptr_t ByteNo = uintptr_t(BitNo/8) & ~(sizeof(word_t)-1);
+ unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1));
assert(canSkipToPos(ByteNo) && "Invalid location");
// Move the cursor to the right word.
@@ -281,16 +333,22 @@ public:
CurWord = 0;
// Skip over any bits that are already consumed.
- if (WordBitNo)
- Read(static_cast<unsigned>(WordBitNo));
+ if (WordBitNo) {
+ if (sizeof(word_t) > 4)
+ Read64(WordBitNo);
+ else
+ Read(WordBitNo);
+ }
}
uint32_t Read(unsigned NumBits) {
- assert(NumBits <= 32 && "Cannot return more than 32 bits!");
+ assert(NumBits && NumBits <= 32 &&
+ "Cannot return zero or more than 32 bits!");
+
// If the field is fully contained by CurWord, return it quickly.
if (BitsInCurWord >= NumBits) {
- uint32_t R = CurWord & ((1U << NumBits)-1);
+ uint32_t R = uint32_t(CurWord) & (~0U >> (32-NumBits));
CurWord >>= NumBits;
BitsInCurWord -= NumBits;
return R;
@@ -303,24 +361,37 @@ public:
return 0;
}
- unsigned R = CurWord;
+ uint32_t R = uint32_t(CurWord);
// Read the next word from the stream.
- CurWord = getWord(NextChar);
- NextChar += 4;
+ uint8_t Array[sizeof(word_t)] = {0};
+
+ BitStream->getBitcodeBytes().readBytes(NextChar, sizeof(Array),
+ Array, NULL);
+
+ // Handle big-endian byte-swapping if necessary.
+ support::detail::packed_endian_specific_integral
+ <word_t, support::little, support::unaligned> EndianValue;
+ memcpy(&EndianValue, Array, sizeof(Array));
+
+ CurWord = EndianValue;
+
+ NextChar += sizeof(word_t);
// Extract NumBits-BitsInCurWord from what we just read.
unsigned BitsLeft = NumBits-BitsInCurWord;
- // Be careful here, BitsLeft is in the range [1..32] inclusive.
- R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord;
+ // Be careful here, BitsLeft is in the range [1..32]/[1..64] inclusive.
+ R |= uint32_t((CurWord & (word_t(~0ULL) >> (sizeof(word_t)*8-BitsLeft)))
+ << BitsInCurWord);
- // BitsLeft bits have just been used up from CurWord.
- if (BitsLeft != 32)
+ // BitsLeft bits have just been used up from CurWord. BitsLeft is in the
+ // range [1..32]/[1..64] so be careful how we shift.
+ if (BitsLeft != sizeof(word_t)*8)
CurWord >>= BitsLeft;
else
CurWord = 0;
- BitsInCurWord = 32-BitsLeft;
+ BitsInCurWord = sizeof(word_t)*8-BitsLeft;
return R;
}
@@ -369,10 +440,21 @@ public:
}
}
- void SkipToWord() {
+private:
+ void SkipToFourByteBoundary() {
+ // If word_t is 64-bits and if we've read less than 32 bits, just dump
+ // the bits we have up to the next 32-bit boundary.
+ if (sizeof(word_t) > 4 &&
+ BitsInCurWord >= 32) {
+ CurWord >>= BitsInCurWord-32;
+ BitsInCurWord = 32;
+ return;
+ }
+
BitsInCurWord = 0;
CurWord = 0;
}
+public:
unsigned ReadCode() {
return Read(CurCodeSize);
@@ -395,62 +477,37 @@ public:
// Read and ignore the codelen value. Since we are skipping this block, we
// don't care what code widths are used inside of it.
ReadVBR(bitc::CodeLenWidth);
- SkipToWord();
- unsigned NumWords = Read(bitc::BlockSizeWidth);
+ SkipToFourByteBoundary();
+ unsigned NumFourBytes = Read(bitc::BlockSizeWidth);
// Check that the block wasn't partially defined, and that the offset isn't
// bogus.
- size_t SkipTo = NextChar + NumWords*4;
- if (AtEndOfStream() || !canSkipToPos(SkipTo))
+ size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8;
+ if (AtEndOfStream() || !canSkipToPos(SkipTo/8))
return true;
- NextChar = SkipTo;
+ JumpToBit(SkipTo);
return false;
}
/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter
/// the block, and return true if the block has an error.
- bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
- // Save the current block's state on BlockScope.
- BlockScope.push_back(Block(CurCodeSize));
- BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
-
- // Add the abbrevs specific to this block to the CurAbbrevs list.
- if (const BitstreamReader::BlockInfo *Info =
- BitStream->getBlockInfo(BlockID)) {
- for (unsigned i = 0, e = static_cast<unsigned>(Info->Abbrevs.size());
- i != e; ++i) {
- CurAbbrevs.push_back(Info->Abbrevs[i]);
- CurAbbrevs.back()->addRef();
- }
- }
-
- // Get the codesize of this block.
- CurCodeSize = ReadVBR(bitc::CodeLenWidth);
- SkipToWord();
- unsigned NumWords = Read(bitc::BlockSizeWidth);
- if (NumWordsP) *NumWordsP = NumWords;
-
- // Validate that this block is sane.
- if (CurCodeSize == 0 || AtEndOfStream())
- return true;
-
- return false;
- }
-
+ bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0);
+
bool ReadBlockEnd() {
if (BlockScope.empty()) return true;
// Block tail:
// [END_BLOCK, <align4bytes>]
- SkipToWord();
+ SkipToFourByteBoundary();
- PopBlockScope();
+ popBlockScope();
return false;
}
private:
- void PopBlockScope() {
+
+ void popBlockScope() {
CurCodeSize = BlockScope.back().PrevCodeSize;
// Delete abbrevs from popped scope.
@@ -462,36 +519,17 @@ private:
BlockScope.pop_back();
}
- //===--------------------------------------------------------------------===//
+ //===--------------------------------------------------------------------===//
// Record Processing
//===--------------------------------------------------------------------===//
private:
- void ReadAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
- SmallVectorImpl<uint64_t> &Vals) {
- assert(Op.isLiteral() && "Not a literal");
- // If the abbrev specifies the literal value to use, use it.
- Vals.push_back(Op.getLiteralValue());
- }
-
- void ReadAbbreviatedField(const BitCodeAbbrevOp &Op,
- SmallVectorImpl<uint64_t> &Vals) {
- assert(!Op.isLiteral() && "Use ReadAbbreviatedLiteral for literals!");
-
- // Decode the value as we are commanded.
- switch (Op.getEncoding()) {
- default: llvm_unreachable("Unknown encoding!");
- case BitCodeAbbrevOp::Fixed:
- Vals.push_back(Read((unsigned)Op.getEncodingData()));
- break;
- case BitCodeAbbrevOp::VBR:
- Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData()));
- break;
- case BitCodeAbbrevOp::Char6:
- Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
- break;
- }
- }
+ void readAbbreviatedLiteral(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals);
+ void readAbbreviatedField(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals);
+ void skipAbbreviatedField(const BitCodeAbbrevOp &Op);
+
public:
/// getAbbrev - Return the abbreviation for the specified AbbrevId.
@@ -501,166 +539,18 @@ public:
return CurAbbrevs[AbbrevNo];
}
- unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
- const char **BlobStart = 0, unsigned *BlobLen = 0) {
- if (AbbrevID == bitc::UNABBREV_RECORD) {
- unsigned Code = ReadVBR(6);
- unsigned NumElts = ReadVBR(6);
- for (unsigned i = 0; i != NumElts; ++i)
- Vals.push_back(ReadVBR64(6));
- return Code;
- }
-
- const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID);
-
- for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
- const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
- if (Op.isLiteral()) {
- ReadAbbreviatedLiteral(Op, Vals);
- } else if (Op.getEncoding() == BitCodeAbbrevOp::Array) {
- // Array case. Read the number of elements as a vbr6.
- unsigned NumElts = ReadVBR(6);
-
- // Get the element encoding.
- assert(i+2 == e && "array op not second to last?");
- const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
-
- // Read all the elements.
- for (; NumElts; --NumElts)
- ReadAbbreviatedField(EltEnc, Vals);
- } else if (Op.getEncoding() == BitCodeAbbrevOp::Blob) {
- // Blob case. Read the number of bytes as a vbr6.
- unsigned NumElts = ReadVBR(6);
- SkipToWord(); // 32-bit alignment
-
- // Figure out where the end of this blob will be including tail padding.
- size_t NewEnd = NextChar+((NumElts+3)&~3);
-
- // If this would read off the end of the bitcode file, just set the
- // record to empty and return.
- if (!canSkipToPos(NewEnd)) {
- Vals.append(NumElts, 0);
- NextChar = BitStream->getBitcodeBytes().getExtent();
- break;
- }
-
- // Otherwise, read the number of bytes. If we can return a reference to
- // the data, do so to avoid copying it.
- if (BlobStart) {
- *BlobStart = (const char*)BitStream->getBitcodeBytes().getPointer(
- NextChar, NumElts);
- *BlobLen = NumElts;
- } else {
- for (; NumElts; ++NextChar, --NumElts)
- Vals.push_back(getByte(NextChar));
- }
- // Skip over tail padding.
- NextChar = NewEnd;
- } else {
- ReadAbbreviatedField(Op, Vals);
- }
- }
-
- unsigned Code = (unsigned)Vals[0];
- Vals.erase(Vals.begin());
- return Code;
- }
-
- unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
- const char *&BlobStart, unsigned &BlobLen) {
- return ReadRecord(AbbrevID, Vals, &BlobStart, &BlobLen);
- }
-
+ /// skipRecord - Read the current record and discard it.
+ void skipRecord(unsigned AbbrevID);
+
+ unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals,
+ StringRef *Blob = 0);
//===--------------------------------------------------------------------===//
// Abbrev Processing
//===--------------------------------------------------------------------===//
-
- void ReadAbbrevRecord() {
- BitCodeAbbrev *Abbv = new BitCodeAbbrev();
- unsigned NumOpInfo = ReadVBR(5);
- for (unsigned i = 0; i != NumOpInfo; ++i) {
- bool IsLiteral = Read(1) ? true : false;
- if (IsLiteral) {
- Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
- continue;
- }
-
- BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
- if (BitCodeAbbrevOp::hasEncodingData(E))
- Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
- else
- Abbv->Add(BitCodeAbbrevOp(E));
- }
- CurAbbrevs.push_back(Abbv);
- }
-
-public:
-
- bool ReadBlockInfoBlock() {
- // If this is the second stream to get to the block info block, skip it.
- if (BitStream->hasBlockInfoRecords())
- return SkipBlock();
-
- if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
-
- SmallVector<uint64_t, 64> Record;
- BitstreamReader::BlockInfo *CurBlockInfo = 0;
-
- // Read all the records for this module.
- while (1) {
- unsigned Code = ReadCode();
- if (Code == bitc::END_BLOCK)
- return ReadBlockEnd();
- if (Code == bitc::ENTER_SUBBLOCK) {
- ReadSubBlockID();
- if (SkipBlock()) return true;
- continue;
- }
-
- // Read abbrev records, associate them with CurBID.
- if (Code == bitc::DEFINE_ABBREV) {
- if (!CurBlockInfo) return true;
- ReadAbbrevRecord();
-
- // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
- // appropriate BlockInfo.
- BitCodeAbbrev *Abbv = CurAbbrevs.back();
- CurAbbrevs.pop_back();
- CurBlockInfo->Abbrevs.push_back(Abbv);
- continue;
- }
-
- // Read a record.
- Record.clear();
- switch (ReadRecord(Code, Record)) {
- default: break; // Default behavior, ignore unknown content.
- case bitc::BLOCKINFO_CODE_SETBID:
- if (Record.size() < 1) return true;
- CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]);
- break;
- case bitc::BLOCKINFO_CODE_BLOCKNAME: {
- if (!CurBlockInfo) return true;
- if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
- std::string Name;
- for (unsigned i = 0, e = Record.size(); i != e; ++i)
- Name += (char)Record[i];
- CurBlockInfo->Name = Name;
- break;
- }
- case bitc::BLOCKINFO_CODE_SETRECORDNAME: {
- if (!CurBlockInfo) return true;
- if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name.
- std::string Name;
- for (unsigned i = 1, e = Record.size(); i != e; ++i)
- Name += (char)Record[i];
- CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0],
- Name));
- break;
- }
- }
- }
- }
+ void ReadAbbrevRecord();
+
+ bool ReadBlockInfoBlock();
};
} // End llvm namespace
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
index 1021fbd..7b68f87 100644
--- a/include/llvm/Bitcode/BitstreamWriter.h
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef BITSTREAM_WRITER_H
-#define BITSTREAM_WRITER_H
+#ifndef LLVM_BITCODE_BITSTREAMWRITER_H
+#define LLVM_BITCODE_BITSTREAMWRITER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
index 601777d..f9690d5 100644
--- a/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -29,13 +29,12 @@ namespace bitc {
// Module sub-block id's.
PARAMATTR_BLOCK_ID,
-
- UNUSED_ID1,
+ PARAMATTR_GROUP_BLOCK_ID,
CONSTANTS_BLOCK_ID,
FUNCTION_BLOCK_ID,
- UNUSED_ID2,
+ UNUSED_ID1,
VALUE_SYMTAB_BLOCK_ID,
METADATA_BLOCK_ID,
@@ -69,7 +68,7 @@ namespace bitc {
// ALIAS: [alias type, aliasee val#, linkage, visibility]
MODULE_CODE_ALIAS = 9,
- /// MODULE_CODE_PURGEVALS: [numvals]
+ // MODULE_CODE_PURGEVALS: [numvals]
MODULE_CODE_PURGEVALS = 10,
MODULE_CODE_GCNAME = 11 // GCNAME: [strchr x N]
@@ -77,7 +76,12 @@ namespace bitc {
/// PARAMATTR blocks have code for defining a parameter attribute set.
enum AttributeCodes {
- PARAMATTR_CODE_ENTRY = 1 // ENTRY: [paramidx0, attr0, paramidx1, attr1...]
+ // FIXME: Remove `PARAMATTR_CODE_ENTRY_OLD' in 4.0
+ PARAMATTR_CODE_ENTRY_OLD = 1, // ENTRY: [paramidx0, attr0,
+ // paramidx1, attr1...]
+ PARAMATTR_CODE_ENTRY = 2, // ENTRY: [paramidx0, attrgrp0,
+ // paramidx1, attrgrp1, ...]
+ PARAMATTR_GRP_CODE_ENTRY = 3 // ENTRY: [id, attr0, att1, ...]
};
/// TYPE blocks have codes for each type primitive they use.
@@ -143,6 +147,7 @@ namespace bitc {
METADATA_NAMED_NODE = 10, // NAMED_NODE: [n x mdnodes]
METADATA_ATTACHMENT = 11 // [m x [value, [n x [id, mdnode]]]
};
+
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each
// constant and maintains an implicit current type value.
enum ConstantsCodes {
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index dd96b04..78f40ca 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_BITCODE_H
-#define LLVM_BITCODE_H
+#ifndef LLVM_BITCODE_READERWRITER_H
+#define LLVM_BITCODE_READERWRITER_H
#include <string>
diff --git a/include/llvm/CodeGen/Analysis.h b/include/llvm/CodeGen/Analysis.h
index 81e75d8..ce9ca0a 100644
--- a/include/llvm/CodeGen/Analysis.h
+++ b/include/llvm/CodeGen/Analysis.h
@@ -86,8 +86,7 @@ ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
/// between it and the return.
///
/// This function only tests target-independent requirements.
-bool isInTailCallPosition(ImmutableCallSite CS, Attribute CalleeRetAttr,
- const TargetLowering &TLI);
+bool isInTailCallPosition(ImmutableCallSite CS, const TargetLowering &TLI);
} // End llvm namespace
diff --git a/include/llvm/CodeGen/CommandFlags.h b/include/llvm/CodeGen/CommandFlags.h
index a66e05b..9a27661 100644
--- a/include/llvm/CodeGen/CommandFlags.h
+++ b/include/llvm/CodeGen/CommandFlags.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
-#define LLVM_CODEGEN_COMMAND_LINE_FLAGS_H
+#ifndef LLVM_CODEGEN_COMMANDFLAGS_H
+#define LLVM_CODEGEN_COMMANDFLAGS_H
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/CommandLine.h"
diff --git a/include/llvm/CodeGen/FastISel.h b/include/llvm/CodeGen/FastISel.h
index 0561905..57273d8 100644
--- a/include/llvm/CodeGen/FastISel.h
+++ b/include/llvm/CodeGen/FastISel.h
@@ -90,6 +90,11 @@ public:
/// getCurDebugLoc() - Return current debug location information.
DebugLoc getCurDebugLoc() const { return DL; }
+
+ /// LowerArguments - Do "fast" instruction selection for function arguments
+ /// and append machine instructions to the current block. Return true if
+ /// it is successful.
+ bool LowerArguments();
/// SelectInstruction - Do "fast" instruction selection for the given
/// LLVM IR instruction, and append generated machine instructions to
@@ -160,6 +165,11 @@ protected:
///
virtual bool
TargetSelectInstruction(const Instruction *I) = 0;
+
+ /// FastLowerArguments - This method is called by target-independent code to
+ /// do target specific argument lowering. It returns true if it was
+ /// successful.
+ virtual bool FastLowerArguments();
/// FastEmit_r - This method is called by target-independent code
/// to request that an instruction with the given type and opcode
@@ -362,6 +372,11 @@ protected:
return 0;
}
+ /// Whether we should skip target-independent fast-isel
+ virtual bool SkipTargetIndependentFastISel() {
+ return false;
+ }
+
private:
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h
index 72e0937..ea6cb27 100644
--- a/include/llvm/CodeGen/FunctionLoweringInfo.h
+++ b/include/llvm/CodeGen/FunctionLoweringInfo.h
@@ -17,17 +17,13 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/BranchProbabilityInfo.h"
-#include "llvm/CodeGen/ISDOpcodes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/Support/CallSite.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <vector>
@@ -35,6 +31,7 @@ namespace llvm {
class AllocaInst;
class BasicBlock;
+class BranchProbabilityInfo;
class CallInst;
class Function;
class GlobalVariable;
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 5d0a3b4..092fa5a 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -455,6 +455,9 @@ namespace ISD {
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
+
+ /// FSINCOS - Compute both fsin and fcos as a single operation.
+ FSINCOS,
/// LOAD and STORE have token chains as their first operand, then the same
/// operands as an LLVM load/store instruction, then an offset node that
diff --git a/include/llvm/CodeGen/JITCodeEmitter.h b/include/llvm/CodeGen/JITCodeEmitter.h
index 21a3f48..9a73214 100644
--- a/include/llvm/CodeGen/JITCodeEmitter.h
+++ b/include/llvm/CodeGen/JITCodeEmitter.h
@@ -207,8 +207,7 @@ public:
/// emitString - This callback is invoked when a String needs to be
/// written to the output stream.
void emitString(const std::string &String) {
- for (unsigned i = 0, N = static_cast<unsigned>(String.size());
- i < N; ++i) {
+ for (size_t i = 0, N = String.size(); i < N; ++i) {
uint8_t C = String[i];
emitByte(C);
}
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index 8fb31aa..d454347 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LATENCY_PRIORITY_QUEUE_H
-#define LATENCY_PRIORITY_QUEUE_H
+#ifndef LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
+#define LLVM_CODEGEN_LATENCYPRIORITYQUEUE_H
#include "llvm/CodeGen/ScheduleDAG.h"
diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h
index 3cb6b4d..ff65db4 100644
--- a/include/llvm/CodeGen/LexicalScopes.h
+++ b/include/llvm/CodeGen/LexicalScopes.h
@@ -159,9 +159,6 @@ public:
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
: Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A),
LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0) {
-#ifndef NDEBUG
- IndentLevel = 0;
-#endif
if (Parent)
Parent->addChild(this);
}
@@ -228,7 +225,7 @@ public:
void setDFSIn(unsigned I) { DFSIn = I; }
/// dump - print lexical scope.
- void dump() const;
+ void dump(unsigned Indent = 0) const;
private:
LexicalScope *Parent; // Parent to this scope.
@@ -244,9 +241,6 @@ private:
const MachineInstr *FirstInsn; // First instruction of this scope.
unsigned DFSIn, DFSOut; // In & Out Depth use to determine
// scope nesting.
-#ifndef NDEBUG
- mutable unsigned IndentLevel; // Private state for dump()
-#endif
};
} // end llvm namespace
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 9576075..244be9c 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -86,9 +86,10 @@ namespace llvm {
SlotIndex end; // End point of the interval (exclusive)
VNInfo *valno; // identifier for the value contained in this interval.
+ LiveRange() : valno(0) {}
+
LiveRange(SlotIndex S, SlotIndex E, VNInfo *V)
: start(S), end(E), valno(V) {
-
assert(S < E && "Cannot create empty or backwards range");
}
@@ -373,8 +374,8 @@ namespace llvm {
/// addRange - Add the specified LiveRange to this interval, merging
/// intervals as appropriate. This returns an iterator to the inserted live
/// range (which may have grown since it was inserted.
- void addRange(LiveRange LR) {
- addRangeFrom(LR, ranges.begin());
+ iterator addRange(LiveRange LR) {
+ return addRangeFrom(LR, ranges.begin());
}
/// extendInBlock - If this interval is live before Kill in the basic block
@@ -460,9 +461,6 @@ namespace llvm {
void extendIntervalEndTo(Ranges::iterator I, SlotIndex NewEnd);
Ranges::iterator extendIntervalStartTo(Ranges::iterator I, SlotIndex NewStr);
void markValNoForDeletion(VNInfo *V);
- void mergeIntervalRanges(const LiveInterval &RHS,
- VNInfo *LHSValNo = 0,
- const VNInfo *RHSValNo = 0);
LiveInterval& operator=(const LiveInterval& rhs) LLVM_DELETED_FUNCTION;
@@ -473,6 +471,64 @@ namespace llvm {
return OS;
}
+ /// Helper class for performant LiveInterval bulk updates.
+ ///
+ /// Calling LiveInterval::addRange() repeatedly can be expensive on large
+ /// live ranges because segments after the insertion point may need to be
+ /// shifted. The LiveRangeUpdater class can defer the shifting when adding
+ /// many segments in order.
+ ///
+ /// The LiveInterval will be in an invalid state until flush() is called.
+ class LiveRangeUpdater {
+ LiveInterval *LI;
+ SlotIndex LastStart;
+ LiveInterval::iterator WriteI;
+ LiveInterval::iterator ReadI;
+ SmallVector<LiveRange, 16> Spills;
+ void mergeSpills();
+
+ public:
+ /// Create a LiveRangeUpdater for adding segments to LI.
+ /// LI will temporarily be in an invalid state until flush() is called.
+ LiveRangeUpdater(LiveInterval *li = 0) : LI(li) {}
+
+ ~LiveRangeUpdater() { flush(); }
+
+ /// Add a segment to LI and coalesce when possible, just like LI.addRange().
+ /// Segments should be added in increasing start order for best performance.
+ void add(LiveRange);
+
+ void add(SlotIndex Start, SlotIndex End, VNInfo *VNI) {
+ add(LiveRange(Start, End, VNI));
+ }
+
+ /// Return true if the LI is currently in an invalid state, and flush()
+ /// needs to be called.
+ bool isDirty() const { return LastStart.isValid(); }
+
+ /// Flush the updater state to LI so it is valid and contains all added
+ /// segments.
+ void flush();
+
+ /// Select a different destination live range.
+ void setDest(LiveInterval *li) {
+ if (LI != li && isDirty())
+ flush();
+ LI = li;
+ }
+
+ /// Get the current destination live range.
+ LiveInterval *getDest() const { return LI; }
+
+ void dump() const;
+ void print(raw_ostream&) const;
+ };
+
+ inline raw_ostream &operator<<(raw_ostream &OS, const LiveRangeUpdater &X) {
+ X.print(OS);
+ return OS;
+ }
+
/// LiveRangeQuery - Query information about a live range around a given
/// instruction. This class hides the implementation details of live ranges,
/// and it should be used as the primary interface for examining live ranges
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
index 9e89519..4632368 100644
--- a/include/llvm/CodeGen/LiveIntervalAnalysis.h
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -53,7 +53,6 @@ namespace llvm {
const TargetRegisterInfo* TRI;
const TargetInstrInfo* TII;
AliasAnalysis *AA;
- LiveVariables* LV;
SlotIndexes* Indexes;
MachineDominatorTree *DomTree;
LiveRangeCalc *LRCalc;
@@ -215,6 +214,13 @@ namespace llvm {
return Indexes->getMBBFromIndex(index);
}
+ void insertMBBInMaps(MachineBasicBlock *MBB) {
+ Indexes->insertMBBInMaps(MBB);
+ assert(unsigned(MBB->getNumber()) == RegMaskBlocks.size() &&
+ "Blocks must be added in order.");
+ RegMaskBlocks.push_back(std::make_pair(RegMaskSlots.size(), 0));
+ }
+
SlotIndex InsertMachineInstrInMaps(MachineInstr *MI) {
return Indexes->insertMachineInstrInMaps(MI);
}
@@ -275,6 +281,21 @@ namespace llvm {
void handleMoveIntoBundle(MachineInstr* MI, MachineInstr* BundleStart,
bool UpdateFlags = false);
+ /// repairIntervalsInRange - Update live intervals for instructions in a
+ /// range of iterators. It is intended for use after target hooks that may
+ /// insert or remove instructions, and is only efficient for a small number
+ /// of instructions.
+ ///
+ /// OrigRegs is a vector of registers that were originally used by the
+ /// instructions in the range between the two iterators.
+ ///
+ /// Currently, the only only changes that are supported are simple removal
+ /// and addition of uses.
+ void repairIntervalsInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End,
+ ArrayRef<unsigned> OrigRegs);
+
// Register mask functions.
//
// Machine instructions may use a register mask operand to indicate that a
@@ -352,36 +373,12 @@ namespace llvm {
}
private:
- /// computeIntervals - Compute live intervals.
- void computeIntervals();
-
/// Compute live intervals for all virtual registers.
void computeVirtRegs();
/// Compute RegMaskSlots and RegMaskBits.
void computeRegMasks();
- /// handleRegisterDef - update intervals for a register def
- /// (calls handleVirtualRegisterDef)
- void handleRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx,
- MachineOperand& MO, unsigned MOIdx);
-
- /// isPartialRedef - Return true if the specified def at the specific index
- /// is partially re-defining the specified live interval. A common case of
- /// this is a definition of the sub-register.
- bool isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
- LiveInterval &interval);
-
- /// handleVirtualRegisterDef - update intervals for a virtual
- /// register def
- void handleVirtualRegisterDef(MachineBasicBlock *MBB,
- MachineBasicBlock::iterator MI,
- SlotIndex MIIdx, MachineOperand& MO,
- unsigned MOIdx,
- LiveInterval& interval);
-
static LiveInterval* createInterval(unsigned Reg);
void printInstrs(raw_ostream &O) const;
diff --git a/include/llvm/CodeGen/LiveIntervalUnion.h b/include/llvm/CodeGen/LiveIntervalUnion.h
index 6a61614..615b339 100644
--- a/include/llvm/CodeGen/LiveIntervalUnion.h
+++ b/include/llvm/CodeGen/LiveIntervalUnion.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_LIVEINTERVALUNION
-#define LLVM_CODEGEN_LIVEINTERVALUNION
+#ifndef LLVM_CODEGEN_LIVEINTERVALUNION_H
+#define LLVM_CODEGEN_LIVEINTERVALUNION_H
#include "llvm/ADT/IntervalMap.h"
#include "llvm/CodeGen/LiveInterval.h"
@@ -202,4 +202,4 @@ public:
} // end namespace llvm
-#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION)
+#endif // !defined(LLVM_CODEGEN_LIVEINTERVALUNION_H)
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index a3b1855..92c35f7 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
-#define LLVM_CODEGEN_LIVESTACK_ANALYSIS_H
+#ifndef LLVM_CODEGEN_LIVESTACKANALYSIS_H
+#define LLVM_CODEGEN_LIVESTACKANALYSIS_H
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
index 21fe74f..8c9b7a8 100644
--- a/include/llvm/CodeGen/MachORelocation.h
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
-#define LLVM_CODEGEN_MACHO_RELOCATION_H
+#ifndef LLVM_CODEGEN_MACHORELOCATION_H
+#define LLVM_CODEGEN_MACHORELOCATION_H
#include "llvm/Support/DataTypes.h"
@@ -53,4 +53,4 @@ namespace llvm {
} // end llvm namespace
-#endif // LLVM_CODEGEN_MACHO_RELOCATION_H
+#endif // LLVM_CODEGEN_MACHORELOCATION_H
diff --git a/include/llvm/CodeGen/MachineCodeInfo.h b/include/llvm/CodeGen/MachineCodeInfo.h
index c5c0c44..ba9dfab 100644
--- a/include/llvm/CodeGen/MachineCodeInfo.h
+++ b/include/llvm/CodeGen/MachineCodeInfo.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EE_MACHINE_CODE_INFO_H
-#define EE_MACHINE_CODE_INFO_H
+#ifndef LLVM_CODEGEN_MACHINECODEINFO_H
+#define LLVM_CODEGEN_MACHINECODEINFO_H
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index 40b2542..e41d206 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -41,15 +41,15 @@ class MachineDominatorTree : public MachineFunctionPass {
public:
static char ID; // Pass ID, replacement for typeid
DominatorTreeBase<MachineBasicBlock>* DT;
-
+
MachineDominatorTree();
-
+
~MachineDominatorTree();
-
+
DominatorTreeBase<MachineBasicBlock>& getBase() { return *DT; }
-
+
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
-
+
/// getRoots - Return the root blocks of the current CFG. This may include
/// multiple blocks if we are computing post dominators. For forward
/// dominators, this will always be a single block (the entry node).
@@ -57,33 +57,35 @@ public:
inline const std::vector<MachineBasicBlock*> &getRoots() const {
return DT->getRoots();
}
-
+
inline MachineBasicBlock *getRoot() const {
return DT->getRoot();
}
-
+
inline MachineDomTreeNode *getRootNode() const {
return DT->getRootNode();
}
-
+
virtual bool runOnMachineFunction(MachineFunction &F);
-
- inline bool dominates(MachineDomTreeNode* A, MachineDomTreeNode* B) const {
+
+ inline bool dominates(const MachineDomTreeNode* A,
+ const MachineDomTreeNode* B) const {
return DT->dominates(A, B);
}
-
- inline bool dominates(MachineBasicBlock* A, MachineBasicBlock* B) const {
+
+ inline bool dominates(const MachineBasicBlock* A,
+ const MachineBasicBlock* B) const {
return DT->dominates(A, B);
}
-
+
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
- bool dominates(MachineInstr *A, MachineInstr *B) const {
- MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
+ bool dominates(const MachineInstr *A, const MachineInstr *B) const {
+ const MachineBasicBlock *BBA = A->getParent(), *BBB = B->getParent();
if (BBA != BBB) return DT->dominates(BBA, BBB);
// Loop through the basic block until we find A or B.
- MachineBasicBlock::iterator I = BBA->begin();
+ MachineBasicBlock::const_iterator I = BBA->begin();
for (; &*I != A && &*I != B; ++I)
/*empty*/ ;
@@ -95,43 +97,43 @@ public:
// return &*I == B;
//}
}
-
+
inline bool properlyDominates(const MachineDomTreeNode* A,
- MachineDomTreeNode* B) const {
+ const MachineDomTreeNode* B) const {
return DT->properlyDominates(A, B);
}
-
- inline bool properlyDominates(MachineBasicBlock* A,
- MachineBasicBlock* B) const {
+
+ inline bool properlyDominates(const MachineBasicBlock* A,
+ const MachineBasicBlock* B) const {
return DT->properlyDominates(A, B);
}
-
+
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
inline MachineBasicBlock *findNearestCommonDominator(MachineBasicBlock *A,
MachineBasicBlock *B) {
return DT->findNearestCommonDominator(A, B);
}
-
+
inline MachineDomTreeNode *operator[](MachineBasicBlock *BB) const {
return DT->getNode(BB);
}
-
+
/// getNode - return the (Post)DominatorTree node for the specified basic
/// block. This is the same as using operator[] on this class.
///
inline MachineDomTreeNode *getNode(MachineBasicBlock *BB) const {
return DT->getNode(BB);
}
-
+
/// addNewBlock - Add a new node to the dominator tree information. This
- /// creates a new node as a child of DomBB dominator node,linking it into
+ /// creates a new node as a child of DomBB dominator node,linking it into
/// the children list of the immediate dominator.
inline MachineDomTreeNode *addNewBlock(MachineBasicBlock *BB,
MachineBasicBlock *DomBB) {
return DT->addNewBlock(BB, DomBB);
}
-
+
/// changeImmediateDominator - This method is used to update the dominator
/// tree information when a node's immediate dominator changes.
///
@@ -139,19 +141,19 @@ public:
MachineBasicBlock* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
-
+
inline void changeImmediateDominator(MachineDomTreeNode *N,
MachineDomTreeNode* NewIDom) {
DT->changeImmediateDominator(N, NewIDom);
}
-
+
/// eraseNode - Removes a node from the dominator tree. Block must not
/// dominate any other blocks. Removes node from its immediate dominator's
/// children list. Deletes dominator node associated with basic block BB.
inline void eraseNode(MachineBasicBlock *BB) {
DT->eraseNode(BB);
}
-
+
/// splitBlock - BB is split and now it has one successor. Update dominator
/// tree to reflect this change.
inline void splitBlock(MachineBasicBlock* NewBB) {
@@ -160,12 +162,12 @@ public:
/// isReachableFromEntry - Return true if A is dominated by the entry
/// block of the function containing it.
- bool isReachableFromEntry(MachineBasicBlock *A) {
+ bool isReachableFromEntry(const MachineBasicBlock *A) {
return DT->isReachableFromEntry(A);
}
virtual void releaseMemory();
-
+
virtual void print(raw_ostream &OS, const Module*) const;
};
@@ -179,7 +181,7 @@ template<class T> struct GraphTraits;
template <> struct GraphTraits<MachineDomTreeNode *> {
typedef MachineDomTreeNode NodeType;
typedef NodeType::iterator ChildIteratorType;
-
+
static NodeType *getEntryNode(NodeType *N) {
return N;
}
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
index cd704c1..82c4cd6 100644
--- a/include/llvm/CodeGen/MachineFunction.h
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -131,6 +131,9 @@ class MachineFunction {
/// about the control flow of such functions.
bool ExposesReturnsTwice;
+ /// True if the function includes MS-style inline assembly.
+ bool HasMSInlineAsm;
+
MachineFunction(const MachineFunction &) LLVM_DELETED_FUNCTION;
void operator=(const MachineFunction&) LLVM_DELETED_FUNCTION;
public:
@@ -214,6 +217,17 @@ public:
void setExposesReturnsTwice(bool B) {
ExposesReturnsTwice = B;
}
+
+ /// Returns true if the function contains any MS-style inline assembly.
+ bool hasMSInlineAsm() const {
+ return HasMSInlineAsm;
+ }
+
+ /// Set a flag that indicates that the function contains MS-style inline
+ /// assembly.
+ void setHasMSInlineAsm(bool B) {
+ HasMSInlineAsm = B;
+ }
/// getInfo - Keep track of various per-function pieces of information for
/// backends that would like to do so.
diff --git a/include/llvm/CodeGen/MachineFunctionAnalysis.h b/include/llvm/CodeGen/MachineFunctionAnalysis.h
index 50ea206..112f07e 100644
--- a/include/llvm/CodeGen/MachineFunctionAnalysis.h
+++ b/include/llvm/CodeGen/MachineFunctionAnalysis.h
@@ -11,15 +11,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
-#define LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
+#ifndef LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H
+#define LLVM_CODEGEN_MACHINEFUNCTIONANALYSIS_H
#include "llvm/Pass.h"
-#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MachineFunction;
+class TargetMachine;
/// MachineFunctionAnalysis - This class is a Pass that manages a
/// MachineFunction object.
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
index b7bf0a3..04881e5 100644
--- a/include/llvm/CodeGen/MachineFunctionPass.h
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
-#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+#ifndef LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
+#define LLVM_CODEGEN_MACHINEFUNCTIONPASS_H
#include "llvm/Pass.h"
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 89521e8..195cce7 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -313,11 +313,11 @@ public:
/// The second argument indicates whether the query should look inside
/// instruction bundles.
bool hasProperty(unsigned MCFlag, QueryType Type = AnyInBundle) const {
- // Inline the fast path.
- if (Type == IgnoreBundle || !isBundle())
+ // Inline the fast path for unbundled or bundle-internal instructions.
+ if (Type == IgnoreBundle || !isBundled() || isBundledWithPred())
return getDesc().getFlags() & (1 << MCFlag);
- // If we have a bundle, take the slow path.
+ // If this is the first instruction in a bundle, take the slow path.
return hasPropertyInBundle(1 << MCFlag, Type);
}
@@ -642,6 +642,9 @@ public:
bool isKill() const { return getOpcode() == TargetOpcode::KILL; }
bool isImplicitDef() const { return getOpcode()==TargetOpcode::IMPLICIT_DEF; }
bool isInlineAsm() const { return getOpcode() == TargetOpcode::INLINEASM; }
+ bool isMSInlineAsm() const {
+ return getOpcode() == TargetOpcode::INLINEASM && getInlineAsmDialect();
+ }
bool isStackAligningInlineAsm() const;
InlineAsm::AsmDialect getInlineAsmDialect() const;
bool isInsertSubreg() const {
@@ -699,7 +702,11 @@ public:
}
}
- /// getBundleSize - Return the number of instructions inside the MI bundle.
+ /// Return the number of instructions inside the MI bundle, excluding the
+ /// bundle header.
+ ///
+ /// This is the number of instructions that MachineBasicBlock::iterator
+ /// skips, 0 for unbundled instructions.
unsigned getBundleSize() const;
/// readsRegister - Return true if the MachineInstr reads the specified
@@ -944,7 +951,8 @@ public:
//
// Debugging support
//
- void print(raw_ostream &OS, const TargetMachine *TM = 0) const;
+ void print(raw_ostream &OS, const TargetMachine *TM = 0,
+ bool SkipOpers = false) const;
void dump() const;
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index a2d3d63..92c8da9 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -18,6 +18,7 @@
#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -391,11 +392,7 @@ public:
/// Create an MIBundleBuilder representing an existing instruction or bundle
/// that has MI as its head.
explicit MIBundleBuilder(MachineInstr *MI)
- : MBB(*MI->getParent()), Begin(MI) {
- MachineBasicBlock::iterator I = MI;
- ++I;
- End = I.getInstrIterator();
- }
+ : MBB(*MI->getParent()), Begin(MI), End(getBundleEnd(MI)) {}
/// Return a reference to the basic block containing this bundle.
MachineBasicBlock &getMBB() const { return MBB; }
diff --git a/include/llvm/CodeGen/MachineInstrBundle.h b/include/llvm/CodeGen/MachineInstrBundle.h
index 3c60ad1..9519edb 100644
--- a/include/llvm/CodeGen/MachineInstrBundle.h
+++ b/include/llvm/CodeGen/MachineInstrBundle.h
@@ -45,18 +45,36 @@ bool finalizeBundles(MachineFunction &MF);
///
inline MachineInstr *getBundleStart(MachineInstr *MI) {
MachineBasicBlock::instr_iterator I = MI;
- while (I->isInsideBundle())
+ while (I->isBundledWithPred())
--I;
return I;
}
inline const MachineInstr *getBundleStart(const MachineInstr *MI) {
MachineBasicBlock::const_instr_iterator I = MI;
- while (I->isInsideBundle())
+ while (I->isBundledWithPred())
--I;
return I;
}
+/// Return an iterator pointing beyond the bundle containing MI.
+inline MachineBasicBlock::instr_iterator
+getBundleEnd(MachineInstr *MI) {
+ MachineBasicBlock::instr_iterator I = MI;
+ while (I->isBundledWithSucc())
+ ++I;
+ return ++I;
+}
+
+/// Return an iterator pointing beyond the bundle containing MI.
+inline MachineBasicBlock::const_instr_iterator
+getBundleEnd(const MachineInstr *MI) {
+ MachineBasicBlock::const_instr_iterator I = MI;
+ while (I->isBundledWithSucc())
+ ++I;
+ return ++I;
+}
+
//===----------------------------------------------------------------------===//
// MachineOperand iterator
//
diff --git a/include/llvm/CodeGen/MachineLoopInfo.h b/include/llvm/CodeGen/MachineLoopInfo.h
index 99da6b2..b058ecb 100644
--- a/include/llvm/CodeGen/MachineLoopInfo.h
+++ b/include/llvm/CodeGen/MachineLoopInfo.h
@@ -27,8 +27,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_MACHINE_LOOP_INFO_H
-#define LLVM_CODEGEN_MACHINE_LOOP_INFO_H
+#ifndef LLVM_CODEGEN_MACHINELOOPINFO_H
+#define LLVM_CODEGEN_MACHINELOOPINFO_H
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
index 6194d05..1db6252 100644
--- a/include/llvm/CodeGen/MachineModuleInfo.h
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -35,7 +35,6 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MachineLocation.h"
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index 36427e9..875285b 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -99,13 +99,11 @@ class MachineRegisterInfo {
/// started.
BitVector ReservedRegs;
- /// LiveIns/LiveOuts - Keep track of the physical registers that are
- /// livein/liveout of the function. Live in values are typically arguments in
- /// registers, live out values are typically return values in registers.
- /// LiveIn values are allowed to have virtual registers associated with them,
- /// stored in the second element.
+ /// Keep track of the physical registers that are live in to the function.
+ /// Live in values are typically arguments in registers, live out values are
+ /// typically return values in registers. LiveIn values are allowed to have
+ /// virtual registers associated with them, stored in the second element.
std::vector<std::pair<unsigned, unsigned> > LiveIns;
- std::vector<unsigned> LiveOuts;
MachineRegisterInfo(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
void operator=(const MachineRegisterInfo&) LLVM_DELETED_FUNCTION;
@@ -379,6 +377,12 @@ public:
return false;
}
+ /// Mark the specified register unit as used in this function.
+ /// This should only be called during and after register allocation.
+ void setRegUnitUsed(unsigned RegUnit) {
+ UsedRegUnits.set(RegUnit);
+ }
+
/// setPhysRegUsed - Mark the specified register used in this function.
/// This should only be called during and after register allocation.
void setPhysRegUsed(unsigned Reg) {
@@ -468,7 +472,6 @@ public:
void addLiveIn(unsigned Reg, unsigned vreg = 0) {
LiveIns.push_back(std::make_pair(Reg, vreg));
}
- void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); }
// Iteration support for live in/out sets. These sets are kept in sorted
// order by their register number.
@@ -478,12 +481,8 @@ public:
livein_iterator livein_begin() const { return LiveIns.begin(); }
livein_iterator livein_end() const { return LiveIns.end(); }
bool livein_empty() const { return LiveIns.empty(); }
- liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
- liveout_iterator liveout_end() const { return LiveOuts.end(); }
- bool liveout_empty() const { return LiveOuts.empty(); }
bool isLiveIn(unsigned Reg) const;
- bool isLiveOut(unsigned Reg) const;
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
/// corresponding live-in physical register.
diff --git a/include/llvm/CodeGen/MachineScheduler.h b/include/llvm/CodeGen/MachineScheduler.h
index 88f347e..57febe7 100644
--- a/include/llvm/CodeGen/MachineScheduler.h
+++ b/include/llvm/CodeGen/MachineScheduler.h
@@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MACHINESCHEDULER_H
-#define MACHINESCHEDULER_H
+#ifndef LLVM_CODEGEN_MACHINESCHEDULER_H
+#define LLVM_CODEGEN_MACHINESCHEDULER_H
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/CodeGen/RegisterPressure.h"
@@ -43,6 +43,7 @@ class MachineDominatorTree;
class MachineLoopInfo;
class RegisterClassInfo;
class ScheduleDAGInstrs;
+class SchedDFSResult;
/// MachineSchedContext provides enough context from the MachineScheduler pass
/// for the target to instantiate a scheduler.
@@ -119,6 +120,9 @@ public:
/// be scheduled at the bottom.
virtual SUnit *pickNode(bool &IsTopNode) = 0;
+ /// \brief Scheduler callback to notify that a new subtree is scheduled.
+ virtual void scheduleTree(unsigned SubtreeID) {}
+
/// Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an
/// instruction and updated scheduled/remaining flags in the DAG nodes.
virtual void schedNode(SUnit *SU, bool IsTopNode) = 0;
@@ -164,6 +168,8 @@ public:
iterator end() { return Queue.end(); }
+ ArrayRef<SUnit*> elements() { return Queue; }
+
iterator find(SUnit *SU) {
return std::find(Queue.begin(), Queue.end(), SU);
}
@@ -202,6 +208,11 @@ protected:
RegisterClassInfo *RegClassInfo;
MachineSchedStrategy *SchedImpl;
+ /// Information about DAG subtrees. If DFSResult is NULL, then SchedulerTrees
+ /// will be empty.
+ SchedDFSResult *DFSResult;
+ BitVector ScheduledTrees;
+
/// Topo - A topological ordering for SUnits which permits fast IsReachable
/// and similar queries.
ScheduleDAGTopologicalSort Topo;
@@ -243,7 +254,7 @@ protected:
public:
ScheduleDAGMI(MachineSchedContext *C, MachineSchedStrategy *S):
ScheduleDAGInstrs(*C->MF, *C->MLI, *C->MDT, /*IsPostRA=*/false, C->LIS),
- AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S),
+ AA(C->AA), RegClassInfo(C->RegClassInfo), SchedImpl(S), DFSResult(0),
Topo(SUnits, &ExitSU), RPTracker(RegPressure), CurrentTop(),
TopRPTracker(TopPressure), CurrentBottom(), BotRPTracker(BotPressure),
NextClusterPred(NULL), NextClusterSucc(NULL) {
@@ -252,10 +263,7 @@ public:
#endif
}
- virtual ~ScheduleDAGMI() {
- DeleteContainerPointers(Mutations);
- delete SchedImpl;
- }
+ virtual ~ScheduleDAGMI();
/// Add a postprocessing step to the DAG builder.
/// Mutations are applied in the order that they are added after normal DAG
@@ -308,6 +316,18 @@ public:
const SUnit *getNextClusterSucc() const { return NextClusterSucc; }
+ /// Compute a DFSResult after DAG building is complete, and before any
+ /// queue comparisons.
+ void computeDFSResult();
+
+ /// Return a non-null DFS result if the scheduling strategy initialized it.
+ const SchedDFSResult *getDFSResult() const { return DFSResult; }
+
+ BitVector &getScheduledTrees() { return ScheduledTrees; }
+
+ void viewGraph(const Twine &Name, const Twine &Title) LLVM_OVERRIDE;
+ void viewGraph() LLVM_OVERRIDE;
+
protected:
// Top-Level entry points for the schedule() driver...
@@ -321,8 +341,8 @@ protected:
/// instances of ScheduleDAGMI to perform custom DAG postprocessing.
void postprocessDAG();
- /// Identify DAG roots and setup scheduler queues.
- void initQueues();
+ /// Release ExitSU predecessors and setup scheduler queues.
+ void initQueues(ArrayRef<SUnit*> TopRoots, ArrayRef<SUnit*> BotRoots);
/// Move an instruction and update register pressure.
void scheduleMI(SUnit *SU, bool IsTopNode);
@@ -340,12 +360,13 @@ protected:
void initRegPressure();
- void updateScheduledPressure(std::vector<unsigned> NewMaxPressure);
+ void updateScheduledPressure(const std::vector<unsigned> &NewMaxPressure);
void moveInstruction(MachineInstr *MI, MachineBasicBlock::iterator InsertPos);
bool checkSchedLimit();
- void releaseRoots();
+ void findRootsAndBiasEdges(SmallVectorImpl<SUnit*> &TopRoots,
+ SmallVectorImpl<SUnit*> &BotRoots);
void releaseSucc(SUnit *SU, SDep *SuccEdge);
void releaseSuccessors(SUnit *SU);
diff --git a/include/llvm/CodeGen/MachineTraceMetrics.h b/include/llvm/CodeGen/MachineTraceMetrics.h
new file mode 100644
index 0000000..460730b
--- /dev/null
+++ b/include/llvm/CodeGen/MachineTraceMetrics.h
@@ -0,0 +1,350 @@
+//===- lib/CodeGen/MachineTraceMetrics.h - Super-scalar metrics -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface for the MachineTraceMetrics analysis pass
+// that estimates CPU resource usage and critical data dependency paths through
+// preferred traces. This is useful for super-scalar CPUs where execution speed
+// can be limited both by data dependencies and by limited execution resources.
+//
+// Out-of-order CPUs will often be executing instructions from multiple basic
+// blocks at the same time. This makes it difficult to estimate the resource
+// usage accurately in a single basic block. Resources can be estimated better
+// by looking at a trace through the current basic block.
+//
+// For every block, the MachineTraceMetrics pass will pick a preferred trace
+// that passes through the block. The trace is chosen based on loop structure,
+// branch probabilities, and resource usage. The intention is to pick likely
+// traces that would be the most affected by code transformations.
+//
+// It is expensive to compute a full arbitrary trace for every block, so to
+// save some computations, traces are chosen to be convergent. This means that
+// if the traces through basic blocks A and B ever cross when moving away from
+// A and B, they never diverge again. This applies in both directions - If the
+// traces meet above A and B, they won't diverge when going further back.
+//
+// Traces tend to align with loops. The trace through a block in an inner loop
+// will begin at the loop entry block and end at a back edge. If there are
+// nested loops, the trace may begin and end at those instead.
+//
+// For each trace, we compute the critical path length, which is the number of
+// cycles required to execute the trace when execution is limited by data
+// dependencies only. We also compute the resource height, which is the number
+// of cycles required to execute all instructions in the trace when ignoring
+// data dependencies.
+//
+// Every instruction in the current block has a slack - the number of cycles
+// execution of the instruction can be delayed without extending the critical
+// path.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_TRACE_METRICS_H
+#define LLVM_CODEGEN_MACHINE_TRACE_METRICS_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/TargetSchedule.h"
+
+namespace llvm {
+
+class InstrItineraryData;
+class MachineBasicBlock;
+class MachineInstr;
+class MachineLoop;
+class MachineLoopInfo;
+class MachineRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterInfo;
+class raw_ostream;
+
+class MachineTraceMetrics : public MachineFunctionPass {
+ const MachineFunction *MF;
+ const TargetInstrInfo *TII;
+ const TargetRegisterInfo *TRI;
+ const MachineRegisterInfo *MRI;
+ const MachineLoopInfo *Loops;
+ TargetSchedModel SchedModel;
+
+public:
+ class Ensemble;
+ class Trace;
+ static char ID;
+ MachineTraceMetrics();
+ void getAnalysisUsage(AnalysisUsage&) const;
+ bool runOnMachineFunction(MachineFunction&);
+ void releaseMemory();
+ void verifyAnalysis() const;
+
+ friend class Ensemble;
+ friend class Trace;
+
+ /// Per-basic block information that doesn't depend on the trace through the
+ /// block.
+ struct FixedBlockInfo {
+ /// The number of non-trivial instructions in the block.
+ /// Doesn't count PHI and COPY instructions that are likely to be removed.
+ unsigned InstrCount;
+
+ /// True when the block contains calls.
+ bool HasCalls;
+
+ FixedBlockInfo() : InstrCount(~0u), HasCalls(false) {}
+
+ /// Returns true when resource information for this block has been computed.
+ bool hasResources() const { return InstrCount != ~0u; }
+
+ /// Invalidate resource information.
+ void invalidate() { InstrCount = ~0u; }
+ };
+
+ /// Get the fixed resource information about MBB. Compute it on demand.
+ const FixedBlockInfo *getResources(const MachineBasicBlock*);
+
+ /// A virtual register or regunit required by a basic block or its trace
+ /// successors.
+ struct LiveInReg {
+ /// The virtual register required, or a register unit.
+ unsigned Reg;
+
+ /// For virtual registers: Minimum height of the defining instruction.
+ /// For regunits: Height of the highest user in the trace.
+ unsigned Height;
+
+ LiveInReg(unsigned Reg, unsigned Height = 0) : Reg(Reg), Height(Height) {}
+ };
+
+ /// Per-basic block information that relates to a specific trace through the
+ /// block. Convergent traces means that only one of these is required per
+ /// block in a trace ensemble.
+ struct TraceBlockInfo {
+ /// Trace predecessor, or NULL for the first block in the trace.
+ /// Valid when hasValidDepth().
+ const MachineBasicBlock *Pred;
+
+ /// Trace successor, or NULL for the last block in the trace.
+ /// Valid when hasValidHeight().
+ const MachineBasicBlock *Succ;
+
+ /// The block number of the head of the trace. (When hasValidDepth()).
+ unsigned Head;
+
+ /// The block number of the tail of the trace. (When hasValidHeight()).
+ unsigned Tail;
+
+ /// Accumulated number of instructions in the trace above this block.
+ /// Does not include instructions in this block.
+ unsigned InstrDepth;
+
+ /// Accumulated number of instructions in the trace below this block.
+ /// Includes instructions in this block.
+ unsigned InstrHeight;
+
+ TraceBlockInfo() :
+ Pred(0), Succ(0),
+ InstrDepth(~0u), InstrHeight(~0u),
+ HasValidInstrDepths(false), HasValidInstrHeights(false) {}
+
+ /// Returns true if the depth resources have been computed from the trace
+ /// above this block.
+ bool hasValidDepth() const { return InstrDepth != ~0u; }
+
+ /// Returns true if the height resources have been computed from the trace
+ /// below this block.
+ bool hasValidHeight() const { return InstrHeight != ~0u; }
+
+ /// Invalidate depth resources when some block above this one has changed.
+ void invalidateDepth() { InstrDepth = ~0u; HasValidInstrDepths = false; }
+
+ /// Invalidate height resources when a block below this one has changed.
+ void invalidateHeight() { InstrHeight = ~0u; HasValidInstrHeights = false; }
+
+ /// Determine if this block belongs to the same trace as TBI and comes
+ /// before it in the trace.
+ /// Also returns true when TBI == this.
+ bool isEarlierInSameTrace(const TraceBlockInfo &TBI) const {
+ return hasValidDepth() && TBI.hasValidDepth() &&
+ Head == TBI.Head && InstrDepth <= TBI.InstrDepth;
+ }
+
+ // Data-dependency-related information. Per-instruction depth and height
+ // are computed from data dependencies in the current trace, using
+ // itinerary data.
+
+ /// Instruction depths have been computed. This implies hasValidDepth().
+ bool HasValidInstrDepths;
+
+ /// Instruction heights have been computed. This implies hasValidHeight().
+ bool HasValidInstrHeights;
+
+ /// Critical path length. This is the number of cycles in the longest data
+ /// dependency chain through the trace. This is only valid when both
+ /// HasValidInstrDepths and HasValidInstrHeights are set.
+ unsigned CriticalPath;
+
+ /// Live-in registers. These registers are defined above the current block
+ /// and used by this block or a block below it.
+ /// This does not include PHI uses in the current block, but it does
+ /// include PHI uses in deeper blocks.
+ SmallVector<LiveInReg, 4> LiveIns;
+
+ void print(raw_ostream&) const;
+ };
+
+ /// InstrCycles represents the cycle height and depth of an instruction in a
+ /// trace.
+ struct InstrCycles {
+ /// Earliest issue cycle as determined by data dependencies and instruction
+ /// latencies from the beginning of the trace. Data dependencies from
+ /// before the trace are not included.
+ unsigned Depth;
+
+ /// Minimum number of cycles from this instruction is issued to the of the
+ /// trace, as determined by data dependencies and instruction latencies.
+ unsigned Height;
+ };
+
+ /// A trace represents a plausible sequence of executed basic blocks that
+ /// passes through the current basic block one. The Trace class serves as a
+ /// handle to internal cached data structures.
+ class Trace {
+ Ensemble &TE;
+ TraceBlockInfo &TBI;
+
+ unsigned getBlockNum() const { return &TBI - &TE.BlockInfo[0]; }
+
+ public:
+ explicit Trace(Ensemble &te, TraceBlockInfo &tbi) : TE(te), TBI(tbi) {}
+ void print(raw_ostream&) const;
+
+ /// Compute the total number of instructions in the trace.
+ unsigned getInstrCount() const {
+ return TBI.InstrDepth + TBI.InstrHeight;
+ }
+
+ /// Return the resource depth of the top/bottom of the trace center block.
+ /// This is the number of cycles required to execute all instructions from
+ /// the trace head to the trace center block. The resource depth only
+ /// considers execution resources, it ignores data dependencies.
+ /// When Bottom is set, instructions in the trace center block are included.
+ unsigned getResourceDepth(bool Bottom) const;
+
+ /// Return the resource length of the trace. This is the number of cycles
+ /// required to execute the instructions in the trace if they were all
+ /// independent, exposing the maximum instruction-level parallelism.
+ ///
+ /// Any blocks in Extrablocks are included as if they were part of the
+ /// trace.
+ unsigned getResourceLength(ArrayRef<const MachineBasicBlock*> Extrablocks =
+ ArrayRef<const MachineBasicBlock*>()) const;
+
+ /// Return the length of the (data dependency) critical path through the
+ /// trace.
+ unsigned getCriticalPath() const { return TBI.CriticalPath; }
+
+ /// Return the depth and height of MI. The depth is only valid for
+ /// instructions in or above the trace center block. The height is only
+ /// valid for instructions in or below the trace center block.
+ InstrCycles getInstrCycles(const MachineInstr *MI) const {
+ return TE.Cycles.lookup(MI);
+ }
+
+ /// Return the slack of MI. This is the number of cycles MI can be delayed
+ /// before the critical path becomes longer.
+ /// MI must be an instruction in the trace center block.
+ unsigned getInstrSlack(const MachineInstr *MI) const;
+
+ /// Return the Depth of a PHI instruction in a trace center block successor.
+ /// The PHI does not have to be part of the trace.
+ unsigned getPHIDepth(const MachineInstr *PHI) const;
+ };
+
+ /// A trace ensemble is a collection of traces selected using the same
+ /// strategy, for example 'minimum resource height'. There is one trace for
+ /// every block in the function.
+ class Ensemble {
+ SmallVector<TraceBlockInfo, 4> BlockInfo;
+ DenseMap<const MachineInstr*, InstrCycles> Cycles;
+ friend class Trace;
+
+ void computeTrace(const MachineBasicBlock*);
+ void computeDepthResources(const MachineBasicBlock*);
+ void computeHeightResources(const MachineBasicBlock*);
+ unsigned computeCrossBlockCriticalPath(const TraceBlockInfo&);
+ void computeInstrDepths(const MachineBasicBlock*);
+ void computeInstrHeights(const MachineBasicBlock*);
+ void addLiveIns(const MachineInstr *DefMI, unsigned DefOp,
+ ArrayRef<const MachineBasicBlock*> Trace);
+
+ protected:
+ MachineTraceMetrics &MTM;
+ virtual const MachineBasicBlock *pickTracePred(const MachineBasicBlock*) =0;
+ virtual const MachineBasicBlock *pickTraceSucc(const MachineBasicBlock*) =0;
+ explicit Ensemble(MachineTraceMetrics*);
+ const MachineLoop *getLoopFor(const MachineBasicBlock*) const;
+ const TraceBlockInfo *getDepthResources(const MachineBasicBlock*) const;
+ const TraceBlockInfo *getHeightResources(const MachineBasicBlock*) const;
+
+ public:
+ virtual ~Ensemble();
+ virtual const char *getName() const =0;
+ void print(raw_ostream&) const;
+ void invalidate(const MachineBasicBlock *MBB);
+ void verify() const;
+
+ /// Get the trace that passes through MBB.
+ /// The trace is computed on demand.
+ Trace getTrace(const MachineBasicBlock *MBB);
+ };
+
+ /// Strategies for selecting traces.
+ enum Strategy {
+ /// Select the trace through a block that has the fewest instructions.
+ TS_MinInstrCount,
+
+ TS_NumStrategies
+ };
+
+ /// Get the trace ensemble representing the given trace selection strategy.
+ /// The returned Ensemble object is owned by the MachineTraceMetrics analysis,
+ /// and valid for the lifetime of the analysis pass.
+ Ensemble *getEnsemble(Strategy);
+
+ /// Invalidate cached information about MBB. This must be called *before* MBB
+ /// is erased, or the CFG is otherwise changed.
+ ///
+ /// This invalidates per-block information about resource usage for MBB only,
+ /// and it invalidates per-trace information for any trace that passes
+ /// through MBB.
+ ///
+ /// Call Ensemble::getTrace() again to update any trace handles.
+ void invalidate(const MachineBasicBlock *MBB);
+
+private:
+ // One entry per basic block, indexed by block number.
+ SmallVector<FixedBlockInfo, 4> BlockInfo;
+
+ // One ensemble per strategy.
+ Ensemble* Ensembles[TS_NumStrategies];
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const MachineTraceMetrics::Trace &Tr) {
+ Tr.print(OS);
+ return OS;
+}
+
+inline raw_ostream &operator<<(raw_ostream &OS,
+ const MachineTraceMetrics::Ensemble &En) {
+ En.print(OS);
+ return OS;
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/PBQP/Math.h b/include/llvm/CodeGen/PBQP/Math.h
index 4e51913..08f8b98 100644
--- a/include/llvm/CodeGen/PBQP/Math.h
+++ b/include/llvm/CodeGen/PBQP/Math.h
@@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_PBQP_MATH_H
+#ifndef LLVM_CODEGEN_PBQP_MATH_H
#define LLVM_CODEGEN_PBQP_MATH_H
#include <algorithm>
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 0d02700..5f710e6 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -25,6 +25,7 @@ namespace llvm {
class MachineFunctionPass;
class PassInfo;
class PassManagerBase;
+ class TargetLoweringBase;
class TargetLowering;
class TargetRegisterClass;
class raw_ostream;
@@ -180,6 +181,16 @@ protected:
/// instructions in SSA form.
virtual void addMachineSSAOptimization();
+ /// Add passes that optimize instruction level parallelism for out-of-order
+ /// targets. These passes are run while the machine code is still in SSA
+ /// form, so they can use MachineTraceMetrics to control their heuristics.
+ ///
+ /// All passes added here should preserve the MachineDominatorTree,
+ /// MachineLoopInfo, and MachineTraceMetrics analyses.
+ virtual bool addILPOpts() {
+ return false;
+ }
+
/// addPreRegAlloc - This method may be implemented by targets that want to
/// run passes immediately before register allocation. This should return
/// true if -print-machineinstrs should print after these passes.
@@ -284,7 +295,8 @@ namespace llvm {
///
/// This pass implements the target transform info analysis using the target
/// independent information available to the LLVM code generator.
- ImmutablePass *createBasicTargetTransformInfoPass(const TargetLowering *TLI);
+ ImmutablePass *
+ createBasicTargetTransformInfoPass(const TargetLoweringBase *TLI);
/// createUnreachableBlockEliminationPass - The LLVM code generator does not
/// work well with unreachable basic blocks (what live ranges make sense for a
@@ -481,7 +493,7 @@ namespace llvm {
/// createStackProtectorPass - This pass adds stack protectors to functions.
///
- FunctionPass *createStackProtectorPass(const TargetLowering *tli);
+ FunctionPass *createStackProtectorPass(const TargetLoweringBase *tli);
/// createMachineVerifierPass - This pass verifies cenerated machine code
/// instructions for correctness.
@@ -495,7 +507,7 @@ namespace llvm {
/// createSjLjEHPreparePass - This pass adapts exception handling code to use
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
///
- FunctionPass *createSjLjEHPreparePass(const TargetLowering *tli);
+ FunctionPass *createSjLjEHPreparePass(const TargetLoweringBase *tli);
/// LocalStackSlotAllocation - This pass assigns local frame indices to stack
/// slots relative to one another and allocates base registers to access them
diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h
index 100e357..ca49577 100644
--- a/include/llvm/CodeGen/RegAllocRegistry.h
+++ b/include/llvm/CodeGen/RegAllocRegistry.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGENREGALLOCREGISTRY_H
-#define LLVM_CODEGENREGALLOCREGISTRY_H
+#ifndef LLVM_CODEGEN_REGALLOCREGISTRY_H
+#define LLVM_CODEGEN_REGALLOCREGISTRY_H
#include "llvm/CodeGen/MachinePassRegistry.h"
diff --git a/include/llvm/CodeGen/RegisterClassInfo.h b/include/llvm/CodeGen/RegisterClassInfo.h
index 12bd1c6..3ad22e6 100644
--- a/include/llvm/CodeGen/RegisterClassInfo.h
+++ b/include/llvm/CodeGen/RegisterClassInfo.h
@@ -29,9 +29,14 @@ class RegisterClassInfo {
unsigned Tag;
unsigned NumRegs;
bool ProperSubClass;
+ uint8_t MinCost;
+ uint16_t LastCostChange;
OwningArrayPtr<MCPhysReg> Order;
- RCInfo() : Tag(0), NumRegs(0), ProperSubClass(false) {}
+ RCInfo()
+ : Tag(0), NumRegs(0), ProperSubClass(false), MinCost(0),
+ LastCostChange(0) {}
+
operator ArrayRef<MCPhysReg>() const {
return makeArrayRef(Order.get(), NumRegs);
}
@@ -106,6 +111,21 @@ public:
return CalleeSaved[N-1];
return 0;
}
+
+ /// Get the minimum register cost in RC's allocation order.
+ /// This is the smallest value returned by TRI->getCostPerUse(Reg) for all
+ /// the registers in getOrder(RC).
+ unsigned getMinCost(const TargetRegisterClass *RC) {
+ return get(RC).MinCost;
+ }
+
+ /// Get the position of the last cost change in getOrder(RC).
+ ///
+ /// All registers in getOrder(RC).slice(getLastCostChange(RC)) will have the
+ /// same cost according to TRI->getCostPerUse().
+ unsigned getLastCostChange(const TargetRegisterClass *RC) {
+ return get(RC).LastCostChange;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
index 6604d4c..0119920 100644
--- a/include/llvm/CodeGen/RegisterScavenging.h
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
-#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
+#ifndef LLVM_CODEGEN_REGISTERSCAVENGING_H
+#define LLVM_CODEGEN_REGISTERSCAVENGING_H
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
index 66a6039..f20a9fc 100644
--- a/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef RESOURCE_PRIORITY_QUEUE_H
-#define RESOURCE_PRIORITY_QUEUE_H
+#ifndef LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
+#define LLVM_CODEGEN_RESOURCEPRIORITYQUEUE_H
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/ScheduleDAG.h"
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index 1a9dc1c..41289a4 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -158,6 +158,11 @@ namespace RTLIB {
COS_F80,
COS_F128,
COS_PPCF128,
+ SINCOS_F32,
+ SINCOS_F64,
+ SINCOS_F80,
+ SINCOS_F128,
+ SINCOS_PPCF128,
POW_F32,
POW_F64,
POW_F80,
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index aa91b03..d80bdf8 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -17,11 +17,10 @@
#define LLVM_CODEGEN_SCHEDULEDAG_H
#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/GraphTraits.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Target/TargetLowering.h"
namespace llvm {
@@ -258,6 +257,8 @@ namespace llvm {
/// SUnit - Scheduling unit. This is a node in the scheduling DAG.
class SUnit {
private:
+ enum { BoundaryID = ~0u };
+
SDNode *Node; // Representative node.
MachineInstr *Instr; // Alternatively, a MachineInstr.
public:
@@ -343,7 +344,7 @@ namespace llvm {
/// SUnit - Construct a placeholder SUnit.
SUnit()
- : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(~0u),
+ : Node(0), Instr(0), OrigNode(0), SchedClass(0), NodeNum(BoundaryID),
NodeQueueId(0), NumPreds(0), NumSuccs(0), NumPredsLeft(0),
NumSuccsLeft(0), WeakPredsLeft(0), WeakSuccsLeft(0), NumRegDefsLeft(0),
Latency(0), isVRegCycle(false), isCall(false), isCallOp(false),
@@ -354,6 +355,15 @@ namespace llvm {
isDepthCurrent(false), isHeightCurrent(false), Depth(0), Height(0),
TopReadyCycle(0), BotReadyCycle(0), CopyDstRC(NULL), CopySrcRC(NULL) {}
+ /// \brief Boundary nodes are placeholders for the boundary of the
+ /// scheduling region.
+ ///
+ /// BoundaryNodes can have DAG edges, including Data edges, but they do not
+ /// correspond to schedulable entities (e.g. instructions) and do not have a
+ /// valid ID. Consequently, always check for boundary nodes before accessing
+ /// an assoicative data structure keyed on node ID.
+ bool isBoundaryNode() const { return NodeNum == BoundaryID; };
+
/// setNode - Assign the representative SDNode for this SUnit.
/// This may be used during pre-regalloc scheduling.
void setNode(SDNode *N) {
@@ -455,6 +465,10 @@ namespace llvm {
return NumSuccsLeft == 0;
}
+ /// \brief Order this node's predecessor edges such that the critical path
+ /// edge occurs first.
+ void biasCriticalPath();
+
void dump(const ScheduleDAG *G) const;
void dumpAll(const ScheduleDAG *G) const;
void print(raw_ostream &O, const ScheduleDAG *G) const;
@@ -563,8 +577,8 @@ namespace llvm {
/// viewGraph - Pop up a GraphViz/gv window with the ScheduleDAG rendered
/// using 'dot'.
///
- void viewGraph(const Twine &Name, const Twine &Title);
- void viewGraph();
+ virtual void viewGraph(const Twine &Name, const Twine &Title);
+ virtual void viewGraph();
virtual void dumpNode(const SUnit *SU) const = 0;
diff --git a/include/llvm/CodeGen/ScheduleDAGInstrs.h b/include/llvm/CodeGen/ScheduleDAGInstrs.h
index ffc442e..94abec2 100644
--- a/include/llvm/CodeGen/ScheduleDAGInstrs.h
+++ b/include/llvm/CodeGen/ScheduleDAGInstrs.h
@@ -12,11 +12,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SCHEDULEDAGINSTRS_H
-#define SCHEDULEDAGINSTRS_H
+#ifndef LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
+#define LLVM_CODEGEN_SCHEDULEDAGINSTRS_H
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SparseSet.h"
+#include "llvm/ADT/SparseMultiSet.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/ScheduleDAG.h"
@@ -48,56 +49,18 @@ namespace llvm {
struct PhysRegSUOper {
SUnit *SU;
int OpIdx;
+ unsigned Reg;
- PhysRegSUOper(SUnit *su, int op): SU(su), OpIdx(op) {}
- };
-
- /// Combine a SparseSet with a 1x1 vector to track physical registers.
- /// The SparseSet allows iterating over the (few) live registers for quickly
- /// comparing against a regmask or clearing the set.
- ///
- /// Storage for the map is allocated once for the pass. The map can be
- /// cleared between scheduling regions without freeing unused entries.
- class Reg2SUnitsMap {
- SparseSet<unsigned> PhysRegSet;
- std::vector<std::vector<PhysRegSUOper> > SUnits;
- public:
- typedef SparseSet<unsigned>::const_iterator const_iterator;
-
- // Allow iteration over register numbers (keys) in the map. If needed, we
- // can provide an iterator over SUnits (values) as well.
- const_iterator reg_begin() const { return PhysRegSet.begin(); }
- const_iterator reg_end() const { return PhysRegSet.end(); }
-
- /// Initialize the map with the number of registers.
- /// If the map is already large enough, no allocation occurs.
- /// For simplicity we expect the map to be empty().
- void setRegLimit(unsigned Limit);
-
- /// Returns true if the map is empty.
- bool empty() const { return PhysRegSet.empty(); }
+ PhysRegSUOper(SUnit *su, int op, unsigned R): SU(su), OpIdx(op), Reg(R) {}
- /// Clear the map without deallocating storage.
- void clear();
-
- bool contains(unsigned Reg) const { return PhysRegSet.count(Reg); }
-
- /// If this register is mapped, return its existing SUnits vector.
- /// Otherwise map the register and return an empty SUnits vector.
- std::vector<PhysRegSUOper> &operator[](unsigned Reg) {
- bool New = PhysRegSet.insert(Reg).second;
- assert((!New || SUnits[Reg].empty()) && "stale SUnits vector");
- (void)New;
- return SUnits[Reg];
- }
-
- /// Erase an existing element without freeing memory.
- void erase(unsigned Reg) {
- PhysRegSet.erase(Reg);
- SUnits[Reg].clear();
- }
+ unsigned getSparseSetIndex() const { return Reg; }
};
+ /// Use a SparseMultiSet to track physical registers. Storage is only
+ /// allocated once for the pass. It can be cleared in constant time and reused
+ /// without any frees.
+ typedef SparseMultiSet<PhysRegSUOper, llvm::identity<unsigned>, uint16_t> Reg2SUnitsMap;
+
/// Use SparseSet as a SparseMap by relying on the fact that it never
/// compares ValueT's, only unsigned keys. This allows the set to be cleared
/// between scheduling regions in constant time as long as ValueT does not
diff --git a/include/llvm/CodeGen/ScheduleDFS.h b/include/llvm/CodeGen/ScheduleDFS.h
index fbbadd9..73ce99f 100644
--- a/include/llvm/CodeGen/ScheduleDFS.h
+++ b/include/llvm/CodeGen/ScheduleDFS.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_SCHEDULEDAGILP_H
-#define LLVM_CODEGEN_SCHEDULEDAGILP_H
+#ifndef LLVM_CODEGEN_SCHEDULEDFS_H
+#define LLVM_CODEGEN_SCHEDULEDFS_H
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/Support/DataTypes.h"
@@ -27,6 +27,9 @@ class SUnit;
/// \brief Represent the ILP of the subDAG rooted at a DAG node.
///
+/// ILPValues summarize the DAG subtree rooted at each node. ILPValues are
+/// valid for all nodes regardless of their subtree membership.
+///
/// When computed using bottom-up DFS, this metric assumes that the DAG is a
/// forest of trees with roots at the bottom of the schedule branching upward.
struct ILPValue {
@@ -62,19 +65,30 @@ struct ILPValue {
};
/// \brief Compute the values of each DAG node for various metrics during DFS.
-///
-/// ILPValues summarize the DAG subtree rooted at each node up to
-/// SubtreeLimit. ILPValues are also valid for interior nodes of a subtree, not
-/// just the root.
class SchedDFSResult {
friend class SchedDFSImpl;
+ static const unsigned InvalidSubtreeID = ~0u;
+
/// \brief Per-SUnit data computed during DFS for various metrics.
+ ///
+ /// A node's SubtreeID is set to itself when it is visited to indicate that it
+ /// is the root of a subtree. Later it is set to its parent to indicate an
+ /// interior node. Finally, it is set to a representative subtree ID during
+ /// finalization.
struct NodeData {
unsigned InstrCount;
unsigned SubtreeID;
- NodeData(): InstrCount(0), SubtreeID(0) {}
+ NodeData(): InstrCount(0), SubtreeID(InvalidSubtreeID) {}
+ };
+
+ /// \brief Per-Subtree data computed during DFS.
+ struct TreeData {
+ unsigned ParentTreeID;
+ unsigned SubInstrCount;
+
+ TreeData(): ParentTreeID(InvalidSubtreeID), SubInstrCount(0) {}
};
/// \brief Record a connection between subtrees and the connection level.
@@ -88,7 +102,10 @@ class SchedDFSResult {
bool IsBottomUp;
unsigned SubtreeLimit;
/// DFS results for each SUnit in this DAG.
- std::vector<NodeData> DFSData;
+ std::vector<NodeData> DFSNodeData;
+
+ // Store per-tree data indexed on tree ID,
+ SmallVector<TreeData, 16> DFSTreeData;
// For each subtree discovered during DFS, record its connections to other
// subtrees.
@@ -102,41 +119,68 @@ public:
SchedDFSResult(bool IsBU, unsigned lim)
: IsBottomUp(IsBU), SubtreeLimit(lim) {}
+ /// \brief Get the node cutoff before subtrees are considered significant.
+ unsigned getSubtreeLimit() const { return SubtreeLimit; }
+
+ /// \brief Return true if this DFSResult is uninitialized.
+ ///
+ /// resize() initializes DFSResult, while compute() populates it.
+ bool empty() const { return DFSNodeData.empty(); }
+
/// \brief Clear the results.
void clear() {
- DFSData.clear();
+ DFSNodeData.clear();
+ DFSTreeData.clear();
SubtreeConnections.clear();
SubtreeConnectLevels.clear();
}
/// \brief Initialize the result data with the size of the DAG.
void resize(unsigned NumSUnits) {
- DFSData.resize(NumSUnits);
+ DFSNodeData.resize(NumSUnits);
}
/// \brief Compute various metrics for the DAG with given roots.
- void compute(ArrayRef<SUnit *> Roots);
+ void compute(ArrayRef<SUnit> SUnits);
+
+ /// \brief Get the number of instructions in the given subtree and its
+ /// children.
+ unsigned getNumInstrs(const SUnit *SU) const {
+ return DFSNodeData[SU->NodeNum].InstrCount;
+ }
+
+ /// \brief Get the number of instructions in the given subtree not including
+ /// children.
+ unsigned getNumSubInstrs(unsigned SubtreeID) const {
+ return DFSTreeData[SubtreeID].SubInstrCount;
+ }
/// \brief Get the ILP value for a DAG node.
///
/// A leaf node has an ILP of 1/1.
- ILPValue getILP(const SUnit *SU) {
- return ILPValue(DFSData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
+ ILPValue getILP(const SUnit *SU) const {
+ return ILPValue(DFSNodeData[SU->NodeNum].InstrCount, 1 + SU->getDepth());
}
/// \brief The number of subtrees detected in this DAG.
unsigned getNumSubtrees() const { return SubtreeConnectLevels.size(); }
/// \brief Get the ID of the subtree the given DAG node belongs to.
- unsigned getSubtreeID(const SUnit *SU) {
- return DFSData[SU->NodeNum].SubtreeID;
+ ///
+ /// For convenience, if DFSResults have not been computed yet, give everything
+ /// tree ID 0.
+ unsigned getSubtreeID(const SUnit *SU) const {
+ if (empty())
+ return 0;
+ assert(SU->NodeNum < DFSNodeData.size() && "New Node");
+ return DFSNodeData[SU->NodeNum].SubtreeID;
}
/// \brief Get the connection level of a subtree.
///
/// For bottom-up trees, the connection level is the latency depth (in cycles)
/// of the deepest connection to another subtree.
- unsigned getSubtreeLevel(unsigned SubtreeID) {
+ unsigned getSubtreeLevel(unsigned SubtreeID) const {
return SubtreeConnectLevels[SubtreeID];
}
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
index 836b73a..51ac7f2 100644
--- a/include/llvm/CodeGen/SchedulerRegistry.h
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H
-#define LLVM_CODEGENSCHEDULERREGISTRY_H
+#ifndef LLVM_CODEGEN_SCHEDULERREGISTRY_H
+#define LLVM_CODEGEN_SCHEDULERREGISTRY_H
#include "llvm/CodeGen/MachinePassRegistry.h"
#include "llvm/Target/TargetMachine.h"
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index c5cc8f5..c25497a 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -935,6 +935,20 @@ public:
}
}
+ /// Returns an APFloat semantics tag appropriate for the given type. If VT is
+ /// a vector type, the element semantics are returned.
+ static const fltSemantics &EVTToAPFloatSemantics(EVT VT) {
+ switch (VT.getScalarType().getSimpleVT().SimpleTy) {
+ default: llvm_unreachable("Unknown FP format");
+ case MVT::f16: return APFloat::IEEEhalf;
+ case MVT::f32: return APFloat::IEEEsingle;
+ case MVT::f64: return APFloat::IEEEdouble;
+ case MVT::f80: return APFloat::x87DoubleExtended;
+ case MVT::f128: return APFloat::IEEEquad;
+ case MVT::ppcf128: return APFloat::PPCDoubleDouble;
+ }
+ }
+
/// AssignOrdering - Assign an order to the SDNode.
void AssignOrdering(const SDNode *SD, unsigned Order);
@@ -978,10 +992,8 @@ public:
SDValue CreateStackTemporary(EVT VT1, EVT VT2);
/// FoldConstantArithmetic -
- SDValue FoldConstantArithmetic(unsigned Opcode,
- EVT VT,
- ConstantSDNode *Cst1,
- ConstantSDNode *Cst2);
+ SDValue FoldConstantArithmetic(unsigned Opcode, EVT VT,
+ SDNode *Cst1, SDNode *Cst2);
/// FoldSetCC - Constant fold a setcc to true or false.
SDValue FoldSetCC(EVT VT, SDValue N1,
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index 16aacc0..af7993f 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H
-#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H
+#ifndef LLVM_CODEGEN_SELECTIONDAGISEL_H
+#define LLVM_CODEGEN_SELECTIONDAGISEL_H
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/SelectionDAG.h"
@@ -281,4 +281,4 @@ private:
}
-#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */
+#endif /* LLVM_CODEGEN_SELECTIONDAGISEL_H */
diff --git a/include/llvm/CodeGen/SlotIndexes.h b/include/llvm/CodeGen/SlotIndexes.h
index b46d153..78fb233 100644
--- a/include/llvm/CodeGen/SlotIndexes.h
+++ b/include/llvm/CodeGen/SlotIndexes.h
@@ -112,7 +112,7 @@ namespace llvm {
return lie.getPointer();
}
- int getIndex() const {
+ unsigned getIndex() const {
return listEntry()->getIndex() | getSlot();
}
@@ -360,6 +360,11 @@ namespace llvm {
/// Renumber the index list, providing space for new instructions.
void renumberIndexes();
+ /// Repair indexes after adding and removing instructions.
+ void repairIndexesInRange(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator Begin,
+ MachineBasicBlock::iterator End);
+
/// Returns the zero index for this analysis.
SlotIndex getZeroIndex() {
assert(indexList.front().getIndex() == 0 && "First index is not 0?");
@@ -602,29 +607,35 @@ namespace llvm {
void insertMBBInMaps(MachineBasicBlock *mbb) {
MachineFunction::iterator nextMBB =
llvm::next(MachineFunction::iterator(mbb));
- IndexListEntry *startEntry = createEntry(0, 0);
- IndexListEntry *stopEntry = createEntry(0, 0);
- IndexListEntry *nextEntry = 0;
+ IndexListEntry *startEntry = 0;
+ IndexListEntry *endEntry = 0;
+ IndexList::iterator newItr;
if (nextMBB == mbb->getParent()->end()) {
- nextEntry = indexList.end();
+ startEntry = &indexList.back();
+ endEntry = createEntry(0, 0);
+ newItr = indexList.insertAfter(startEntry, endEntry);
} else {
- nextEntry = getMBBStartIdx(nextMBB).listEntry();
+ startEntry = createEntry(0, 0);
+ endEntry = getMBBStartIdx(nextMBB).listEntry();
+ newItr = indexList.insert(endEntry, startEntry);
}
- indexList.insert(nextEntry, startEntry);
- indexList.insert(nextEntry, stopEntry);
-
SlotIndex startIdx(startEntry, SlotIndex::Slot_Block);
- SlotIndex endIdx(nextEntry, SlotIndex::Slot_Block);
+ SlotIndex endIdx(endEntry, SlotIndex::Slot_Block);
+
+ MachineFunction::iterator prevMBB(mbb);
+ assert(prevMBB != mbb->getParent()->end() &&
+ "Can't insert a new block at the beginning of a function.");
+ --prevMBB;
+ MBBRanges[prevMBB->getNumber()].second = startIdx;
assert(unsigned(mbb->getNumber()) == MBBRanges.size() &&
"Blocks must be added in order");
MBBRanges.push_back(std::make_pair(startIdx, endIdx));
-
idx2MBBMap.push_back(IdxMBBPair(startIdx, mbb));
- renumberIndexes();
+ renumberIndexes(newItr);
std::sort(idx2MBBMap.begin(), idx2MBBMap.end(), Idx2MBBCompare());
}
diff --git a/include/llvm/CodeGen/TargetSchedule.h b/include/llvm/CodeGen/TargetSchedule.h
index 4c4a2a8..3e22252 100644
--- a/include/llvm/CodeGen/TargetSchedule.h
+++ b/include/llvm/CodeGen/TargetSchedule.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_TARGETSCHEDMODEL_H
-#define LLVM_TARGET_TARGETSCHEDMODEL_H
+#ifndef LLVM_CODEGEN_TARGETSCHEDULE_H
+#define LLVM_CODEGEN_TARGETSCHEDULE_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCInstrItineraries.h"
@@ -84,6 +84,9 @@ public:
/// \brief Maximum number of micro-ops that may be scheduled per cycle.
unsigned getIssueWidth() const { return SchedModel.IssueWidth; }
+ /// \brief Number of cycles the OOO processor is expected to hide.
+ unsigned getILPWindow() const { return SchedModel.ILPWindow; }
+
/// \brief Return the number of issue slots required for this MI.
unsigned getNumMicroOps(const MachineInstr *MI,
const MCSchedClassDesc *SC = 0) const;
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index f8a6503..ec48b67 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -827,7 +827,7 @@ namespace llvm {
/// types are returned as Other, otherwise they are invalid.
static EVT getEVT(Type *Ty, bool HandleUnknown = false);
- intptr_t getRawBits() {
+ intptr_t getRawBits() const {
if (isSimple())
return V.SimpleTy;
else
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index ff765cc..0a26857 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -72,7 +72,7 @@
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
-/* Define if __crashreporter_info__ exists. */
+/* can use __crashreporter_info__ */
#undef HAVE_CRASHREPORTER_INFO
/* Define to 1 if you have the <ctype.h> header file. */
@@ -146,6 +146,24 @@
/* Define to 1 if you have the `floorf' function. */
#cmakedefine HAVE_FLOORF ${HAVE_FLOORF}
+/* Define to 1 if you have the `log' function. */
+#cmakedefine HAVE_LOG ${HAVE_LOG}
+
+/* Define to 1 if you have the `log2' function. */
+#cmakedefine HAVE_LOG2 ${HAVE_LOG2}
+
+/* Define to 1 if you have the `log10' function. */
+#cmakedefine HAVE_LOG10 ${HAVE_LOG10}
+
+/* Define to 1 if you have the `exp' function. */
+#cmakedefine HAVE_EXP ${HAVE_LOG}
+
+/* Define to 1 if you have the `exp2' function. */
+#cmakedefine HAVE_EXP2 ${HAVE_LOG2}
+
+/* Define to 1 if you have the `exp10' function. */
+#cmakedefine HAVE_EXP10 ${HAVE_LOG10}
+
/* Define to 1 if you have the `fmodf' function. */
#cmakedefine HAVE_FMODF ${HAVE_FMODF}
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index a4f8af4..2f9e6ff 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -72,7 +72,7 @@
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
-/* Define if __crashreporter_info__ exists. */
+/* can use __crashreporter_info__ */
#undef HAVE_CRASHREPORTER_INFO
/* Define to 1 if you have the <ctype.h> header file. */
@@ -122,6 +122,12 @@
/* Define to 1 if you have the <execinfo.h> header file. */
#undef HAVE_EXECINFO_H
+/* Define to 1 if you have the `exp' function. */
+#undef HAVE_EXP
+
+/* Define to 1 if you have the `exp2' function. */
+#undef HAVE_EXP2
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@@ -225,6 +231,15 @@
the current directory to the dynamic linker search path. */
#undef HAVE_LINK_R
+/* Define to 1 if you have the `log' function. */
+#undef HAVE_LOG
+
+/* Define to 1 if you have the `log10' function. */
+#undef HAVE_LOG10
+
+/* Define to 1 if you have the `log2' function. */
+#undef HAVE_LOG2
+
/* Define to 1 if you have the `longjmp' function. */
#undef HAVE_LONGJMP
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index fbc3040..eda17ee 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -124,4 +124,7 @@
/* Minor version of the LLVM API */
#cmakedefine LLVM_VERSION_MINOR ${LLVM_VERSION_MINOR}
+/* Define to 1 if you have the <sanitizer/msan_interface.h> header file. */
+#cmakedefine HAVE_SANITIZER_MSAN_INTERFACE_H ${HAVE_SANITIZER_MSAN_INTERFACE_H}
+
#endif
diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h
index 0a59cdd..d598475 100644
--- a/include/llvm/DIBuilder.h
+++ b/include/llvm/DIBuilder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DIBUILDER_H
-#define LLVM_ANALYSIS_DIBUILDER_H
+#ifndef LLVM_DIBUILDER_H
+#define LLVM_DIBUILDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -28,6 +28,9 @@ namespace llvm {
class LLVMContext;
class MDNode;
class StringRef;
+ class DIBasicType;
+ class DICompositeType;
+ class DIDerivedType;
class DIDescriptor;
class DIFile;
class DIEnumerator;
@@ -88,9 +91,12 @@ namespace llvm {
/// by a tool analyzing generated debugging information.
/// @param RV This indicates runtime version for languages like
/// Objective-C.
+ /// @param SplitName The name of the file that we'll split debug info out
+ /// into.
void createCompileUnit(unsigned Lang, StringRef File, StringRef Dir,
- StringRef Producer,
- bool isOptimized, StringRef Flags, unsigned RV);
+ StringRef Producer, bool isOptimized,
+ StringRef Flags, unsigned RV,
+ StringRef SplitName = StringRef());
/// createFile - Create a file descriptor to hold debugging information
/// for a file.
@@ -108,32 +114,32 @@ namespace llvm {
/// @param SizeInBits Size of the type.
/// @param AlignInBits Type alignment.
/// @param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
- DIType createBasicType(StringRef Name, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Encoding);
+ DIBasicType createBasicType(StringRef Name, uint64_t SizeInBits,
+ uint64_t AlignInBits, unsigned Encoding);
/// createQualifiedType - Create debugging information entry for a qualified
/// type, e.g. 'const int'.
/// @param Tag Tag identifing type, e.g. dwarf::TAG_volatile_type
/// @param FromTy Base Type.
- DIType createQualifiedType(unsigned Tag, DIType FromTy);
+ DIDerivedType createQualifiedType(unsigned Tag, DIType FromTy);
/// createPointerType - Create debugging information entry for a pointer.
/// @param PointeeTy Type pointed by this pointer.
/// @param SizeInBits Size.
/// @param AlignInBits Alignment. (optional)
/// @param Name Pointer type name. (optional)
- DIType createPointerType(DIType PointeeTy, uint64_t SizeInBits,
- uint64_t AlignInBits = 0,
- StringRef Name = StringRef());
+ DIDerivedType
+ createPointerType(DIType PointeeTy, uint64_t SizeInBits,
+ uint64_t AlignInBits = 0, StringRef Name = StringRef());
/// \brief Create debugging information entry for a pointer to member.
/// @param PointeeTy Type pointed to by this pointer.
/// @param Class Type for which this pointer points to members of.
- DIType createMemberPointerType(DIType PointeeTy, DIType Class);
+ DIDerivedType createMemberPointerType(DIType PointeeTy, DIType Class);
/// createReferenceType - Create debugging information entry for a c++
/// style reference or rvalue reference type.
- DIType createReferenceType(unsigned Tag, DIType RTy);
+ DIDerivedType createReferenceType(unsigned Tag, DIType RTy);
/// createTypedef - Create debugging information entry for a typedef.
/// @param Ty Original type.
@@ -141,8 +147,8 @@ namespace llvm {
/// @param File File where this type is defined.
/// @param LineNo Line number.
/// @param Context The surrounding context for the typedef.
- DIType createTypedef(DIType Ty, StringRef Name, DIFile File,
- unsigned LineNo, DIDescriptor Context);
+ DIDerivedType createTypedef(DIType Ty, StringRef Name, DIFile File,
+ unsigned LineNo, DIDescriptor Context);
/// createFriend - Create debugging information entry for a 'friend'.
DIType createFriend(DIType Ty, DIType FriendTy);
@@ -154,8 +160,8 @@ namespace llvm {
/// @param BaseOffset Base offset.
/// @param Flags Flags to describe inheritance attribute,
/// e.g. private
- DIType createInheritance(DIType Ty, DIType BaseTy, uint64_t BaseOffset,
- unsigned Flags);
+ DIDerivedType createInheritance(DIType Ty, DIType BaseTy,
+ uint64_t BaseOffset, unsigned Flags);
/// createMemberType - Create debugging information entry for a member.
/// @param Scope Member scope.
@@ -167,10 +173,23 @@ namespace llvm {
/// @param OffsetInBits Member offset.
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Ty Parent type.
- DIType createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNo, uint64_t SizeInBits,
- uint64_t AlignInBits, uint64_t OffsetInBits,
- unsigned Flags, DIType Ty);
+ DIDerivedType
+ createMemberType(DIDescriptor Scope, StringRef Name, DIFile File,
+ unsigned LineNo, uint64_t SizeInBits, uint64_t AlignInBits,
+ uint64_t OffsetInBits, unsigned Flags, DIType Ty);
+
+ /// createStaticMemberType - Create debugging information entry for a
+ /// C++ static data member.
+ /// @param Scope Member scope.
+ /// @param Name Member name.
+ /// @param File File where this member is declared.
+ /// @param LineNo Line number.
+ /// @param Ty Type of the static member.
+ /// @param Flags Flags to encode member attribute, e.g. private.
+ /// @param Val Const initializer of the member.
+ DIType createStaticMemberType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNo, DIType Ty,
+ unsigned Flags, llvm::Value *Val);
/// createObjCIVar - Create debugging information entry for Objective-C
/// instance variable.
@@ -263,10 +282,12 @@ namespace llvm {
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Elements Struct elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
- DIType createStructType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Flags,
- DIArray Elements, unsigned RunTimeLang = 0);
+ DICompositeType createStructType(DIDescriptor Scope, StringRef Name,
+ DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits,
+ unsigned Flags, DIType DerivedFrom,
+ DIArray Elements, unsigned RunTimeLang = 0,
+ MDNode *VTableHolder = 0);
/// createUnionType - Create debugging information entry for an union.
/// @param Scope Scope in which this union is defined.
@@ -278,10 +299,10 @@ namespace llvm {
/// @param Flags Flags to encode member attribute, e.g. private
/// @param Elements Union elements.
/// @param RunTimeLang Optional parameter, Objective-C runtime version.
- DIType createUnionType(DIDescriptor Scope, StringRef Name, DIFile File,
- unsigned LineNumber, uint64_t SizeInBits,
- uint64_t AlignInBits, unsigned Flags,
- DIArray Elements, unsigned RunTimeLang = 0);
+ DICompositeType createUnionType(
+ DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags,
+ DIArray Elements, unsigned RunTimeLang = 0);
/// createTemplateTypeParameter - Create debugging information for template
/// type parameter.
@@ -316,8 +337,8 @@ namespace llvm {
/// @param AlignInBits Alignment.
/// @param Ty Element type.
/// @param Subscripts Subscripts.
- DIType createArrayType(uint64_t Size, uint64_t AlignInBits,
- DIType Ty, DIArray Subscripts);
+ DICompositeType createArrayType(uint64_t Size, uint64_t AlignInBits,
+ DIType Ty, DIArray Subscripts);
/// createVectorType - Create debugging information entry for a vector type.
/// @param Size Array size.
@@ -336,16 +357,16 @@ namespace llvm {
/// @param SizeInBits Member size.
/// @param AlignInBits Member alignment.
/// @param Elements Enumeration elements.
- DIType createEnumerationType(DIDescriptor Scope, StringRef Name,
- DIFile File, unsigned LineNumber,
- uint64_t SizeInBits, uint64_t AlignInBits,
- DIArray Elements, DIType ClassType);
+ DICompositeType createEnumerationType(
+ DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber,
+ uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements,
+ DIType ClassType);
/// createSubroutineType - Create subroutine type.
/// @param File File in which this subroutine is defined.
/// @param ParameterTypes An array of subroutine parameter types. This
/// includes return type at 0th index.
- DIType createSubroutineType(DIFile File, DIArray ParameterTypes);
+ DICompositeType createSubroutineType(DIFile File, DIArray ParameterTypes);
/// createArtificialType - Create a new DIType with "artificial" flag set.
DIType createArtificialType(DIType Ty);
@@ -402,10 +423,12 @@ namespace llvm {
/// @param isLocalToUnit Boolean flag indicate whether this variable is
/// externally visible or not.
/// @param Val llvm::Value of the variable.
+ /// @param Decl Reference to the corresponding declaration.
DIGlobalVariable
createStaticVariable(DIDescriptor Context, StringRef Name,
StringRef LinkageName, DIFile File, unsigned LineNo,
- DIType Ty, bool isLocalToUnit, llvm::Value *Val);
+ DIType Ty, bool isLocalToUnit, llvm::Value *Val,
+ MDNode *Decl = NULL);
/// createLocalVariable - Create a new descriptor for the specified
diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h
index cc1c6a0..c557a7a 100644
--- a/include/llvm/DebugInfo.h
+++ b/include/llvm/DebugInfo.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ANALYSIS_DEBUGINFO_H
-#define LLVM_ANALYSIS_DEBUGINFO_H
+#ifndef LLVM_DEBUGINFO_H
+#define LLVM_DEBUGINFO_H
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
@@ -62,7 +62,8 @@ namespace llvm {
FlagPrototyped = 1 << 8,
FlagObjcClassComplete = 1 << 9,
FlagObjectPointer = 1 << 10,
- FlagVector = 1 << 11
+ FlagVector = 1 << 11,
+ FlagStaticMember = 1 << 12
};
protected:
const MDNode *DbgNode;
@@ -186,12 +187,12 @@ namespace llvm {
/// isMain - Each input file is encoded as a separate compile unit in LLVM
/// debugging information output. However, many target specific tool chains
/// prefer to encode only one compile unit in an object file. In this
- /// situation, the LLVM code generator will include debugging information
+ /// situation, the LLVM code generator will include debugging information
/// entities in the compile unit that is marked as main compile unit. The
/// code generator accepts maximum one main compile unit per module. If a
/// module does not contain any main compile unit then the code generator
/// will emit multiple compile units in the output object file.
-
+ // TODO: This can be removed when we remove the legacy debug information.
bool isMain() const { return getUnsignedField(6) != 0; }
bool isOptimized() const { return getUnsignedField(7) != 0; }
StringRef getFlags() const { return getStringField(8); }
@@ -202,6 +203,8 @@ namespace llvm {
DIArray getSubprograms() const;
DIArray getGlobalVariables() const;
+ StringRef getSplitDebugFilename() const { return getStringField(14); }
+
/// Verify - Verify that a compile unit is well formed.
bool Verify() const;
};
@@ -300,6 +303,9 @@ namespace llvm {
bool isVector() const {
return (getFlags() & FlagVector) != 0;
}
+ bool isStaticMember() const {
+ return (getFlags() & FlagStaticMember) != 0;
+ }
bool isValid() const {
return DbgNode && (isBasicType() || isDerivedType() || isCompositeType());
}
@@ -337,7 +343,8 @@ namespace llvm {
};
/// DIDerivedType - A simple derived type, like a const qualified type,
- /// a typedef, a pointer or reference, etc.
+ /// a typedef, a pointer or reference, et cetera. Or, a data member of
+ /// a class/struct/union.
class DIDerivedType : public DIType {
friend class DIDescriptor;
void printInternal(raw_ostream &OS) const;
@@ -363,6 +370,11 @@ namespace llvm {
return getFieldAs<DIType>(10);
}
+ Constant *getConstant() const {
+ assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
+ return getConstantField(10);
+ }
+
StringRef getObjCPropertyName() const {
if (getVersion() > LLVMDebugVersion11)
return StringRef();
@@ -512,6 +524,10 @@ namespace llvm {
return getFieldAs<DICompositeType>(13);
}
+ unsigned getFlags() const {
+ return getUnsignedField(14);
+ }
+
unsigned isArtificial() const {
if (getVersion() <= llvm::LLVMDebugVersion8)
return getUnsignedField(14);
@@ -560,6 +576,10 @@ namespace llvm {
return getFieldAs<DIFile>(6).getDirectory();
}
+ DIFile getFile() const {
+ return getFieldAs<DIFile>(6);
+ }
+
/// getScopeLineNumber - Get the beginning of the scope of the
/// function, not necessarily where the name of the program
/// starts.
@@ -620,6 +640,9 @@ namespace llvm {
GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
Constant *getConstant() const { return getConstantField(11); }
+ DIDerivedType getStaticDataMemberDeclaration() const {
+ return getFieldAs<DIDerivedType>(12);
+ }
/// Verify - Verify that a global variable descriptor is well formed.
bool Verify() const;
@@ -692,7 +715,7 @@ namespace llvm {
return getType().isBlockByrefStruct();
}
- /// isInlinedFnArgument - Return trule if this variable provides debugging
+ /// isInlinedFnArgument - Return true if this variable provides debugging
/// information for an inlined function arguments.
bool isInlinedFnArgument(const Function *CurFn);
@@ -721,7 +744,7 @@ namespace llvm {
class DILexicalBlockFile : public DIScope {
public:
explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
- DIScope getContext() const { return getScope().getContext(); }
+ DIScope getContext() const { if (getScope().isSubprogram()) return getScope(); return getScope().getContext(); }
unsigned getLineNumber() const { return getScope().getLineNumber(); }
unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
StringRef getDirectory() const {
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index 5ebf4b0..8fcd9e0 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -58,6 +58,8 @@ public:
}
};
+typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
+
/// DIInliningInfo - a format-neutral container for inlined code description.
class DIInliningInfo {
SmallVector<DILineInfo, 4> Frames;
@@ -92,6 +94,24 @@ public:
}
};
+/// Selects which debug sections get dumped.
+enum DIDumpType {
+ DIDT_Null,
+ DIDT_All,
+ DIDT_Abbrev,
+ DIDT_AbbrevDwo,
+ DIDT_Aranges,
+ DIDT_Frames,
+ DIDT_Info,
+ DIDT_InfoDwo,
+ DIDT_Line,
+ DIDT_Ranges,
+ DIDT_Pubnames,
+ DIDT_Str,
+ DIDT_StrDwo,
+ DIDT_StrOffsetsDwo
+};
+
// In place of applying the relocations to the data we've read from disk we use
// a separate mapping table to the side and checking that at locations in the
// dwarf where we expect relocated values. This adds a bit of complexity to the
@@ -106,10 +126,12 @@ public:
/// getDWARFContext - get a context for binary DWARF data.
static DIContext *getDWARFContext(object::ObjectFile *);
- virtual void dump(raw_ostream &OS) = 0;
+ virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All) = 0;
virtual DILineInfo getLineInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
+ uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
};
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 2d60c36..3fd69e266 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_H
-#define LLVM_EXECUTION_ENGINE_H
+#ifndef LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
+#define LLVM_EXECUTIONENGINE_EXECUTIONENGINE_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h
index a2fed98..e160e3a 100644
--- a/include/llvm/ExecutionEngine/GenericValue.h
+++ b/include/llvm/ExecutionEngine/GenericValue.h
@@ -12,8 +12,8 @@
//===----------------------------------------------------------------------===//
-#ifndef GENERIC_VALUE_H
-#define GENERIC_VALUE_H
+#ifndef LLVM_EXECUTIONENGINE_GENERICVALUE_H
+#define LLVM_EXECUTIONENGINE_GENERICVALUE_H
#include "llvm/ADT/APInt.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/ExecutionEngine/Interpreter.h b/include/llvm/ExecutionEngine/Interpreter.h
index 72d97ef..f49d0c4 100644
--- a/include/llvm/ExecutionEngine/Interpreter.h
+++ b/include/llvm/ExecutionEngine/Interpreter.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef EXECUTION_ENGINE_INTERPRETER_H
-#define EXECUTION_ENGINE_INTERPRETER_H
+#ifndef LLVM_EXECUTIONENGINE_INTERPRETER_H
+#define LLVM_EXECUTIONENGINE_INTERPRETER_H
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include <cstdlib>
diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h
index b4cda1d..581d6e6 100644
--- a/include/llvm/ExecutionEngine/JIT.h
+++ b/include/llvm/ExecutionEngine/JIT.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_JIT_H
-#define LLVM_EXECUTION_ENGINE_JIT_H
+#ifndef LLVM_EXECUTIONENGINE_JIT_H
+#define LLVM_EXECUTIONENGINE_JIT_H
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include <cstdlib>
diff --git a/include/llvm/ExecutionEngine/JITEventListener.h b/include/llvm/ExecutionEngine/JITEventListener.h
index 3aa014e..ed66102 100644
--- a/include/llvm/ExecutionEngine/JITEventListener.h
+++ b/include/llvm/ExecutionEngine/JITEventListener.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
-#define LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
+#ifndef LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
+#define LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/DataTypes.h"
@@ -127,4 +127,4 @@ public:
} // end namespace llvm.
-#endif // defined LLVM_EXECUTION_ENGINE_JIT_EVENTLISTENER_H
+#endif // defined LLVM_EXECUTIONENGINE_JITEVENTLISTENER_H
diff --git a/include/llvm/ExecutionEngine/JITMemoryManager.h b/include/llvm/ExecutionEngine/JITMemoryManager.h
index 29e01aa..714a980 100644
--- a/include/llvm/ExecutionEngine/JITMemoryManager.h
+++ b/include/llvm/ExecutionEngine/JITMemoryManager.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
-#define LLVM_EXECUTION_ENGINE_JIT_MEMMANAGER_H
+#ifndef LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_JITMEMORYMANAGER_H
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h
index ac16bdc..66ddb7c 100644
--- a/include/llvm/ExecutionEngine/MCJIT.h
+++ b/include/llvm/ExecutionEngine/MCJIT.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H
-#define LLVM_EXECUTION_ENGINE_MCJIT_H
+#ifndef LLVM_EXECUTIONENGINE_MCJIT_H
+#define LLVM_EXECUTIONENGINE_MCJIT_H
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include <cstdlib>
diff --git a/include/llvm/ExecutionEngine/OProfileWrapper.h b/include/llvm/ExecutionEngine/OProfileWrapper.h
index 99553a3..05da594 100644
--- a/include/llvm/ExecutionEngine/OProfileWrapper.h
+++ b/include/llvm/ExecutionEngine/OProfileWrapper.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef OPROFILE_WRAPPER_H
-#define OPROFILE_WRAPPER_H
+#ifndef LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
+#define LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
#include "llvm/Support/DataTypes.h"
#include <opagent.h>
@@ -121,4 +121,4 @@ private:
} // namespace llvm
-#endif //OPROFILE_WRAPPER_H
+#endif // LLVM_EXECUTIONENGINE_OPROFILEWRAPPER_H
diff --git a/include/llvm/ExecutionEngine/ObjectImage.h b/include/llvm/ExecutionEngine/ObjectImage.h
index d09e4de..9fddca7 100644
--- a/include/llvm/ExecutionEngine/ObjectImage.h
+++ b/include/llvm/ExecutionEngine/ObjectImage.h
@@ -50,6 +50,8 @@ public:
virtual StringRef getData() const = 0;
+ virtual object::ObjectFile* getObjectFile() const = 0;
+
// Subclasses can override these methods to provide JIT debugging support
virtual void registerWithDebugger() = 0;
virtual void deregisterWithDebugger() = 0;
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index e2905e3..4222d53 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_RUNTIME_DYLD_H
-#define LLVM_RUNTIME_DYLD_H
+#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
+#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/ObjectBuffer.h"
diff --git a/include/llvm/ExecutionEngine/SectionMemoryManager.h b/include/llvm/ExecutionEngine/SectionMemoryManager.h
index ba4ba8d0..ae5004e 100644
--- a/include/llvm/ExecutionEngine/SectionMemoryManager.h
+++ b/include/llvm/ExecutionEngine/SectionMemoryManager.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
-#define LLVM_EXECUTION_ENGINE_SECTION_MEMORY_MANAGER_H
+#ifndef LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
+#define LLVM_EXECUTIONENGINE_SECTIONMEMORYMANAGER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
diff --git a/include/llvm/GVMaterializer.h b/include/llvm/GVMaterializer.h
index c143552..1e5c426 100644
--- a/include/llvm/GVMaterializer.h
+++ b/include/llvm/GVMaterializer.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef GVMATERIALIZER_H
-#define GVMATERIALIZER_H
+#ifndef LLVM_GVMATERIALIZER_H
+#define LLVM_GVMATERIALIZER_H
#include <string>
diff --git a/include/llvm/IR/Argument.h b/include/llvm/IR/Argument.h
index f737e40..ef4e4fc 100644
--- a/include/llvm/IR/Argument.h
+++ b/include/llvm/IR/Argument.h
@@ -7,12 +7,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file declares the Argument class.
+// This file declares the Argument class.
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ARGUMENT_H
-#define LLVM_ARGUMENT_H
+#ifndef LLVM_IR_ARGUMENT_H
+#define LLVM_IR_ARGUMENT_H
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
@@ -24,11 +24,14 @@ namespace llvm {
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-/// A class to represent an incoming formal argument to a Function. An argument
-/// is a very simple Value. It is essentially a named (optional) type. When used
-/// in the body of a function, it represents the value of the actual argument
-/// the function was called with.
-/// @brief LLVM Argument representation
+/// \brief LLVM Argument representation
+///
+/// This class represents an incoming formal argument to a Function. A formal
+/// argument, since it is ``formal'', does not contain an actual value but
+/// instead represents the type, argument number, and attributes of an argument
+/// for a specific function. When used in the body of said function, the
+/// argument of course represents the value of the actual argument that the
+/// function was called with.
class Argument : public Value, public ilist_node<Argument> {
virtual void anchor();
Function *Parent;
@@ -37,50 +40,52 @@ class Argument : public Value, public ilist_node<Argument> {
void setParent(Function *parent);
public:
- /// Argument ctor - If Function argument is specified, this argument is
- /// inserted at the end of the argument list for the function.
+ /// \brief Constructor.
///
+ /// If \p F is specified, the argument is inserted at the end of the argument
+ /// list for \p F.
explicit Argument(Type *Ty, const Twine &Name = "", Function *F = 0);
inline const Function *getParent() const { return Parent; }
inline Function *getParent() { return Parent; }
- /// getArgNo - Return the index of this formal argument in its containing
- /// function. For example in "void foo(int a, float b)" a is 0 and b is 1.
+ /// \brief Return the index of this formal argument in its containing
+ /// function.
+ ///
+ /// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned getArgNo() const;
-
- /// hasByValAttr - Return true if this argument has the byval attribute on it
- /// in its containing function.
+
+ /// \brief Return true if this argument has the byval attribute on it in its
+ /// containing function.
bool hasByValAttr() const;
-
- /// getParamAlignment - If this is a byval argument, return its alignment.
+
+ /// \brief If this is a byval argument, return its alignment.
unsigned getParamAlignment() const;
- /// hasNestAttr - Return true if this argument has the nest attribute on
- /// it in its containing function.
+ /// \brief Return true if this argument has the nest attribute on it in its
+ /// containing function.
bool hasNestAttr() const;
- /// hasNoAliasAttr - Return true if this argument has the noalias attribute on
- /// it in its containing function.
+ /// \brief Return true if this argument has the noalias attribute on it in its
+ /// containing function.
bool hasNoAliasAttr() const;
-
- /// hasNoCaptureAttr - Return true if this argument has the nocapture
- /// attribute on it in its containing function.
+
+ /// \brief Return true if this argument has the nocapture attribute on it in
+ /// its containing function.
bool hasNoCaptureAttr() const;
-
- /// hasStructRetAttr - Return true if this argument has the sret attribute on
- /// it in its containing function.
+
+ /// \brief Return true if this argument has the sret attribute on it in its
+ /// containing function.
bool hasStructRetAttr() const;
- /// addAttr - Add a Attribute to an argument
- void addAttr(Attribute);
-
- /// removeAttr - Remove a Attribute from an argument
- void removeAttr(Attribute);
+ /// \brief Add a Attribute to an argument.
+ void addAttr(AttributeSet AS);
- /// classof - Methods for support type inquiry through isa, cast, and
- /// dyn_cast:
- ///
+ /// \brief Remove a Attribute from an argument.
+ void removeAttr(AttributeSet AS);
+
+ /// \brief Method for support type inquiry through isa, cast, and
+ /// dyn_cast.
static inline bool classof(const Value *V) {
return V->getValueID() == ArgumentVal;
}
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 95b654c..30c0965 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -13,20 +13,25 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ATTRIBUTES_H
-#define LLVM_ATTRIBUTES_H
+#ifndef LLVM_IR_ATTRIBUTES_H
+#define LLVM_IR_ATTRIBUTES_H
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/Support/MathExtras.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <bitset>
#include <cassert>
+#include <map>
#include <string>
namespace llvm {
class AttrBuilder;
class AttributeImpl;
+class AttributeSetImpl;
+class AttributeSetNode;
class Constant;
+template<typename T> struct DenseMapInfo;
class LLVMContext;
class Type;
@@ -39,13 +44,13 @@ class Type;
class Attribute {
public:
/// This enumeration lists the attributes that can be associated with
- /// parameters, function results or the function itself.
+ /// parameters, function results, or the function itself.
///
- /// Note: uwtable is about the ABI or the user mandating an entry in the
- /// unwind table. The nounwind attribute is about an exception passing by the
- /// function.
+ /// Note: The `uwtable' attribute is about the ABI or the user mandating an
+ /// entry in the unwind table. The `nounwind' attribute is about an exception
+ /// passing by the function.
///
- /// In a theoretical system that uses tables for profiling and sjlj for
+ /// In a theoretical system that uses tables for profiling and SjLj for
/// exceptions, they would be fully independent. In a normal system that uses
/// tables for both, the semantics are:
///
@@ -58,7 +63,6 @@ public:
enum AttrKind {
// IR-Level Attributes
None, ///< No attributes have been set
- AddressSafety, ///< Address safety checking is on.
Alignment, ///< Alignment of parameter (5 bits)
///< stored as log2 of alignment with +1 bias
///< 0 means unaligned (different from align(1))
@@ -70,6 +74,7 @@ public:
Naked, ///< Naked function
Nest, ///< Nested function static chain
NoAlias, ///< Considered to not alias after call
+ NoBuiltin, ///< Callee isn't recognized as a builtin
NoCapture, ///< Function creates no aliases of pointer
NoDuplicate, ///< Call cannot be duplicated
NoImplicitFloat, ///< Disable implicit floating point insts
@@ -90,14 +95,15 @@ public:
///< alignstack=(1))
StackProtect, ///< Stack protection.
StackProtectReq, ///< Stack protection required.
+ StackProtectStrong, ///< Strong Stack protection.
StructRet, ///< Hidden pointer to structure to return
+ SanitizeAddress, ///< AddressSanitizer is on.
+ SanitizeThread, ///< ThreadSanitizer is on.
+ SanitizeMemory, ///< MemorySanitizer is on.
UWTable, ///< Function must be in a unwind table
ZExt, ///< Zero extended before/after call
- EndAttrKinds, ///< Sentinal value useful for loops
-
- AttrKindEmptyKey, ///< Empty key value for DenseMapInfo
- AttrKindTombstoneKey ///< Tombstone key value for DenseMapInfo
+ EndAttrKinds ///< Sentinal value useful for loops
};
private:
AttributeImpl *pImpl;
@@ -105,126 +111,88 @@ private:
public:
Attribute() : pImpl(0) {}
- /// \brief Return a uniquified Attribute object. This takes the uniquified
- /// value from the Builder and wraps it in the Attribute class.
- static Attribute get(LLVMContext &Context, ArrayRef<AttrKind> Vals);
- static Attribute get(LLVMContext &Context, AttrBuilder &B);
+ //===--------------------------------------------------------------------===//
+ // Attribute Construction
+ //===--------------------------------------------------------------------===//
- /// \brief Return true if the attribute is present.
- bool hasAttribute(AttrKind Val) const;
+ /// \brief Return a uniquified Attribute object.
+ static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
+ static Attribute get(LLVMContext &Context, StringRef Kind,
+ StringRef Val = StringRef());
- /// \brief Return true if attributes exist
- bool hasAttributes() const;
+ /// \brief Return a uniquified Attribute object that has the specific
+ /// alignment set.
+ static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align);
+ static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align);
- /// \brief Returns the alignment field of an attribute as a byte alignment
- /// value.
- unsigned getAlignment() const;
+ //===--------------------------------------------------------------------===//
+ // Attribute Accessors
+ //===--------------------------------------------------------------------===//
- /// \brief Set the alignment field of an attribute.
- void setAlignment(unsigned Align);
+ /// \brief Return true if the attribute is an Attribute::AttrKind type.
+ bool isEnumAttribute() const;
- /// \brief Returns the stack alignment field of an attribute as a byte
- /// alignment value.
- unsigned getStackAlignment() const;
+ /// \brief Return true if the attribute is an alignment attribute.
+ bool isAlignAttribute() const;
- /// \brief Set the stack alignment field of an attribute.
- void setStackAlignment(unsigned Align);
+ /// \brief Return true if the attribute is a string (target-dependent)
+ /// attribute.
+ bool isStringAttribute() const;
- /// \brief Equality and non-equality query methods.
- bool operator==(AttrKind K) const;
- bool operator!=(AttrKind K) const;
+ /// \brief Return true if the attribute is present.
+ bool hasAttribute(AttrKind Val) const;
- // FIXME: Remove these 'operator' methods.
- bool operator==(const Attribute &A) const {
- return pImpl == A.pImpl;
- }
- bool operator!=(const Attribute &A) const {
- return pImpl != A.pImpl;
- }
+ /// \brief Return true if the target-dependent attribute is present.
+ bool hasAttribute(StringRef Val) const;
- uint64_t getBitMask() const;
+ /// \brief Return the attribute's kind as an enum (Attribute::AttrKind). This
+ /// requires the attribute to be an enum or alignment attribute.
+ Attribute::AttrKind getKindAsEnum() const;
- /// \brief Which attributes cannot be applied to a type.
- static Attribute typeIncompatible(Type *Ty);
+ /// \brief Return the attribute's value as an integer. This requires that the
+ /// attribute be an alignment attribute.
+ uint64_t getValueAsInt() const;
- /// \brief This returns an integer containing an encoding of all the LLVM
- /// attributes found in the given attribute bitset. Any change to this
- /// encoding is a breaking change to bitcode compatibility.
- static uint64_t encodeLLVMAttributesForBitcode(Attribute Attrs);
+ /// \brief Return the attribute's kind as a string. This requires the
+ /// attribute to be a string attribute.
+ StringRef getKindAsString() const;
- /// \brief This returns an attribute bitset containing the LLVM attributes
- /// that have been decoded from the given integer. This function must stay in
- /// sync with 'encodeLLVMAttributesForBitcode'.
- static Attribute decodeLLVMAttributesForBitcode(LLVMContext &C,
- uint64_t EncodedAttrs);
+ /// \brief Return the attribute's value as a string. This requires the
+ /// attribute to be a string attribute.
+ StringRef getValueAsString() const;
+
+ /// \brief Returns the alignment field of an attribute as a byte alignment
+ /// value.
+ unsigned getAlignment() const;
+
+ /// \brief Returns the stack alignment field of an attribute as a byte
+ /// alignment value.
+ unsigned getStackAlignment() const;
/// \brief The Attribute is converted to a string of equivalent mnemonic. This
/// is, presumably, for writing out the mnemonics for the assembly writer.
- std::string getAsString() const;
-};
+ std::string getAsString(bool InAttrGrp = false) const;
-//===----------------------------------------------------------------------===//
-/// \class
-/// \brief Provide DenseMapInfo for Attribute::AttrKinds. This is used by
-/// AttrBuilder.
-template<> struct DenseMapInfo<Attribute::AttrKind> {
- static inline Attribute::AttrKind getEmptyKey() {
- return Attribute::AttrKindEmptyKey;
- }
- static inline Attribute::AttrKind getTombstoneKey() {
- return Attribute::AttrKindTombstoneKey;
- }
- static unsigned getHashValue(const Attribute::AttrKind &Val) {
- return Val * 37U;
- }
- static bool isEqual(const Attribute::AttrKind &LHS,
- const Attribute::AttrKind &RHS) {
- return LHS == RHS;
- }
-};
+ /// \brief Equality and non-equality operators.
+ bool operator==(Attribute A) const { return pImpl == A.pImpl; }
+ bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
-//===----------------------------------------------------------------------===//
-/// \class
-/// \brief This is just a pair of values to associate a set of attributes with
-/// an index.
-struct AttributeWithIndex {
- Attribute Attrs; ///< The attributes that are set, or'd together.
- Constant *Val; ///< Value attached to attribute, e.g. alignment.
- unsigned Index; ///< Index of the parameter for which the attributes apply.
- ///< Index 0 is used for return value attributes.
- ///< Index ~0U is used for function attributes.
-
- static AttributeWithIndex get(LLVMContext &C, unsigned Idx,
- ArrayRef<Attribute::AttrKind> Attrs) {
- return get(Idx, Attribute::get(C, Attrs));
- }
- static AttributeWithIndex get(unsigned Idx, Attribute Attrs) {
- AttributeWithIndex P;
- P.Index = Idx;
- P.Attrs = Attrs;
- P.Val = 0;
- return P;
- }
- static AttributeWithIndex get(unsigned Idx, Attribute Attrs, Constant *Val) {
- AttributeWithIndex P;
- P.Index = Idx;
- P.Attrs = Attrs;
- P.Val = Val;
- return P;
+ /// \brief Less-than operator. Useful for sorting the attributes list.
+ bool operator<(Attribute A) const;
+
+ void Profile(FoldingSetNodeID &ID) const {
+ ID.AddPointer(pImpl);
}
};
//===----------------------------------------------------------------------===//
-// AttributeSet Smart Pointer
-//===----------------------------------------------------------------------===//
-
-class AttrBuilder;
-class AttributeSetImpl;
-
-//===----------------------------------------------------------------------===//
/// \class
-/// \brief This class manages the ref count for the opaque AttributeSetImpl
-/// object and provides accessors for it.
+/// \brief This class holds the attributes for a function, its return value, and
+/// its parameters. You access the attributes for each of them via an index into
+/// the AttributeSet object. The function attributes are at index
+/// `AttributeSet::FunctionIndex', the return value is at index
+/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at
+/// index `1'.
class AttributeSet {
public:
enum AttrIndex {
@@ -233,105 +201,141 @@ public:
};
private:
friend class AttrBuilder;
+ friend class AttributeSetImpl;
+ template <typename Ty> friend struct DenseMapInfo;
- /// \brief The attributes that we are managing. This can be null to represent
+ /// \brief The attributes that we are managing. This can be null to represent
/// the empty attributes list.
- AttributeSetImpl *AttrList;
+ AttributeSetImpl *pImpl;
+
+ /// \brief The attributes for the specified index are returned.
+ AttributeSetNode *getAttributes(unsigned Idx) const;
- /// \brief The attributes for the specified index are returned. Attributes
- /// for the result are denoted with Idx = 0.
- Attribute getAttributes(unsigned Idx) const;
+ /// \brief Create an AttributeSet with the specified parameters in it.
+ static AttributeSet get(LLVMContext &C,
+ ArrayRef<std::pair<unsigned, Attribute> > Attrs);
+ static AttributeSet get(LLVMContext &C,
+ ArrayRef<std::pair<unsigned,
+ AttributeSetNode*> > Attrs);
- explicit AttributeSet(AttributeSetImpl *LI) : AttrList(LI) {}
+ static AttributeSet getImpl(LLVMContext &C,
+ ArrayRef<std::pair<unsigned,
+ AttributeSetNode*> > Attrs);
+
+
+ explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {}
public:
- AttributeSet() : AttrList(0) {}
- AttributeSet(const AttributeSet &P) : AttrList(P.AttrList) {}
- const AttributeSet &operator=(const AttributeSet &RHS);
+ AttributeSet() : pImpl(0) {}
+ AttributeSet(const AttributeSet &P) : pImpl(P.pImpl) {}
+ const AttributeSet &operator=(const AttributeSet &RHS) {
+ pImpl = RHS.pImpl;
+ return *this;
+ }
//===--------------------------------------------------------------------===//
- // Attribute List Construction and Mutation
+ // AttributeSet Construction and Mutation
//===--------------------------------------------------------------------===//
/// \brief Return an AttributeSet with the specified parameters in it.
- static AttributeSet get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
+ static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
+ static AttributeSet get(LLVMContext &C, unsigned Idx,
+ ArrayRef<Attribute::AttrKind> Kind);
static AttributeSet get(LLVMContext &C, unsigned Idx, AttrBuilder &B);
- /// \brief Add the specified attribute at the specified index to this
- /// attribute list. Since attribute lists are immutable, this returns the new
- /// list.
- AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+ /// \brief Add an attribute to the attribute set at the given index. Since
+ /// attribute sets are immutable, this returns a new set.
+ AttributeSet addAttribute(LLVMContext &C, unsigned Idx,
+ Attribute::AttrKind Attr) const;
+
+ /// \brief Add attributes to the attribute set at the given index. Since
+ /// attribute sets are immutable, this returns a new set.
+ AttributeSet addAttributes(LLVMContext &C, unsigned Idx,
+ AttributeSet Attrs) const;
/// \brief Remove the specified attribute at the specified index from this
- /// attribute list. Since attribute lists are immutable, this returns the new
+ /// attribute list. Since attribute lists are immutable, this returns the new
+ /// list.
+ AttributeSet removeAttribute(LLVMContext &C, unsigned Idx,
+ Attribute::AttrKind Attr) const;
+
+ /// \brief Remove the specified attributes at the specified index from this
+ /// attribute list. Since attribute lists are immutable, this returns the new
/// list.
- AttributeSet removeAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+ AttributeSet removeAttributes(LLVMContext &C, unsigned Idx,
+ AttributeSet Attrs) const;
//===--------------------------------------------------------------------===//
- // Attribute List Accessors
+ // AttributeSet Accessors
//===--------------------------------------------------------------------===//
+ /// \brief Retrieve the LLVM context.
+ LLVMContext &getContext() const;
+
/// \brief The attributes for the specified index are returned.
- Attribute getParamAttributes(unsigned Idx) const {
- return getAttributes(Idx);
- }
+ AttributeSet getParamAttributes(unsigned Idx) const;
/// \brief The attributes for the ret value are returned.
- Attribute getRetAttributes() const {
- return getAttributes(ReturnIndex);
- }
+ AttributeSet getRetAttributes() const;
/// \brief The function attributes are returned.
- Attribute getFnAttributes() const {
- return getAttributes(FunctionIndex);
- }
-
- /// \brief Return the alignment for the specified function parameter.
- unsigned getParamAlignment(unsigned Idx) const {
- return getAttributes(Idx).getAlignment();
- }
+ AttributeSet getFnAttributes() const;
/// \brief Return true if the attribute exists at the given index.
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+ /// \brief Return true if the attribute exists at the given index.
+ bool hasAttribute(unsigned Index, StringRef Kind) const;
+
/// \brief Return true if attribute exists at the given index.
bool hasAttributes(unsigned Index) const;
+ /// \brief Return true if the specified attribute is set for at least one
+ /// parameter or for the return value.
+ bool hasAttrSomewhere(Attribute::AttrKind Attr) const;
+
+ /// \brief Return the attribute object that exists at the given index.
+ Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+
+ /// \brief Return the attribute object that exists at the given index.
+ Attribute getAttribute(unsigned Index, StringRef Kind) const;
+
+ /// \brief Return the alignment for the specified function parameter.
+ unsigned getParamAlignment(unsigned Idx) const;
+
/// \brief Get the stack alignment.
unsigned getStackAlignment(unsigned Index) const;
/// \brief Return the attributes at the index as a string.
- std::string getAsString(unsigned Index) const;
+ std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
- uint64_t getBitMask(unsigned Index) const;
+ typedef ArrayRef<Attribute>::iterator iterator;
- /// \brief Return true if the specified attribute is set for at least one
- /// parameter or for the return value.
- bool hasAttrSomewhere(Attribute::AttrKind Attr) const;
+ iterator begin(unsigned Idx) const;
+ iterator end(unsigned Idx) const;
/// operator==/!= - Provide equality predicates.
bool operator==(const AttributeSet &RHS) const {
- return AttrList == RHS.AttrList;
+ return pImpl == RHS.pImpl;
}
bool operator!=(const AttributeSet &RHS) const {
- return AttrList != RHS.AttrList;
+ return pImpl != RHS.pImpl;
}
//===--------------------------------------------------------------------===//
- // Attribute List Introspection
+ // AttributeSet Introspection
//===--------------------------------------------------------------------===//
+ // FIXME: Remove this.
+ uint64_t Raw(unsigned Index) const;
+
/// \brief Return a raw pointer that uniquely identifies this attribute list.
void *getRawPointer() const {
- return AttrList;
+ return pImpl;
}
- // Attributes are stored as a dense set of slots, where there is one slot for
- // each argument that has an attribute. This allows walking over the dense
- // set instead of walking the sparse list of attributes.
-
/// \brief Return true if there are no attributes.
bool isEmpty() const {
- return AttrList == 0;
+ return getNumSlots() == 0;
}
/// \brief Return the number of slots used in this attribute list. This is
@@ -339,56 +343,101 @@ public:
/// function itself).
unsigned getNumSlots() const;
- /// \brief Return the AttributeWithIndex at the specified slot. This holds a
- /// index number plus a set of attributes.
- const AttributeWithIndex &getSlot(unsigned Slot) const;
+ /// \brief Return the index for the given slot.
+ uint64_t getSlotIndex(unsigned Slot) const;
+
+ /// \brief Return the attributes at the given slot.
+ AttributeSet getSlotAttributes(unsigned Slot) const;
void dump() const;
};
//===----------------------------------------------------------------------===//
/// \class
+/// \brief Provide DenseMapInfo for AttributeSet.
+template<> struct DenseMapInfo<AttributeSet> {
+ static inline AttributeSet getEmptyKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-1);
+ Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
+ return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+ }
+ static inline AttributeSet getTombstoneKey() {
+ uintptr_t Val = static_cast<uintptr_t>(-2);
+ Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
+ return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val));
+ }
+ static unsigned getHashValue(AttributeSet AS) {
+ return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
+ (unsigned((uintptr_t)AS.pImpl) >> 9);
+ }
+ static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
/// \brief This class is used in conjunction with the Attribute::get method to
/// create an Attribute object. The object itself is uniquified. The Builder's
/// value, however, is not. So this can be used as a quick way to test for
/// equality, presence of attributes, etc.
class AttrBuilder {
- DenseSet<Attribute::AttrKind> Attrs;
+ std::bitset<Attribute::EndAttrKinds> Attrs;
+ std::map<std::string, std::string> TargetDepAttrs;
uint64_t Alignment;
uint64_t StackAlignment;
public:
- AttrBuilder() : Alignment(0), StackAlignment(0) {}
- explicit AttrBuilder(uint64_t B) : Alignment(0), StackAlignment(0) {
- addRawValue(B);
+ AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {}
+ explicit AttrBuilder(uint64_t Val)
+ : Attrs(0), Alignment(0), StackAlignment(0) {
+ addRawValue(Val);
}
- AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) {
- addAttributes(A);
+ AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment(0) {
+ addAttribute(A);
}
AttrBuilder(AttributeSet AS, unsigned Idx);
+ AttrBuilder(const AttrBuilder &B)
+ : Attrs(B.Attrs),
+ TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()),
+ Alignment(B.Alignment), StackAlignment(B.StackAlignment) {}
void clear();
/// \brief Add an attribute to the builder.
AttrBuilder &addAttribute(Attribute::AttrKind Val);
+ /// \brief Add the Attribute object to the builder.
+ AttrBuilder &addAttribute(Attribute A);
+
+ /// \brief Add the target-dependent attribute to the builder.
+ AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
+
/// \brief Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attribute::AttrKind Val);
- /// \brief Add the attributes from A to the builder.
- AttrBuilder &addAttributes(const Attribute &A);
+ /// \brief Remove the attributes from the builder.
+ AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index);
- /// \brief Remove the attributes from A from the builder.
- AttrBuilder &removeAttributes(const Attribute &A);
+ /// \brief Remove the target-dependent attribute to the builder.
+ AttrBuilder &removeAttribute(StringRef A);
+
+ /// \brief Add the attributes from the builder.
+ AttrBuilder &merge(const AttrBuilder &B);
/// \brief Return true if the builder has the specified attribute.
- bool contains(Attribute::AttrKind A) const;
+ bool contains(Attribute::AttrKind A) const {
+ assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
+ return Attrs[A];
+ }
+
+ /// \brief Return true if the builder has the specified target-dependent
+ /// attribute.
+ bool contains(StringRef A) const;
/// \brief Return true if the builder has IR-level attributes.
bool hasAttributes() const;
/// \brief Return true if the builder has any attribute that's in the
/// specified attribute.
- bool hasAttributes(const Attribute &A) const;
+ bool hasAttributes(AttributeSet A, uint64_t Index) const;
/// \brief Return true if the builder has an alignment attribute.
bool hasAlignmentAttr() const;
@@ -407,52 +456,44 @@ public:
/// the form used internally in Attribute.
AttrBuilder &addStackAlignmentAttr(unsigned Align);
- typedef DenseSet<Attribute::AttrKind>::iterator iterator;
- typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator;
+ /// \brief Return true if the builder contains no target-independent
+ /// attributes.
+ bool empty() const { return Attrs.none(); }
- iterator begin() { return Attrs.begin(); }
- iterator end() { return Attrs.end(); }
+ // Iterators for target-dependent attributes.
+ typedef std::pair<std::string, std::string> td_type;
+ typedef std::map<std::string, std::string>::iterator td_iterator;
+ typedef std::map<std::string, std::string>::const_iterator td_const_iterator;
- const_iterator begin() const { return Attrs.begin(); }
- const_iterator end() const { return Attrs.end(); }
+ td_iterator td_begin() { return TargetDepAttrs.begin(); }
+ td_iterator td_end() { return TargetDepAttrs.end(); }
- /// \brief Add the raw value to the internal representation.
- ///
- /// N.B. This should be used ONLY for decoding LLVM bitcode!
- AttrBuilder &addRawValue(uint64_t Val);
+ td_const_iterator td_begin() const { return TargetDepAttrs.begin(); }
+ td_const_iterator td_end() const { return TargetDepAttrs.end(); }
- /// \brief Remove attributes that are used on functions only.
- void removeFunctionOnlyAttrs() {
- removeAttribute(Attribute::NoReturn)
- .removeAttribute(Attribute::NoUnwind)
- .removeAttribute(Attribute::ReadNone)
- .removeAttribute(Attribute::ReadOnly)
- .removeAttribute(Attribute::NoInline)
- .removeAttribute(Attribute::AlwaysInline)
- .removeAttribute(Attribute::OptimizeForSize)
- .removeAttribute(Attribute::StackProtect)
- .removeAttribute(Attribute::StackProtectReq)
- .removeAttribute(Attribute::NoRedZone)
- .removeAttribute(Attribute::NoImplicitFloat)
- .removeAttribute(Attribute::Naked)
- .removeAttribute(Attribute::InlineHint)
- .removeAttribute(Attribute::StackAlignment)
- .removeAttribute(Attribute::UWTable)
- .removeAttribute(Attribute::NonLazyBind)
- .removeAttribute(Attribute::ReturnsTwice)
- .removeAttribute(Attribute::AddressSafety)
- .removeAttribute(Attribute::MinSize)
- .removeAttribute(Attribute::NoDuplicate);
- }
+ bool td_empty() const { return TargetDepAttrs.empty(); }
- uint64_t getBitMask() const;
+ /// \brief Remove attributes that are used on functions only.
+ void removeFunctionOnlyAttrs();
bool operator==(const AttrBuilder &B);
bool operator!=(const AttrBuilder &B) {
return !(*this == B);
}
+
+ // FIXME: Remove this in 4.0.
+
+ /// \brief Add the raw value to the internal representation.
+ AttrBuilder &addRawValue(uint64_t Val);
};
+namespace AttributeFuncs {
+
+/// \brief Which attributes cannot be applied to a type.
+AttributeSet typeIncompatible(Type *Ty, uint64_t Index);
+
+} // end AttributeFuncs namespace
+
} // end llvm namespace
#endif
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 15f4aa7..ea5695a 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_BASICBLOCK_H
-#define LLVM_BASICBLOCK_H
+#ifndef LLVM_IR_BASICBLOCK_H
+#define LLVM_IR_BASICBLOCK_H
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist.h"
@@ -29,19 +29,19 @@ class BlockAddress;
template<> struct ilist_traits<Instruction>
: public SymbolTableListTraits<Instruction, BasicBlock> {
- // createSentinel is used to get hold of a node that marks the end of
- // the list...
- // The sentinel is relative to this instance, so we use a non-static
- // method.
+
+ /// \brief Return a node that marks the end of a list.
+ ///
+ /// The sentinel is relative to this instance, so we use a non-static
+ /// method.
Instruction *createSentinel() const {
- // since i(p)lists always publicly derive from the corresponding
- // traits, placing a data member in this class will augment i(p)list.
- // But since the NodeTy is expected to publicly derive from
- // ilist_node<NodeTy>, there is a legal viable downcast from it
- // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
- // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
- // forbidden (save the ilist_node<NodeTy>) so no one will ever notice
- // the superposition.
+ // Since i(p)lists always publicly derive from their corresponding traits,
+ // placing a data member in this class will augment the i(p)list. But since
+ // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+ // there is a legal viable downcast from it to NodeTy. We use this trick to
+ // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+ // sentinel. Dereferencing the sentinel is forbidden (save the
+ // ilist_node<NodeTy>), so no one will ever notice the superposition.
return static_cast<Instruction*>(&Sentinel);
}
static void destroySentinel(Instruction*) {}
@@ -53,6 +53,8 @@ private:
mutable ilist_half_node<Instruction> Sentinel;
};
+/// \brief LLVM Basic Block Representation
+///
/// This represents a single basic block in LLVM. A basic block is simply a
/// container of instructions that execute sequentially. Basic blocks are Values
/// because they are referenced by instructions such as branches and switch
@@ -66,7 +68,6 @@ private:
/// occur because it may be useful in the intermediate stage of constructing or
/// modifying a program. However, the verifier will ensure that basic blocks
/// are "well formed".
-/// @brief LLVM Basic Block Representation
class BasicBlock : public Value, // Basic blocks are data objects also
public ilist_node<BasicBlock> {
friend class BlockAddress;
@@ -82,14 +83,15 @@ private:
BasicBlock(const BasicBlock &) LLVM_DELETED_FUNCTION;
void operator=(const BasicBlock &) LLVM_DELETED_FUNCTION;
- /// BasicBlock ctor - If the function parameter is specified, the basic block
- /// is automatically inserted at either the end of the function (if
- /// InsertBefore is null), or before the specified basic block.
+ /// \brief Constructor.
///
+ /// If the function parameter is specified, the basic block is automatically
+ /// inserted at either the end of the function (if InsertBefore is null), or
+ /// before the specified basic block.
explicit BasicBlock(LLVMContext &C, const Twine &Name = "",
Function *Parent = 0, BasicBlock *InsertBefore = 0);
public:
- /// getContext - Get the context in which this basic block lives.
+ /// \brief Get the context in which this basic block lives.
LLVMContext &getContext() const;
/// Instruction iterators...
@@ -98,88 +100,87 @@ public:
typedef InstListType::reverse_iterator reverse_iterator;
typedef InstListType::const_reverse_iterator const_reverse_iterator;
- /// Create - Creates a new BasicBlock. If the Parent parameter is specified,
- /// the basic block is automatically inserted at either the end of the
- /// function (if InsertBefore is 0), or before the specified basic block.
+ /// \brief Creates a new BasicBlock.
+ ///
+ /// If the Parent parameter is specified, the basic block is automatically
+ /// inserted at either the end of the function (if InsertBefore is 0), or
+ /// before the specified basic block.
static BasicBlock *Create(LLVMContext &Context, const Twine &Name = "",
Function *Parent = 0,BasicBlock *InsertBefore = 0) {
return new BasicBlock(Context, Name, Parent, InsertBefore);
}
~BasicBlock();
- /// getParent - Return the enclosing method, or null if none
- ///
+ /// \brief Return the enclosing method, or null if none.
const Function *getParent() const { return Parent; }
Function *getParent() { return Parent; }
- /// getTerminator() - If this is a well formed basic block, then this returns
- /// a pointer to the terminator instruction. If it is not, then you get a
- /// null pointer back.
- ///
+ /// \brief Returns the terminator instruction if the block is well formed or
+ /// null if the block is not well formed.
TerminatorInst *getTerminator();
const TerminatorInst *getTerminator() const;
- /// Returns a pointer to the first instructon in this block that is not a
- /// PHINode instruction. When adding instruction to the beginning of the
- /// basic block, they should be added before the returned value, not before
- /// the first instruction, which might be PHI.
- /// Returns 0 is there's no non-PHI instruction.
+ /// \brief Returns a pointer to the first instruction in this block that is
+ /// not a PHINode instruction.
+ ///
+ /// When adding instructions to the beginning of the basic block, they should
+ /// be added before the returned value, not before the first instruction,
+ /// which might be PHI. Returns 0 is there's no non-PHI instruction.
Instruction* getFirstNonPHI();
const Instruction* getFirstNonPHI() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHI();
}
- // Same as above, but also skip debug intrinsics.
+ /// \brief Returns a pointer to the first instruction in this block that is not
+ /// a PHINode or a debug intrinsic.
Instruction* getFirstNonPHIOrDbg();
const Instruction* getFirstNonPHIOrDbg() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbg();
}
- // Same as above, but also skip lifetime intrinsics.
+ /// \brief Returns a pointer to the first instruction in this block that is not
+ /// a PHINode, a debug intrinsic, or a lifetime intrinsic.
Instruction* getFirstNonPHIOrDbgOrLifetime();
const Instruction* getFirstNonPHIOrDbgOrLifetime() const {
return const_cast<BasicBlock*>(this)->getFirstNonPHIOrDbgOrLifetime();
}
- /// getFirstInsertionPt - Returns an iterator to the first instruction in this
- /// block that is suitable for inserting a non-PHI instruction. In particular,
- /// it skips all PHIs and LandingPad instructions.
+ /// \brief Returns an iterator to the first instruction in this block that is
+ /// suitable for inserting a non-PHI instruction.
+ ///
+ /// In particular, it skips all PHIs and LandingPad instructions.
iterator getFirstInsertionPt();
const_iterator getFirstInsertionPt() const {
return const_cast<BasicBlock*>(this)->getFirstInsertionPt();
}
- /// removeFromParent - This method unlinks 'this' from the containing
- /// function, but does not delete it.
- ///
+ /// \brief Unlink 'this' from the containing function, but do not delete it.
void removeFromParent();
- /// eraseFromParent - This method unlinks 'this' from the containing function
- /// and deletes it.
- ///
+ /// \brief Unlink 'this' from the containing function and delete it.
void eraseFromParent();
- /// moveBefore - Unlink this basic block from its current function and
- /// insert it into the function that MovePos lives in, right before MovePos.
+ /// \brief Unlink this basic block from its current function and insert it
+ /// into the function that \p MovePos lives in, right before \p MovePos.
void moveBefore(BasicBlock *MovePos);
- /// moveAfter - Unlink this basic block from its current function and
- /// insert it into the function that MovePos lives in, right after MovePos.
+ /// \brief Unlink this basic block from its current function and insert it
+ /// right after \p MovePos in the function \p MovePos lives in.
void moveAfter(BasicBlock *MovePos);
- /// getSinglePredecessor - If this basic block has a single predecessor block,
- /// return the block, otherwise return a null pointer.
+ /// \brief Return this block if it has a single predecessor block. Otherwise
+ /// return a null pointer.
BasicBlock *getSinglePredecessor();
const BasicBlock *getSinglePredecessor() const {
return const_cast<BasicBlock*>(this)->getSinglePredecessor();
}
- /// getUniquePredecessor - If this basic block has a unique predecessor block,
- /// return the block, otherwise return a null pointer.
+ /// \brief Return this block if it has a unique predecessor block. Otherwise return a null pointer.
+ ///
/// Note that unique predecessor doesn't mean single edge, there can be
- /// multiple edges from the unique predecessor to this block (for example
- /// a switch statement with multiple cases having the same destination).
+ /// multiple edges from the unique predecessor to this block (for example a
+ /// switch statement with multiple cases having the same destination).
BasicBlock *getUniquePredecessor();
const BasicBlock *getUniquePredecessor() const {
return const_cast<BasicBlock*>(this)->getUniquePredecessor();
@@ -205,49 +206,52 @@ public:
inline const Instruction &back() const { return InstList.back(); }
inline Instruction &back() { return InstList.back(); }
- /// getInstList() - Return the underlying instruction list container. You
- /// need to access it directly if you want to modify it currently.
+ /// \brief Return the underlying instruction list container.
///
+ /// Currently you need to access the underlying instruction list container
+ /// directly if you want to modify it.
const InstListType &getInstList() const { return InstList; }
InstListType &getInstList() { return InstList; }
- /// getSublistAccess() - returns pointer to member of instruction list
+ /// \brief Returns a pointer to a member of the instruction list.
static iplist<Instruction> BasicBlock::*getSublistAccess(Instruction*) {
return &BasicBlock::InstList;
}
- /// getValueSymbolTable() - returns pointer to symbol table (if any)
+ /// \brief Returns a pointer to the symbol table if one exists.
ValueSymbolTable *getValueSymbolTable();
- /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ /// \brief Methods for support type inquiry through isa, cast, and dyn_cast.
static inline bool classof(const Value *V) {
return V->getValueID() == Value::BasicBlockVal;
}
- /// dropAllReferences() - This function causes all the subinstructions to "let
- /// go" of all references that they are maintaining. This allows one to
- /// 'delete' a whole class at a time, even though there may be circular
- /// references... first all references are dropped, and all use counts go to
- /// zero. Then everything is delete'd for real. Note that no operations are
- /// valid on an object that has "dropped all references", except operator
- /// delete.
+ /// \brief Cause all subinstructions to "let go" of all the references that
+ /// said subinstructions are maintaining.
///
+ /// This allows one to 'delete' a whole class at a time, even though there may
+ /// be circular references... first all references are dropped, and all use
+ /// counts go to zero. Then everything is delete'd for real. Note that no
+ /// operations are valid on an object that has "dropped all references",
+ /// except operator delete.
void dropAllReferences();
- /// removePredecessor - This method is used to notify a BasicBlock that the
- /// specified Predecessor of the block is no longer able to reach it. This is
- /// actually not used to update the Predecessor list, but is actually used to
- /// update the PHI nodes that reside in the block. Note that this should be
- /// called while the predecessor still refers to this block.
+ /// \brief Notify the BasicBlock that the predecessor \p Pred is no longer
+ /// able to reach it.
///
+ /// This is actually not used to update the Predecessor list, but is actually
+ /// used to update the PHI nodes that reside in the block. Note that this
+ /// should be called while the predecessor still refers to this block.
void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false);
- /// splitBasicBlock - This splits a basic block into two at the specified
- /// instruction. Note that all instructions BEFORE the specified iterator
- /// stay as part of the original basic block, an unconditional branch is added
- /// to the original BB, and the rest of the instructions in the BB are moved
- /// to the new BB, including the old terminator. The newly formed BasicBlock
- /// is returned. This function invalidates the specified iterator.
+ /// \brief Split the basic block into two basic blocks at the specified
+ /// instruction.
+ ///
+ /// Note that all instructions BEFORE the specified iterator stay as part of
+ /// the original basic block, an unconditional branch is added to the original
+ /// BB, and the rest of the instructions in the BB are moved to the new BB,
+ /// including the old terminator. The newly formed BasicBlock is returned.
+ /// This function invalidates the specified iterator.
///
/// Note that this only works on well formed basic blocks (must have a
/// terminator), and 'I' must not be the end of instruction list (which would
@@ -256,37 +260,39 @@ public:
///
/// Also note that this doesn't preserve any passes. To split blocks while
/// keeping loop information consistent, use the SplitBlock utility function.
- ///
BasicBlock *splitBasicBlock(iterator I, const Twine &BBName = "");
- /// hasAddressTaken - returns true if there are any uses of this basic block
- /// other than direct branches, switches, etc. to it.
+ /// \brief Returns true if there are any uses of this basic block other than
+ /// direct branches, switches, etc. to it.
bool hasAddressTaken() const { return getSubclassDataFromValue() != 0; }
- /// replaceSuccessorsPhiUsesWith - Update all phi nodes in all our successors
- /// to refer to basic block New instead of to us.
+ /// \brief Update all phi nodes in this basic block's successors to refer to
+ /// basic block \p New instead of to it.
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
- /// isLandingPad - Return true if this basic block is a landing pad. I.e.,
- /// it's the destination of the 'unwind' edge of an invoke instruction.
+ /// \brief Return true if this basic block is a landing pad.
+ ///
+ /// Being a ``landing pad'' means that the basic block is the destination of
+ /// the 'unwind' edge of an invoke instruction.
bool isLandingPad() const;
- /// getLandingPadInst() - Return the landingpad instruction associated with
- /// the landing pad.
+ /// \brief Return the landingpad instruction associated with the landing pad.
LandingPadInst *getLandingPadInst();
const LandingPadInst *getLandingPadInst() const;
private:
- /// AdjustBlockAddressRefCount - BasicBlock stores the number of BlockAddress
- /// objects using it. This is almost always 0, sometimes one, possibly but
- /// almost never 2, and inconceivably 3 or more.
+ /// \brief Increment the internal refcount of the number of BlockAddresses
+ /// referencing this BasicBlock by \p Amt.
+ ///
+ /// This is almost always 0, sometimes one possibly, but almost never 2, and
+ /// inconceivably 3 or more.
void AdjustBlockAddressRefCount(int Amt) {
setValueSubclassData(getSubclassDataFromValue()+Amt);
assert((int)(signed char)getSubclassDataFromValue() >= 0 &&
"Refcount wrap-around");
}
- // Shadow Value::setValueSubclassData with a private forwarding method so that
- // any future subclasses cannot accidentally use it.
+ /// \brief Shadow Value::setValueSubclassData with a private forwarding method
+ /// so that any future subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) {
Value::setValueSubclassData(D);
}
diff --git a/include/llvm/IR/CallingConv.h b/include/llvm/IR/CallingConv.h
index 699cea3..6f3ab20 100644
--- a/include/llvm/IR/CallingConv.h
+++ b/include/llvm/IR/CallingConv.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CALLINGCONV_H
-#define LLVM_CALLINGCONV_H
+#ifndef LLVM_IR_CALLINGCONV_H
+#define LLVM_IR_CALLINGCONV_H
namespace llvm {
diff --git a/include/llvm/IR/Constant.h b/include/llvm/IR/Constant.h
index 36a4538..26bad1d 100644
--- a/include/llvm/IR/Constant.h
+++ b/include/llvm/IR/Constant.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CONSTANT_H
-#define LLVM_CONSTANT_H
+#ifndef LLVM_IR_CONSTANT_H
+#define LLVM_IR_CONSTANT_H
#include "llvm/IR/User.h"
@@ -61,6 +61,9 @@ public:
/// by getZeroValueForNegation.
bool isNegativeZeroValue() const;
+ /// Return true if the value is negative zero or null value.
+ bool isZeroValue() const;
+
/// canTrap - Return true if evaluation of this constant could trap. This is
/// true for things like constant expressions that could divide by zero.
bool canTrap() const;
diff --git a/include/llvm/IR/Constants.h b/include/llvm/IR/Constants.h
index 0f49fe5..ad258f9 100644
--- a/include/llvm/IR/Constants.h
+++ b/include/llvm/IR/Constants.h
@@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_CONSTANTS_H
-#define LLVM_CONSTANTS_H
+#ifndef LLVM_IR_CONSTANTS_H
+#define LLVM_IR_CONSTANTS_H
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index cc02017..bfdb057 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DATALAYOUT_H
-#define LLVM_DATALAYOUT_H
+#ifndef LLVM_IR_DATALAYOUT_H
+#define LLVM_IR_DATALAYOUT_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
@@ -100,7 +100,7 @@ private:
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
- /// Alignments- Where the primitive type alignment data is stored.
+ /// Alignments - Where the primitive type alignment data is stored.
///
/// @sa init().
/// @note Could support multiple size pointer alignments, e.g., 32-bit
@@ -324,19 +324,16 @@ public:
/// an integer type of the specified bitwidth.
unsigned getABIIntegerTypeAlignment(unsigned BitWidth) const;
-
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
/// for the specified type when it is part of a call frame.
unsigned getCallFrameTypeAlignment(Type *Ty) const;
-
/// getPrefTypeAlignment - Return the preferred stack/global alignment for
/// the specified type. This is always at least as good as the ABI alignment.
unsigned getPrefTypeAlignment(Type *Ty) const;
/// getPreferredTypeAlignmentShift - Return the preferred alignment for the
/// specified type, returned as log2 of the value (a shift amount).
- ///
unsigned getPreferredTypeAlignmentShift(Type *Ty) const;
/// getIntPtrType - Return an integer type with size at least as big as that
@@ -350,7 +347,6 @@ public:
/// getIndexedOffset - return the offset from the beginning of the type for
/// the specified indices. This is used to implement getelementptr.
- ///
uint64_t getIndexedOffset(Type *Ty, ArrayRef<Value *> Indices) const;
/// getStructLayout - Return a StructLayout object, indicating the alignment
diff --git a/include/llvm/IR/DerivedTypes.h b/include/llvm/IR/DerivedTypes.h
index 5a941520..3bf7885 100644
--- a/include/llvm/IR/DerivedTypes.h
+++ b/include/llvm/IR/DerivedTypes.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DERIVED_TYPES_H
-#define LLVM_DERIVED_TYPES_H
+#ifndef LLVM_IR_DERIVEDTYPES_H
+#define LLVM_IR_DERIVEDTYPES_H
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/IR/Function.h b/include/llvm/IR/Function.h
index 1762b2c..568b55c 100644
--- a/include/llvm/IR/Function.h
+++ b/include/llvm/IR/Function.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_FUNCTION_H
-#define LLVM_FUNCTION_H
+#ifndef LLVM_IR_FUNCTION_H
+#define LLVM_IR_FUNCTION_H
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
@@ -85,7 +85,7 @@ private:
BasicBlockListType BasicBlocks; ///< The basic blocks
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
- AttributeSet AttributeList; ///< Parameter attributes
+ AttributeSet AttributeSets; ///< Parameter attributes
// HasLazyArguments is stored in Value::SubclassData.
/*bool HasLazyArguments;*/
@@ -162,24 +162,25 @@ public:
/// getAttributes - Return the attribute list for this Function.
///
- const AttributeSet &getAttributes() const { return AttributeList; }
+ AttributeSet getAttributes() const { return AttributeSets; }
/// setAttributes - Set the attribute list for this Function.
///
- void setAttributes(const AttributeSet &attrs) { AttributeList = attrs; }
+ void setAttributes(AttributeSet attrs) { AttributeSets = attrs; }
/// addFnAttr - Add function attributes to this function.
///
void addFnAttr(Attribute::AttrKind N) {
- // Function Attribute are stored at ~0 index
- addAttribute(AttributeSet::FunctionIndex, Attribute::get(getContext(), N));
+ setAttributes(AttributeSets.addAttribute(getContext(),
+ AttributeSet::FunctionIndex, N));
}
- /// removeFnAttr - Remove function attributes from this function.
- ///
- void removeFnAttr(Attribute N) {
- // Function Attribute are stored at ~0 index
- removeAttribute(~0U, N);
+ /// \brief Return true if the function has the attribute.
+ bool hasFnAttribute(Attribute::AttrKind Kind) const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
+ }
+ bool hasFnAttribute(StringRef Kind) const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex, Kind);
}
/// hasGC/getGC/setGC/clearGC - The name of the garbage collection algorithm
@@ -189,20 +190,23 @@ public:
void setGC(const char *Str);
void clearGC();
- /// addAttribute - adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attribute attr);
+ /// @brief adds the attribute to the list of attributes.
+ void addAttribute(unsigned i, Attribute::AttrKind attr);
+
+ /// @brief adds the attributes to the list of attributes.
+ void addAttributes(unsigned i, AttributeSet attrs);
- /// removeAttribute - removes the attribute from the list of attributes.
- void removeAttribute(unsigned i, Attribute attr);
+ /// @brief removes the attributes from the list of attributes.
+ void removeAttributes(unsigned i, AttributeSet attr);
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
- return AttributeList.getParamAlignment(i);
+ return AttributeSets.getParamAlignment(i);
}
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::ReadNone);
}
void setDoesNotAccessMemory() {
@@ -212,7 +216,7 @@ public:
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
return doesNotAccessMemory() ||
- AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::ReadOnly);
}
void setOnlyReadsMemory() {
@@ -221,7 +225,7 @@ public:
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoReturn);
}
void setDoesNotReturn() {
@@ -230,7 +234,7 @@ public:
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoUnwind);
}
void setDoesNotThrow() {
@@ -239,7 +243,7 @@ public:
/// @brief Determine if the call cannot be duplicated.
bool cannotDuplicate() const {
- return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::NoDuplicate);
}
void setCannotDuplicate() {
@@ -249,7 +253,7 @@ public:
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
- return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
Attribute::UWTable);
}
void setHasUWTable() {
@@ -264,25 +268,25 @@ public:
/// @brief Determine if the function returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
- return AttributeList.hasAttribute(1, Attribute::StructRet);
+ return AttributeSets.hasAttribute(1, Attribute::StructRet);
}
/// @brief Determine if the parameter does not alias other parameters.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
- return AttributeList.hasAttribute(n, Attribute::NoAlias);
+ return AttributeSets.hasAttribute(n, Attribute::NoAlias);
}
void setDoesNotAlias(unsigned n) {
- addAttribute(n, Attribute::get(getContext(), Attribute::NoAlias));
+ addAttribute(n, Attribute::NoAlias);
}
/// @brief Determine if the parameter can be captured.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotCapture(unsigned n) const {
- return AttributeList.hasAttribute(n, Attribute::NoCapture);
+ return AttributeSets.hasAttribute(n, Attribute::NoCapture);
}
void setDoesNotCapture(unsigned n) {
- addAttribute(n, Attribute::get(getContext(), Attribute::NoCapture));
+ addAttribute(n, Attribute::NoCapture);
}
/// copyAttributesFrom - copy all additional attributes (those not needed to
diff --git a/include/llvm/IR/GlobalAlias.h b/include/llvm/IR/GlobalAlias.h
index 03c1648..883814a 100644
--- a/include/llvm/IR/GlobalAlias.h
+++ b/include/llvm/IR/GlobalAlias.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GLOBAL_ALIAS_H
-#define LLVM_GLOBAL_ALIAS_H
+#ifndef LLVM_IR_GLOBALALIAS_H
+#define LLVM_IR_GLOBALALIAS_H
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index 246e00b..f398bc1 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GLOBALVALUE_H
-#define LLVM_GLOBALVALUE_H
+#ifndef LLVM_IR_GLOBALVALUE_H
+#define LLVM_IR_GLOBALVALUE_H
#include "llvm/IR/Constant.h"
diff --git a/include/llvm/IR/GlobalVariable.h b/include/llvm/IR/GlobalVariable.h
index 5c42d76..bfed507 100644
--- a/include/llvm/IR/GlobalVariable.h
+++ b/include/llvm/IR/GlobalVariable.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GLOBAL_VARIABLE_H
-#define LLVM_GLOBAL_VARIABLE_H
+#ifndef LLVM_IR_GLOBALVARIABLE_H
+#define LLVM_IR_GLOBALVARIABLE_H
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/ilist_node.h"
@@ -40,9 +40,14 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
void setParent(Module *parent);
- bool isConstantGlobal : 1; // Is this a global constant?
- unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
- // if so, what is the desired model?
+ bool isConstantGlobal : 1; // Is this a global constant?
+ unsigned threadLocalMode : 3; // Is this symbol "Thread Local",
+ // if so, what is the desired
+ // model?
+ bool isExternallyInitializedConstant : 1; // Is this a global whose value
+ // can change from its initial
+ // value before global
+ // initializers are run?
public:
// allocate space for exactly one operand
@@ -62,15 +67,15 @@ public:
/// automatically inserted into the end of the specified modules global list.
GlobalVariable(Type *Ty, bool isConstant, LinkageTypes Linkage,
Constant *Initializer = 0, const Twine &Name = "",
- ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0);
+ ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+ bool isExternallyInitialized = false);
/// GlobalVariable ctor - This creates a global and inserts it before the
/// specified other global.
GlobalVariable(Module &M, Type *Ty, bool isConstant,
LinkageTypes Linkage, Constant *Initializer,
- const Twine &Name = "",
- GlobalVariable *InsertBefore = 0,
- ThreadLocalMode = NotThreadLocal,
- unsigned AddressSpace = 0);
+ const Twine &Name = "", GlobalVariable *InsertBefore = 0,
+ ThreadLocalMode = NotThreadLocal, unsigned AddressSpace = 0,
+ bool isExternallyInitialized = false);
~GlobalVariable() {
NumOperands = 1; // FIXME: needed by operator delete
@@ -105,7 +110,10 @@ public:
return hasInitializer() &&
// The initializer of a global variable with weak linkage may change at
// link time.
- !mayBeOverridden();
+ !mayBeOverridden() &&
+ // The initializer of a global variable with the externally_initialized
+ // marker may change at runtime before C++ initializers are evaluated.
+ !isExternallyInitialized();
}
/// hasUniqueInitializer - Whether the global variable has an initializer, and
@@ -118,7 +126,11 @@ public:
// instead. It is wrong to modify the initializer of a global variable
// with *_odr linkage because then different instances of the global may
// have different initializers, breaking the One Definition Rule.
- !isWeakForLinker();
+ !isWeakForLinker() &&
+ // It is not safe to modify initializers of global variables with the
+ // external_initializer marker since the value may be changed at runtime
+ // before C++ initializers are evaluated.
+ !isExternallyInitialized();
}
/// getInitializer - Return the initializer for this global variable. It is
@@ -155,6 +167,13 @@ public:
return static_cast<ThreadLocalMode>(threadLocalMode);
}
+ bool isExternallyInitialized() const {
+ return isExternallyInitializedConstant;
+ }
+ void setExternallyInitialized(bool Val) {
+ isExternallyInitializedConstant = Val;
+ }
+
/// copyAttributesFrom - copy all additional attributes (those not needed to
/// create a GlobalVariable) from the GlobalVariable Src to this one.
void copyAttributesFrom(const GlobalValue *Src);
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 27f990e..1c71d0a 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_IRBUILDER_H
-#define LLVM_IRBUILDER_H
+#ifndef LLVM_IR_IRBUILDER_H
+#define LLVM_IR_IRBUILDER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
@@ -28,10 +28,11 @@
namespace llvm {
class MDNode;
-/// IRBuilderDefaultInserter - This provides the default implementation of the
-/// IRBuilder 'InsertHelper' method that is called whenever an instruction is
-/// created by IRBuilder and needs to be inserted. By default, this inserts the
-/// instruction at the insertion point.
+/// \brief This provides the default implementation of the IRBuilder
+/// 'InsertHelper' method that is called whenever an instruction is created by
+/// IRBuilder and needs to be inserted.
+///
+/// By default, this inserts the instruction at the insertion point.
template <bool preserveNames = true>
class IRBuilderDefaultInserter {
protected:
@@ -43,7 +44,7 @@ protected:
}
};
-/// IRBuilderBase - Common base class shared among various IRBuilders.
+/// \brief Common base class shared among various IRBuilders.
class IRBuilderBase {
DebugLoc CurDbgLocation;
protected:
@@ -61,8 +62,8 @@ public:
// Builder configuration methods
//===--------------------------------------------------------------------===//
- /// ClearInsertionPoint - Clear the insertion point: created instructions will
- /// not be inserted into a block.
+ /// \brief Clear the insertion point: created instructions will not be
+ /// inserted into a block.
void ClearInsertionPoint() {
BB = 0;
}
@@ -71,30 +72,30 @@ public:
BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
LLVMContext &getContext() const { return Context; }
- /// SetInsertPoint - This specifies that created instructions should be
- /// appended to the end of the specified block.
+ /// \brief This specifies that created instructions should be appended to the
+ /// end of the specified block.
void SetInsertPoint(BasicBlock *TheBB) {
BB = TheBB;
InsertPt = BB->end();
}
- /// SetInsertPoint - This specifies that created instructions should be
- /// inserted before the specified instruction.
+ /// \brief This specifies that created instructions should be inserted before
+ /// the specified instruction.
void SetInsertPoint(Instruction *I) {
BB = I->getParent();
InsertPt = I;
SetCurrentDebugLocation(I->getDebugLoc());
}
- /// SetInsertPoint - This specifies that created instructions should be
- /// inserted at the specified point.
+ /// \brief This specifies that created instructions should be inserted at the
+ /// specified point.
void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
BB = TheBB;
InsertPt = IP;
}
- /// SetInsertPoint(Use) - Find the nearest point that dominates this use, and
- /// specify that created instructions should be inserted at this point.
+ /// \brief 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)) {
@@ -106,25 +107,23 @@ public:
SetInsertPoint(UseInst);
}
- /// SetCurrentDebugLocation - Set location information used by debugging
- /// information.
+ /// \brief Set location information used by debugging information.
void SetCurrentDebugLocation(const DebugLoc &L) {
CurDbgLocation = L;
}
- /// getCurrentDebugLocation - Get location information used by debugging
- /// information.
+ /// \brief Get location information used by debugging information.
DebugLoc getCurrentDebugLocation() const { return CurDbgLocation; }
- /// SetInstDebugLocation - If this builder has a current debug location, set
- /// it on the specified instruction.
+ /// \brief If this builder has a current debug location, set it on the
+ /// specified instruction.
void SetInstDebugLocation(Instruction *I) const {
if (!CurDbgLocation.isUnknown())
I->setDebugLoc(CurDbgLocation);
}
- /// getCurrentFunctionReturnType - Get the return type of the current function
- /// that we're emitting into.
+ /// \brief Get the return type of the current function that we're emitting
+ /// into.
Type *getCurrentFunctionReturnType() const;
/// InsertPoint - A saved insertion point.
@@ -133,35 +132,33 @@ public:
BasicBlock::iterator Point;
public:
- /// Creates a new insertion point which doesn't point to anything.
+ /// \brief Creates a new insertion point which doesn't point to anything.
InsertPoint() : Block(0) {}
- /// Creates a new insertion point at the given location.
+ /// \brief Creates a new insertion point at the given location.
InsertPoint(BasicBlock *InsertBlock, BasicBlock::iterator InsertPoint)
: Block(InsertBlock), Point(InsertPoint) {}
- /// isSet - Returns true if this insert point is set.
+ /// \brief Returns true if this insert point is set.
bool isSet() const { return (Block != 0); }
llvm::BasicBlock *getBlock() const { return Block; }
llvm::BasicBlock::iterator getPoint() const { return Point; }
};
- /// saveIP - Returns the current insert point.
+ /// \brief Returns the current insert point.
InsertPoint saveIP() const {
return InsertPoint(GetInsertBlock(), GetInsertPoint());
}
- /// saveAndClearIP - Returns the current insert point, clearing it
- /// in the process.
+ /// \brief Returns the current insert point, clearing it in the process.
InsertPoint saveAndClearIP() {
InsertPoint IP(GetInsertBlock(), GetInsertPoint());
ClearInsertionPoint();
return IP;
}
- /// restoreIP - Sets the current insert point to a previously-saved
- /// location.
+ /// \brief Sets the current insert point to a previously-saved location.
void restoreIP(InsertPoint IP) {
if (IP.isSet())
SetInsertPoint(IP.getBlock(), IP.getPoint());
@@ -173,49 +170,50 @@ public:
// Miscellaneous creation methods.
//===--------------------------------------------------------------------===//
- /// CreateGlobalString - Make a new global variable with an initializer that
- /// has array of i8 type filled in with the nul terminated string value
- /// specified. The new global variable will be marked mergable with any
- /// others of the same contents. If Name is specified, it is the name of the
- /// global variable created.
+ /// \brief Make a new global variable with initializer type i8*
+ ///
+ /// Make a new global variable with an initializer that has array of i8 type
+ /// filled in with the null terminated string value specified. The new global
+ /// variable will be marked mergable with any others of the same contents. If
+ /// Name is specified, it is the name of the global variable created.
Value *CreateGlobalString(StringRef Str, const Twine &Name = "");
- /// getInt1 - Get a constant value representing either true or false.
+ /// \brief Get a constant value representing either true or false.
ConstantInt *getInt1(bool V) {
return ConstantInt::get(getInt1Ty(), V);
}
- /// getTrue - Get the constant value for i1 true.
+ /// \brief Get the constant value for i1 true.
ConstantInt *getTrue() {
return ConstantInt::getTrue(Context);
}
- /// getFalse - Get the constant value for i1 false.
+ /// \brief Get the constant value for i1 false.
ConstantInt *getFalse() {
return ConstantInt::getFalse(Context);
}
- /// getInt8 - Get a constant 8-bit value.
+ /// \brief Get a constant 8-bit value.
ConstantInt *getInt8(uint8_t C) {
return ConstantInt::get(getInt8Ty(), C);
}
- /// getInt16 - Get a constant 16-bit value.
+ /// \brief Get a constant 16-bit value.
ConstantInt *getInt16(uint16_t C) {
return ConstantInt::get(getInt16Ty(), C);
}
- /// getInt32 - Get a constant 32-bit value.
+ /// \brief Get a constant 32-bit value.
ConstantInt *getInt32(uint32_t C) {
return ConstantInt::get(getInt32Ty(), C);
}
- /// getInt64 - Get a constant 64-bit value.
+ /// \brief Get a constant 64-bit value.
ConstantInt *getInt64(uint64_t C) {
return ConstantInt::get(getInt64Ty(), C);
}
- /// getInt - Get a constant integer value.
+ /// \brief Get a constant integer value.
ConstantInt *getInt(const APInt &AI) {
return ConstantInt::get(Context, AI);
}
@@ -224,50 +222,52 @@ public:
// Type creation methods
//===--------------------------------------------------------------------===//
- /// getInt1Ty - Fetch the type representing a single bit
+ /// \brief Fetch the type representing a single bit
IntegerType *getInt1Ty() {
return Type::getInt1Ty(Context);
}
- /// getInt8Ty - Fetch the type representing an 8-bit integer.
+ /// \brief Fetch the type representing an 8-bit integer.
IntegerType *getInt8Ty() {
return Type::getInt8Ty(Context);
}
- /// getInt16Ty - Fetch the type representing a 16-bit integer.
+ /// \brief Fetch the type representing a 16-bit integer.
IntegerType *getInt16Ty() {
return Type::getInt16Ty(Context);
}
- /// getInt32Ty - Fetch the type representing a 32-bit integer.
+ /// \brief Fetch the type representing a 32-bit integer.
IntegerType *getInt32Ty() {
return Type::getInt32Ty(Context);
}
- /// getInt64Ty - Fetch the type representing a 64-bit integer.
+ /// \brief Fetch the type representing a 64-bit integer.
IntegerType *getInt64Ty() {
return Type::getInt64Ty(Context);
}
- /// getFloatTy - Fetch the type representing a 32-bit floating point value.
+ /// \brief Fetch the type representing a 32-bit floating point value.
Type *getFloatTy() {
return Type::getFloatTy(Context);
}
- /// getDoubleTy - Fetch the type representing a 64-bit floating point value.
+ /// \brief Fetch the type representing a 64-bit floating point value.
Type *getDoubleTy() {
return Type::getDoubleTy(Context);
}
- /// getVoidTy - Fetch the type representing void.
+ /// \brief Fetch the type representing void.
Type *getVoidTy() {
return Type::getVoidTy(Context);
}
+ /// \brief Fetch the type representing a pointer to an 8-bit integer value.
PointerType *getInt8PtrTy(unsigned AddrSpace = 0) {
return Type::getInt8PtrTy(Context, AddrSpace);
}
+ /// \brief Fetch the type representing a pointer to an integer value.
IntegerType* getIntPtrTy(DataLayout *DL, unsigned AddrSpace = 0) {
return DL->getIntPtrType(Context, AddrSpace);
}
@@ -276,9 +276,11 @@ public:
// Intrinsic creation methods
//===--------------------------------------------------------------------===//
- /// CreateMemSet - Create and insert a memset to the specified pointer and the
- /// specified value. If the pointer isn't an i8*, it will be converted. If a
- /// TBAA tag is specified, it will be added to the instruction.
+ /// \brief Create and insert a memset to the specified pointer and the
+ /// specified value.
+ ///
+ /// If the pointer isn't an i8*, it will be converted. If a TBAA tag is
+ /// specified, it will be added to the instruction.
CallInst *CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemSet(Ptr, Val, getInt64(Size), Align, isVolatile, TBAATag);
@@ -287,7 +289,8 @@ public:
CallInst *CreateMemSet(Value *Ptr, Value *Val, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0);
- /// CreateMemCpy - Create and insert a memcpy between the specified pointers.
+ /// \brief Create and insert a memcpy between the specified pointers.
+ ///
/// If the pointers aren't i8*, they will be converted. If a TBAA tag is
/// specified, it will be added to the instruction.
CallInst *CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
@@ -301,9 +304,11 @@ public:
bool isVolatile = false, MDNode *TBAATag = 0,
MDNode *TBAAStructTag = 0);
- /// CreateMemMove - Create and insert a memmove between the specified
- /// pointers. If the pointers aren't i8*, they will be converted. If a TBAA
- /// tag is specified, it will be added to the instruction.
+ /// \brief Create and insert a memmove between the specified
+ /// pointers.
+ ///
+ /// If the pointers aren't i8*, they will be converted. If a TBAA tag is
+ /// specified, it will be added to the instruction.
CallInst *CreateMemMove(Value *Dst, Value *Src, uint64_t Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0) {
return CreateMemMove(Dst, Src, getInt64(Size), Align, isVolatile, TBAATag);
@@ -312,21 +317,23 @@ public:
CallInst *CreateMemMove(Value *Dst, Value *Src, Value *Size, unsigned Align,
bool isVolatile = false, MDNode *TBAATag = 0);
- /// CreateLifetimeStart - Create a lifetime.start intrinsic. If the pointer
- /// isn't i8* it will be converted.
+ /// \brief Create a lifetime.start intrinsic.
+ ///
+ /// If the pointer isn't i8* it will be converted.
CallInst *CreateLifetimeStart(Value *Ptr, ConstantInt *Size = 0);
- /// CreateLifetimeEnd - Create a lifetime.end intrinsic. If the pointer isn't
- /// i8* it will be converted.
+ /// \brief Create a lifetime.end intrinsic.
+ ///
+ /// If the pointer isn't i8* it will be converted.
CallInst *CreateLifetimeEnd(Value *Ptr, ConstantInt *Size = 0);
private:
Value *getCastedInt8PtrValue(Value *Ptr);
};
-/// IRBuilder - This provides a uniform API for creating instructions and
-/// inserting them into a basic block: either at the end of a BasicBlock, or
-/// at a specific iterator location in a block.
+/// \brief This provides a uniform API for creating instructions and inserting
+/// them into a basic block: either at the end of a BasicBlock, or at a specific
+/// iterator location in a block.
///
/// Note that the builder does not expose the full generality of LLVM
/// instructions. For access to extra instruction properties, use the mutators
@@ -396,38 +403,37 @@ public:
SetInsertPoint(TheBB, IP);
}
- /// getFolder - Get the constant folder being used.
+ /// \brief Get the constant folder being used.
const T &getFolder() { return Folder; }
- /// getDefaultFPMathTag - Get the floating point math metadata being used.
+ /// \brief Get the floating point math metadata being used.
MDNode *getDefaultFPMathTag() const { return DefaultFPMathTag; }
- /// Get the flags to be applied to created floating point ops
+ /// \brief Get the flags to be applied to created floating point ops
FastMathFlags getFastMathFlags() const { return FMF; }
- /// Clear the fast-math flags.
+ /// \brief Clear the fast-math flags.
void clearFastMathFlags() { FMF.clear(); }
- /// SetDefaultFPMathTag - Set the floating point math metadata to be used.
+ /// \brief SetDefaultFPMathTag - Set the floating point math metadata to be used.
void SetDefaultFPMathTag(MDNode *FPMathTag) { DefaultFPMathTag = FPMathTag; }
- /// Set the fast-math flags to be used with generated fp-math operators
+ /// \brief Set the fast-math flags to be used with generated fp-math operators
void SetFastMathFlags(FastMathFlags NewFMF) { FMF = NewFMF; }
- /// isNamePreserving - Return true if this builder is configured to actually
- /// add the requested names to IR created through it.
+ /// \brief Return true if this builder is configured to actually add the
+ /// requested names to IR created through it.
bool isNamePreserving() const { return preserveNames; }
- /// Insert - Insert and return the specified instruction.
+ /// \brief Insert and return the specified instruction.
template<typename InstTy>
InstTy *Insert(InstTy *I, const Twine &Name = "") const {
this->InsertHelper(I, Name, BB, InsertPt);
- if (!getCurrentDebugLocation().isUnknown())
- this->SetInstDebugLocation(I);
+ this->SetInstDebugLocation(I);
return I;
}
- /// Insert - No-op overload to handle constants.
+ /// \brief No-op overload to handle constants.
Constant *Insert(Constant *C, const Twine& = "") const {
return C;
}
@@ -447,25 +453,23 @@ private:
}
public:
- /// CreateRetVoid - Create a 'ret void' instruction.
+ /// \brief Create a 'ret void' instruction.
ReturnInst *CreateRetVoid() {
return Insert(ReturnInst::Create(Context));
}
- /// @verbatim
- /// CreateRet - Create a 'ret <val>' instruction.
- /// @endverbatim
+ /// \brief Create a 'ret <val>' instruction.
ReturnInst *CreateRet(Value *V) {
return Insert(ReturnInst::Create(Context, V));
}
- /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
+ /// \brief Create a sequence of N insertvalue instructions,
/// with one Value from the retVals array each, that build a aggregate
/// return value one value at a time, and a ret instruction to return
- /// the resulting aggregate value. This is a convenience function for
- /// code that uses aggregate return values as a vehicle for having
- /// multiple return values.
+ /// the resulting aggregate value.
///
+ /// This is a convenience function for code that uses aggregate return values
+ /// as a vehicle for having multiple return values.
ReturnInst *CreateAggregateRet(Value *const *retVals, unsigned N) {
Value *V = UndefValue::get(getCurrentFunctionReturnType());
for (unsigned i = 0; i != N; ++i)
@@ -473,12 +477,12 @@ public:
return Insert(ReturnInst::Create(Context, V));
}
- /// CreateBr - Create an unconditional 'br label X' instruction.
+ /// \brief Create an unconditional 'br label X' instruction.
BranchInst *CreateBr(BasicBlock *Dest) {
return Insert(BranchInst::Create(Dest));
}
- /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
+ /// \brief Create a conditional 'br Cond, TrueDest, FalseDest'
/// instruction.
BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False,
MDNode *BranchWeights = 0) {
@@ -486,18 +490,18 @@ public:
BranchWeights));
}
- /// CreateSwitch - Create a switch instruction with the specified value,
- /// default dest, and with a hint for the number of cases that will be added
- /// (for efficient allocation).
+ /// \brief Create a switch instruction with the specified value, default dest,
+ /// and with a hint for the number of cases that will be added (for efficient
+ /// allocation).
SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10,
MDNode *BranchWeights = 0) {
return Insert(addBranchWeights(SwitchInst::Create(V, Dest, NumCases),
BranchWeights));
}
- /// CreateIndirectBr - Create an indirect branch instruction with the
- /// specified address operand, with an optional hint for the number of
- /// destinations that will be added (for efficient allocation).
+ /// \brief Create an indirect branch instruction with the specified address
+ /// operand, with an optional hint for the number of destinations that will be
+ /// added (for efficient allocation).
IndirectBrInst *CreateIndirectBr(Value *Addr, unsigned NumDests = 10) {
return Insert(IndirectBrInst::Create(Addr, NumDests));
}
@@ -522,7 +526,7 @@ public:
return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest, Args),
Name);
}
- /// CreateInvoke - Create an invoke instruction.
+ /// \brief Create an invoke instruction.
InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
BasicBlock *UnwindDest, ArrayRef<Value *> Args,
const Twine &Name = "") {
@@ -825,7 +829,7 @@ public:
const Twine &Name = "") {
return Insert(new AllocaInst(Ty, ArraySize), Name);
}
- // Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
+ // \brief Provided to resolve 'CreateLoad(Ptr, "...")' correctly, instead of
// converting the string to 'bool' for the isVolatile parameter.
LoadInst *CreateLoad(Value *Ptr, const char *Name) {
return Insert(new LoadInst(Ptr), Name);
@@ -839,8 +843,9 @@ public:
StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
return Insert(new StoreInst(Val, Ptr, isVolatile));
}
- // Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")' correctly,
- // instead of converting the string to 'bool' for the isVolatile parameter.
+ // \brief Provided to resolve 'CreateAlignedLoad(Ptr, Align, "...")'
+ // correctly, instead of converting the string to 'bool' for the isVolatile
+ // parameter.
LoadInst *CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name) {
LoadInst *LI = CreateLoad(Ptr, Name);
LI->setAlignment(Align);
@@ -1002,8 +1007,8 @@ public:
return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
}
- /// CreateGlobalStringPtr - Same as CreateGlobalString, but return a pointer
- /// with "i8*" type instead of a pointer to array of i8.
+ /// \brief Same as CreateGlobalString, but return a pointer with "i8*" type
+ /// instead of a pointer to array of i8.
Value *CreateGlobalStringPtr(StringRef Str, const Twine &Name = "") {
Value *gv = CreateGlobalString(Str, Name);
Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
@@ -1024,27 +1029,31 @@ public:
Value *CreateSExt(Value *V, Type *DestTy, const Twine &Name = "") {
return CreateCast(Instruction::SExt, V, DestTy, Name);
}
- /// CreateZExtOrTrunc - Create a ZExt or Trunc from the integer value V to
- /// DestTy. Return the value untouched if the type of V is already DestTy.
- Value *CreateZExtOrTrunc(Value *V, IntegerType *DestTy,
+ /// \brief Create a ZExt or Trunc from the integer value V to DestTy. Return
+ /// the value untouched if the type of V is already DestTy.
+ Value *CreateZExtOrTrunc(Value *V, Type *DestTy,
const Twine &Name = "") {
- assert(isa<IntegerType>(V->getType()) && "Can only zero extend integers!");
- IntegerType *IntTy = cast<IntegerType>(V->getType());
- if (IntTy->getBitWidth() < DestTy->getBitWidth())
+ assert(V->getType()->isIntOrIntVectorTy() &&
+ DestTy->isIntOrIntVectorTy() &&
+ "Can only zero extend/truncate integers!");
+ Type *VTy = V->getType();
+ if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
return CreateZExt(V, DestTy, Name);
- if (IntTy->getBitWidth() > DestTy->getBitWidth())
+ if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
return CreateTrunc(V, DestTy, Name);
return V;
}
- /// CreateSExtOrTrunc - Create a SExt or Trunc from the integer value V to
- /// DestTy. Return the value untouched if the type of V is already DestTy.
- Value *CreateSExtOrTrunc(Value *V, IntegerType *DestTy,
+ /// \brief Create a SExt or Trunc from the integer value V to DestTy. Return
+ /// the value untouched if the type of V is already DestTy.
+ Value *CreateSExtOrTrunc(Value *V, Type *DestTy,
const Twine &Name = "") {
- assert(isa<IntegerType>(V->getType()) && "Can only sign extend integers!");
- IntegerType *IntTy = cast<IntegerType>(V->getType());
- if (IntTy->getBitWidth() < DestTy->getBitWidth())
+ assert(V->getType()->isIntOrIntVectorTy() &&
+ DestTy->isIntOrIntVectorTy() &&
+ "Can only sign extend/truncate integers!");
+ Type *VTy = V->getType();
+ if (VTy->getScalarSizeInBits() < DestTy->getScalarSizeInBits())
return CreateSExt(V, DestTy, Name);
- if (IntTy->getBitWidth() > DestTy->getBitWidth())
+ if (VTy->getScalarSizeInBits() > DestTy->getScalarSizeInBits())
return CreateTrunc(V, DestTy, Name);
return V;
}
@@ -1128,8 +1137,9 @@ public:
return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
}
private:
- // Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a compile time
- // error, instead of converting the string to bool for the isSigned parameter.
+ // \brief Provided to resolve 'CreateIntCast(Ptr, Ptr, "...")', giving a
+ // compile time error, instead of converting the string to bool for the
+ // isSigned parameter.
Value *CreateIntCast(Value *, Type *, const char *) LLVM_DELETED_FUNCTION;
public:
Value *CreateFPCast(Value *V, Type *DestTy, const Twine &Name = "") {
@@ -1339,23 +1349,24 @@ public:
// Utility creation methods
//===--------------------------------------------------------------------===//
- /// CreateIsNull - Return an i1 value testing if \p Arg is null.
+ /// \brief Return an i1 value testing if \p Arg is null.
Value *CreateIsNull(Value *Arg, const Twine &Name = "") {
return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
Name);
}
- /// CreateIsNotNull - Return an i1 value testing if \p Arg is not null.
+ /// \brief Return an i1 value testing if \p Arg is not null.
Value *CreateIsNotNull(Value *Arg, const Twine &Name = "") {
return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
Name);
}
- /// CreatePtrDiff - Return the i64 difference between two pointer values,
- /// dividing out the size of the pointed-to objects. This is intended to
- /// implement C-style pointer subtraction. As such, the pointers must be
- /// appropriately aligned for their element types and pointing into the
- /// same object.
+ /// \brief Return the i64 difference between two pointer values, dividing out
+ /// the size of the pointed-to objects.
+ ///
+ /// This is intended to implement C-style pointer subtraction. As such, the
+ /// pointers must be appropriately aligned for their element types and
+ /// pointing into the same object.
Value *CreatePtrDiff(Value *LHS, Value *RHS, const Twine &Name = "") {
assert(LHS->getType() == RHS->getType() &&
"Pointer subtraction operand types must match!");
@@ -1368,8 +1379,8 @@ public:
Name);
}
- /// CreateVectorSplat - Return a vector value that contains \arg V broadcasted
- /// to \p NumElts elements.
+ /// \brief Return a vector value that contains \arg V broadcasted to \p
+ /// NumElts elements.
Value *CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name = "") {
assert(NumElts > 0 && "Cannot splat to an empty vector!");
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 15d4fb0..33e4ab8 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INLINEASM_H
-#define LLVM_INLINEASM_H
+#ifndef LLVM_IR_INLINEASM_H
+#define LLVM_IR_INLINEASM_H
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Value.h"
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index 66bf8dd..3e6903c 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INSTRUCTION_TYPES_H
-#define LLVM_INSTRUCTION_TYPES_H
+#ifndef LLVM_IR_INSTRTYPES_H
+#define LLVM_IR_INSTRTYPES_H
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DerivedTypes.h"
@@ -309,7 +309,7 @@ public:
/// NEG, FNeg, or NOT instruction.
///
static bool isNeg(const Value *V);
- static bool isFNeg(const Value *V);
+ static bool isFNeg(const Value *V, bool IgnoreZeroSign=false);
static bool isNot(const Value *V);
/// getNegArgument, getNotArgument - Helper functions to extract the
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index 2731bfb..5721d8f 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INSTRUCTION_H
-#define LLVM_INSTRUCTION_H
+#ifndef LLVM_IR_INSTRUCTION_H
+#define LLVM_IR_INSTRUCTION_H
#include "llvm/ADT/ilist_node.h"
#include "llvm/IR/User.h"
@@ -309,6 +309,12 @@ public:
///
bool mayThrow() const;
+ /// mayReturn - Return true if this is a function that may return.
+ /// this is true for all normal instructions. The only exception
+ /// is functions that are marked with the 'noreturn' attribute.
+ ///
+ bool mayReturn() const;
+
/// mayHaveSideEffects - Return true if the instruction may have side effects.
///
/// Note that this does not consider malloc and alloca to have side
@@ -316,7 +322,7 @@ public:
/// instructions which don't used the returned value. For cases where this
/// matters, isSafeToSpeculativelyExecute may be more appropriate.
bool mayHaveSideEffects() const {
- return mayWriteToMemory() || mayThrow();
+ return mayWriteToMemory() || mayThrow() || !mayReturn();
}
/// clone() - Create a copy of 'this' instruction that is identical in all
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index bb4ea55..1ae8850 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INSTRUCTIONS_H
-#define LLVM_INSTRUCTIONS_H
+#ifndef LLVM_IR_INSTRUCTIONS_H
+#define LLVM_IR_INSTRUCTIONS_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
@@ -91,7 +91,7 @@ public:
/// getType - Overload to return most specific pointer type
///
PointerType *getType() const {
- return reinterpret_cast<PointerType*>(Instruction::getType());
+ return cast<PointerType>(Instruction::getType());
}
/// getAllocatedType - Return the type that is being allocated by the
@@ -762,9 +762,9 @@ public:
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
- // getType - Overload to return most specific pointer type...
- PointerType *getType() const {
- return reinterpret_cast<PointerType*>(Instruction::getType());
+ // getType - Overload to return most specific sequential type.
+ SequentialType *getType() const {
+ return cast<SequentialType>(Instruction::getType());
}
/// \brief Returns the address space of this instruction's pointer type.
@@ -953,7 +953,7 @@ public:
"Both operands to ICmp instruction are not of the same type!");
// Check that the operands are the right type
assert((getOperand(0)->getType()->isIntOrIntVectorTy() ||
- getOperand(0)->getType()->isPointerTy()) &&
+ getOperand(0)->getType()->getScalarType()->isPointerTy()) &&
"Invalid operand types for ICmp instruction");
}
@@ -1570,7 +1570,7 @@ public:
const Value *getIndexOperand() const { return Op<1>(); }
VectorType *getVectorOperandType() const {
- return reinterpret_cast<VectorType*>(getVectorOperand()->getType());
+ return cast<VectorType>(getVectorOperand()->getType());
}
@@ -1629,7 +1629,7 @@ public:
/// getType - Overload to return most specific vector type.
///
VectorType *getType() const {
- return reinterpret_cast<VectorType*>(Instruction::getType());
+ return cast<VectorType>(Instruction::getType());
}
/// Transparently provide more efficient getOperand methods.
@@ -1681,14 +1681,14 @@ public:
/// getType - Overload to return most specific vector type.
///
VectorType *getType() const {
- return reinterpret_cast<VectorType*>(Instruction::getType());
+ return cast<VectorType>(Instruction::getType());
}
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
Constant *getMask() const {
- return reinterpret_cast<Constant*>(getOperand(2));
+ return cast<Constant>(getOperand(2));
}
/// getMaskValue - Return the index from the shuffle mask for the specified
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index a8dfcbd..8344c56 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -21,8 +21,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INTRINSICINST_H
-#define LLVM_INTRINSICINST_H
+#ifndef LLVM_IR_INTRINSICINST_H
+#define LLVM_IR_INTRINSICINST_H
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
diff --git a/include/llvm/IR/Intrinsics.h b/include/llvm/IR/Intrinsics.h
index 1e20fd7..c97cd91 100644
--- a/include/llvm/IR/Intrinsics.h
+++ b/include/llvm/IR/Intrinsics.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_INTRINSICS_H
-#define LLVM_INTRINSICS_H
+#ifndef LLVM_IR_INTRINSICS_H
+#define LLVM_IR_INTRINSICS_H
#include "llvm/ADT/ArrayRef.h"
#include <string>
@@ -79,7 +79,7 @@ namespace Intrinsic {
/// getIntrinsicInfoTableEntries.
struct IITDescriptor {
enum IITDescriptorKind {
- Void, MMX, Metadata, Float, Double,
+ Void, MMX, Metadata, Half, Float, Double,
Integer, Vector, Pointer, Struct,
Argument, ExtendVecArgument, TruncVecArgument
} Kind;
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index e9fbba9..e252664 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -106,6 +106,7 @@ def llvm_i8_ty : LLVMType<i8>;
def llvm_i16_ty : LLVMType<i16>;
def llvm_i32_ty : LLVMType<i32>;
def llvm_i64_ty : LLVMType<i64>;
+def llvm_half_ty : LLVMType<f16>;
def llvm_float_ty : LLVMType<f32>;
def llvm_double_ty : LLVMType<f64>;
def llvm_f80_ty : LLVMType<f80>;
diff --git a/include/llvm/IR/IntrinsicsNVVM.td b/include/llvm/IR/IntrinsicsNVVM.td
index 1853c99..ebfd03e 100644
--- a/include/llvm/IR/IntrinsicsNVVM.td
+++ b/include/llvm/IR/IntrinsicsNVVM.td
@@ -805,6 +805,16 @@ def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
[LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
"llvm.nvvm.ldu.global.p">;
+// Generated within nvvm. Use for ldg on sm_35 or later
+def int_nvvm_ldg_global_i : Intrinsic<[llvm_anyint_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldg.global.i">;
+def int_nvvm_ldg_global_f : Intrinsic<[llvm_anyfloat_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldg.global.f">;
+def int_nvvm_ldg_global_p : Intrinsic<[llvm_anyptr_ty],
+ [LLVMPointerType<LLVMMatchType<0>>], [IntrReadMem, NoCapture<0>],
+ "llvm.nvvm.ldg.global.p">;
// Use for generic pointers
// - These intrinsics are used to convert address spaces.
@@ -815,36 +825,36 @@ def int_nvvm_ldu_global_p : Intrinsic<[llvm_anyptr_ty],
// of pointer to another type of pointer, while the address space remains
// the same.
def int_nvvm_ptr_local_to_gen: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.local.to.gen">;
def int_nvvm_ptr_shared_to_gen: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.shared.to.gen">;
def int_nvvm_ptr_global_to_gen: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.global.to.gen">;
def int_nvvm_ptr_constant_to_gen: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.constant.to.gen">;
def int_nvvm_ptr_gen_to_global: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.gen.to.global">;
def int_nvvm_ptr_gen_to_shared: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.gen.to.shared">;
def int_nvvm_ptr_gen_to_local: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.gen.to.local">;
def int_nvvm_ptr_gen_to_constant: Intrinsic<[llvm_anyptr_ty],
- [llvm_anyptr_ty], [IntrNoMem, NoCapture<0>],
+ [llvm_anyptr_ty], [IntrNoMem],
"llvm.nvvm.ptr.gen.to.constant">;
// Used in nvvm internally to help address space opt and ptx code generation
// This is for params that are passed to kernel functions by pointer by-val.
def int_nvvm_ptr_gen_to_param: Intrinsic<[llvm_anyptr_ty],
[llvm_anyptr_ty],
- [IntrNoMem, NoCapture<0>],
+ [IntrNoMem],
"llvm.nvvm.ptr.gen.to.param">;
// Move intrinsics, used in nvvm internally
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index 58fb39f..b3c558b 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LLVMCONTEXT_H
-#define LLVM_LLVMCONTEXT_H
+#ifndef LLVM_IR_LLVMCONTEXT_H
+#define LLVM_IR_LLVMCONTEXT_H
#include "llvm/Support/Compiler.h"
@@ -58,39 +58,27 @@ public:
void getMDKindNames(SmallVectorImpl<StringRef> &Result) const;
- typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context,
- unsigned LocCookie);
+ typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,
+ unsigned LocCookie);
- /// setDiagnosticHandler - This method sets a handler that is invoked
- /// when problems are detected by the backend. The first argument is a
- /// function pointer and the second is a context pointer that gets passed
- /// into the DiagHandler.
+ /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked
+ /// when problems with inline asm are detected by the backend. The first
+ /// argument is a function pointer and the second is a context pointer that
+ /// gets passed into the DiagHandler.
///
/// LLVMContext doesn't take ownership or interpret either of these
/// pointers.
- void setDiagnosticHandler(DiagHandlerTy DiagHandler, void *DiagContext = 0);
+ void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
+ void *DiagContext = 0);
- /// getDiagnosticHandler - Return the diagnostic handler set by
- /// setDiagnosticHandler.
- DiagHandlerTy getDiagnosticHandler() const;
+ /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
+ /// setInlineAsmDiagnosticHandler.
+ InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const;
- /// getDiagnosticContext - Return the diagnostic context set by
- /// setDiagnosticHandler.
- void *getDiagnosticContext() const;
+ /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
+ /// setInlineAsmDiagnosticHandler.
+ void *getInlineAsmDiagnosticContext() const;
- /// FIXME: Temporary copies of the old names; to be removed as soon as
- /// clang switches to the new ones.
- typedef DiagHandlerTy InlineAsmDiagHandlerTy;
- void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
- void *DiagContext = 0) {
- setDiagnosticHandler(DiagHandler, DiagContext);
- }
- InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const {
- return getDiagnosticHandler();
- }
- void *getInlineAsmDiagnosticContext() const {
- return getDiagnosticContext();
- }
/// emitError - Emit an error message to the currently installed error handler
/// with optional location information. This function returns, so code should
@@ -101,12 +89,6 @@ public:
void emitError(const Instruction *I, const Twine &ErrorStr);
void emitError(const Twine &ErrorStr);
- /// emitWarning - This is similar to emitError but it emits a warning instead
- /// of an error.
- void emitWarning(unsigned LocCookie, const Twine &ErrorStr);
- void emitWarning(const Instruction *I, const Twine &ErrorStr);
- void emitWarning(const Twine &ErrorStr);
-
private:
LLVMContext(LLVMContext&) LLVM_DELETED_FUNCTION;
void operator=(LLVMContext&) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/IR/MDBuilder.h b/include/llvm/IR/MDBuilder.h
index d3ca644..604051b 100644
--- a/include/llvm/IR/MDBuilder.h
+++ b/include/llvm/IR/MDBuilder.h
@@ -12,150 +12,151 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MDBUILDER_H
-#define LLVM_MDBUILDER_H
+#ifndef LLVM_IR_MDBUILDER_H
+#define LLVM_IR_MDBUILDER_H
-#include "llvm/ADT/APInt.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
namespace llvm {
- class MDBuilder {
- LLVMContext &Context;
-
- public:
- MDBuilder(LLVMContext &context) : Context(context) {}
-
- /// \brief Return the given string as metadata.
- MDString *createString(StringRef Str) {
- return MDString::get(Context, Str);
- }
-
- //===------------------------------------------------------------------===//
- // FPMath metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata with the given settings. The special value 0.0
- /// for the Accuracy parameter indicates the default (maximal precision)
- /// setting.
- MDNode *createFPMath(float Accuracy) {
- if (Accuracy == 0.0)
- return 0;
- assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
- Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy);
- return MDNode::get(Context, Op);
- }
-
- //===------------------------------------------------------------------===//
- // Prof metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata containing two branch weights.
- MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) {
- uint32_t Weights[] = { TrueWeight, FalseWeight };
- return createBranchWeights(Weights);
- }
-
- /// \brief Return metadata containing a number of branch weights.
- MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) {
- assert(Weights.size() >= 2 && "Need at least two branch weights!");
-
- SmallVector<Value *, 4> Vals(Weights.size()+1);
- Vals[0] = createString("branch_weights");
-
- Type *Int32Ty = Type::getInt32Ty(Context);
- for (unsigned i = 0, e = Weights.size(); i != e; ++i)
- Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]);
-
- return MDNode::get(Context, Vals);
- }
-
- //===------------------------------------------------------------------===//
- // Range metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata describing the range [Lo, Hi).
- MDNode *createRange(const APInt &Lo, const APInt &Hi) {
- assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
- // If the range is everything then it is useless.
- if (Hi == Lo)
- return 0;
-
- // Return the range [Lo, Hi).
- Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
- Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) };
- return MDNode::get(Context, Range);
- }
-
-
- //===------------------------------------------------------------------===//
- // TBAA metadata.
- //===------------------------------------------------------------------===//
-
- /// \brief Return metadata appropriate for a TBAA root node. Each returned
- /// node is distinct from all other metadata and will never be identified
- /// (uniqued) with anything else.
- MDNode *createAnonymousTBAARoot() {
- // To ensure uniqueness the root node is self-referential.
- MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
- MDNode *Root = MDNode::get(Context, Dummy);
- // At this point we have
- // !0 = metadata !{} <- dummy
- // !1 = metadata !{metadata !0} <- root
- // Replace the dummy operand with the root node itself and delete the dummy.
- Root->replaceOperandWith(0, Root);
- MDNode::deleteTemporary(Dummy);
- // We now have
- // !1 = metadata !{metadata !1} <- self-referential root
- return Root;
- }
-
- /// \brief Return metadata appropriate for a TBAA root node with the given
- /// name. This may be identified (uniqued) with other roots with the same
- /// name.
- MDNode *createTBAARoot(StringRef Name) {
- return MDNode::get(Context, createString(Name));
- }
-
- /// \brief Return metadata for a non-root TBAA node with the given name,
- /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
- MDNode *createTBAANode(StringRef Name, MDNode *Parent,
- bool isConstant = false) {
- if (isConstant) {
- Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
- Value *Ops[3] = { createString(Name), Parent, Flags };
- return MDNode::get(Context, Ops);
- } else {
- Value *Ops[2] = { createString(Name), Parent };
- return MDNode::get(Context, Ops);
- }
+class APInt;
+class LLVMContext;
+
+class MDBuilder {
+ LLVMContext &Context;
+
+public:
+ MDBuilder(LLVMContext &context) : Context(context) {}
+
+ /// \brief Return the given string as metadata.
+ MDString *createString(StringRef Str) {
+ return MDString::get(Context, Str);
+ }
+
+ //===------------------------------------------------------------------===//
+ // FPMath metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata with the given settings. The special value 0.0
+ /// for the Accuracy parameter indicates the default (maximal precision)
+ /// setting.
+ MDNode *createFPMath(float Accuracy) {
+ if (Accuracy == 0.0)
+ return 0;
+ assert(Accuracy > 0.0 && "Invalid fpmath accuracy!");
+ Value *Op = ConstantFP::get(Type::getFloatTy(Context), Accuracy);
+ return MDNode::get(Context, Op);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Prof metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata containing two branch weights.
+ MDNode *createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight) {
+ uint32_t Weights[] = { TrueWeight, FalseWeight };
+ return createBranchWeights(Weights);
+ }
+
+ /// \brief Return metadata containing a number of branch weights.
+ MDNode *createBranchWeights(ArrayRef<uint32_t> Weights) {
+ assert(Weights.size() >= 2 && "Need at least two branch weights!");
+
+ SmallVector<Value *, 4> Vals(Weights.size()+1);
+ Vals[0] = createString("branch_weights");
+
+ Type *Int32Ty = Type::getInt32Ty(Context);
+ for (unsigned i = 0, e = Weights.size(); i != e; ++i)
+ Vals[i+1] = ConstantInt::get(Int32Ty, Weights[i]);
+
+ return MDNode::get(Context, Vals);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Range metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata describing the range [Lo, Hi).
+ MDNode *createRange(const APInt &Lo, const APInt &Hi) {
+ assert(Lo.getBitWidth() == Hi.getBitWidth() && "Mismatched bitwidths!");
+ // If the range is everything then it is useless.
+ if (Hi == Lo)
+ return 0;
+
+ // Return the range [Lo, Hi).
+ Type *Ty = IntegerType::get(Context, Lo.getBitWidth());
+ Value *Range[2] = { ConstantInt::get(Ty, Lo), ConstantInt::get(Ty, Hi) };
+ return MDNode::get(Context, Range);
+ }
+
+
+ //===------------------------------------------------------------------===//
+ // TBAA metadata.
+ //===------------------------------------------------------------------===//
+
+ /// \brief Return metadata appropriate for a TBAA root node. Each returned
+ /// node is distinct from all other metadata and will never be identified
+ /// (uniqued) with anything else.
+ MDNode *createAnonymousTBAARoot() {
+ // To ensure uniqueness the root node is self-referential.
+ MDNode *Dummy = MDNode::getTemporary(Context, ArrayRef<Value*>());
+ MDNode *Root = MDNode::get(Context, Dummy);
+ // At this point we have
+ // !0 = metadata !{} <- dummy
+ // !1 = metadata !{metadata !0} <- root
+ // Replace the dummy operand with the root node itself and delete the dummy.
+ Root->replaceOperandWith(0, Root);
+ MDNode::deleteTemporary(Dummy);
+ // We now have
+ // !1 = metadata !{metadata !1} <- self-referential root
+ return Root;
+ }
+
+ /// \brief Return metadata appropriate for a TBAA root node with the given
+ /// name. This may be identified (uniqued) with other roots with the same
+ /// name.
+ MDNode *createTBAARoot(StringRef Name) {
+ return MDNode::get(Context, createString(Name));
+ }
+
+ /// \brief Return metadata for a non-root TBAA node with the given name,
+ /// parent in the TBAA tree, and value for 'pointsToConstantMemory'.
+ MDNode *createTBAANode(StringRef Name, MDNode *Parent,
+ bool isConstant = false) {
+ if (isConstant) {
+ Constant *Flags = ConstantInt::get(Type::getInt64Ty(Context), 1);
+ Value *Ops[3] = { createString(Name), Parent, Flags };
+ return MDNode::get(Context, Ops);
+ } else {
+ Value *Ops[2] = { createString(Name), Parent };
+ return MDNode::get(Context, Ops);
}
+ }
+
+ struct TBAAStructField {
+ uint64_t Offset;
+ uint64_t Size;
+ MDNode *TBAA;
+ TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) :
+ Offset(Offset), Size(Size), TBAA(TBAA) {}
+ };
- struct TBAAStructField {
- uint64_t Offset;
- uint64_t Size;
- MDNode *TBAA;
- TBAAStructField(uint64_t Offset, uint64_t Size, MDNode *TBAA) :
- Offset(Offset), Size(Size), TBAA(TBAA) {}
- };
-
- /// \brief Return metadata for a tbaa.struct node with the given
- /// struct field descriptions.
- MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
- SmallVector<Value *, 4> Vals(Fields.size() * 3);
- Type *Int64 = IntegerType::get(Context, 64);
- for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
- Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset);
- Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size);
- Vals[i * 3 + 2] = Fields[i].TBAA;
- }
- return MDNode::get(Context, Vals);
+ /// \brief Return metadata for a tbaa.struct node with the given
+ /// struct field descriptions.
+ MDNode *createTBAAStructNode(ArrayRef<TBAAStructField> Fields) {
+ SmallVector<Value *, 4> Vals(Fields.size() * 3);
+ Type *Int64 = IntegerType::get(Context, 64);
+ for (unsigned i = 0, e = Fields.size(); i != e; ++i) {
+ Vals[i * 3 + 0] = ConstantInt::get(Int64, Fields[i].Offset);
+ Vals[i * 3 + 1] = ConstantInt::get(Int64, Fields[i].Size);
+ Vals[i * 3 + 2] = Fields[i].TBAA;
}
+ return MDNode::get(Context, Vals);
+ }
- };
+};
} // end namespace llvm
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index 402abb3..8c2cfac 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_METADATA_H
-#define LLVM_METADATA_H
+#ifndef LLVM_IR_METADATA_H
+#define LLVM_IR_METADATA_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
@@ -29,8 +29,8 @@ class Module;
template <typename T> class SmallVectorImpl;
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-
-
+
+
//===----------------------------------------------------------------------===//
/// MDString - a single uniqued string.
/// These are used to efficiently contain a byte sequence for metadata.
@@ -51,7 +51,7 @@ public:
unsigned getLength() const { return (unsigned)getName().size(); }
typedef StringRef::iterator iterator;
-
+
/// begin() - Pointer to the first byte of the string.
iterator begin() const { return getName().begin(); }
@@ -64,9 +64,9 @@ public:
}
};
-
+
class MDNodeOperand;
-
+
//===----------------------------------------------------------------------===//
/// MDNode - a tuple of other values.
class MDNode : public Value, public FoldingSetNode {
@@ -82,37 +82,37 @@ class MDNode : public Value, public FoldingSetNode {
/// NumOperands - This many 'MDNodeOperand' items are co-allocated onto the
/// end of this MDNode.
unsigned NumOperands;
-
+
// Subclass data enums.
enum {
/// FunctionLocalBit - This bit is set if this MDNode is function local.
/// This is true when it (potentially transitively) contains a reference to
/// something in a function, like an argument, basicblock, or instruction.
FunctionLocalBit = 1 << 0,
-
+
/// NotUniquedBit - This is set on MDNodes that are not uniqued because they
/// have a null operand.
NotUniquedBit = 1 << 1,
-
+
/// DestroyFlag - This bit is set by destroy() so the destructor can assert
/// that the node isn't being destroyed with a plain 'delete'.
DestroyFlag = 1 << 2
};
-
+
// FunctionLocal enums.
enum FunctionLocalness {
FL_Unknown = -1,
FL_No = 0,
FL_Yes = 1
};
-
- /// replaceOperand - Replace each instance of F from the operand list of this
+
+ /// replaceOperand - Replace each instance of F from the operand list of this
/// node with T.
void replaceOperand(MDNodeOperand *Op, Value *NewVal);
~MDNode();
MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);
-
+
static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,
FunctionLocalness FL, bool Insert = true);
public:
@@ -123,7 +123,7 @@ public:
static MDNode *getWhenValsUnresolved(LLVMContext &Context,
ArrayRef<Value*> Vals,
bool isFunctionLocal);
-
+
static MDNode *getIfExists(LLVMContext &Context, ArrayRef<Value*> Vals);
/// getTemporary - Return a temporary MDNode, for use in constructing
@@ -137,22 +137,22 @@ public:
/// replaceOperandWith - Replace a specific operand.
void replaceOperandWith(unsigned i, Value *NewVal);
-
+
/// getOperand - Return specified operand.
Value *getOperand(unsigned i) const;
-
+
/// getNumOperands - Return number of MDNode operands.
unsigned getNumOperands() const { return NumOperands; }
-
+
/// isFunctionLocal - Return whether MDNode is local to a function.
bool isFunctionLocal() const {
return (getSubclassDataFromValue() & FunctionLocalBit) != 0;
}
-
+
// getFunction - If this metadata is function-local and recursively has a
// function-local operand, return the first such operand's parent function.
// Otherwise, return null. getFunction() should not be used for performance-
- // critical code because it recursively visits all the MDNode's operands.
+ // critical code because it recursively visits all the MDNode's operands.
const Function *getFunction() const;
/// Profile - calculate a unique identifier for this MDNode to collapse
@@ -172,11 +172,11 @@ private:
// destroy - Delete this node. Only when there are no uses.
void destroy();
- bool isNotUniqued() const {
+ bool isNotUniqued() const {
return (getSubclassDataFromValue() & NotUniquedBit) != 0;
}
void setIsNotUniqued();
-
+
// Shadow Value::setValueSubclassData with a private forwarding method so that
// any future subclasses cannot accidentally use it.
void setValueSubclassData(unsigned short D) {
@@ -220,7 +220,7 @@ public:
/// getOperand - Return specified operand.
MDNode *getOperand(unsigned i) const;
-
+
/// getNumOperands - Return the number of NamedMDNode operands.
unsigned getNumOperands() const;
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 4e1ca43..4460aa4 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MODULE_H
-#define LLVM_MODULE_H
+#ifndef LLVM_IR_MODULE_H
+#define LLVM_IR_MODULE_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/Function.h"
@@ -147,30 +147,38 @@ public:
/// An enumeration for describing the size of a pointer on the target machine.
enum PointerSize { AnyPointerSize, Pointer32, Pointer64 };
- /// An enumeration for the supported behaviors of module flags. The following
- /// module flags behavior values are supported:
- ///
- /// Value Behavior
- /// ----- --------
- /// 1 Error
- /// Emits an error if two values disagree.
- ///
- /// 2 Warning
- /// Emits a warning if two values disagree.
- ///
- /// 3 Require
- /// Emits an error when the specified value is not present
- /// or doesn't have the specified value. It is an error for
- /// two (or more) llvm.module.flags with the same ID to have
- /// the Require behavior but different values. There may be
- /// multiple Require flags per ID.
- ///
- /// 4 Override
- /// Uses the specified value if the two values disagree. It
- /// is an error for two (or more) llvm.module.flags with the
- /// same ID to have the Override behavior but different
- /// values.
- enum ModFlagBehavior { Error = 1, Warning = 2, Require = 3, Override = 4 };
+ /// This enumeration defines the supported behaviors of module flags.
+ enum ModFlagBehavior {
+ /// Emits an error if two values disagree, otherwise the resulting value is
+ /// that of the operands.
+ Error = 1,
+
+ /// Emits a warning if two values disagree. The result value will be the
+ /// operand for the flag from the first module being linked.
+ Warning = 2,
+
+ /// Adds a requirement that another module flag be present and have a
+ /// specified value after linking is performed. The value must be a metadata
+ /// pair, where the first element of the pair is the ID of the module flag
+ /// to be restricted, and the second element of the pair is the value the
+ /// module flag should be restricted to. This behavior can be used to
+ /// restrict the allowable results (via triggering of an error) of linking
+ /// IDs with the **Override** behavior.
+ Require = 3,
+
+ /// Uses the specified value, regardless of the behavior or value of the
+ /// other module. If both modules specify **Override**, but the values
+ /// differ, an error will be emitted.
+ Override = 4,
+
+ /// Appends the two values, which are required to be metadata nodes.
+ Append = 5,
+
+ /// Appends the two values, which are required to be metadata
+ /// nodes. However, duplicate entries in the second list are dropped
+ /// during the append operation.
+ AppendUnique = 6
+ };
struct ModuleFlagEntry {
ModFlagBehavior Behavior;
diff --git a/include/llvm/IR/OperandTraits.h b/include/llvm/IR/OperandTraits.h
index 60c8b09..0e4b195 100644
--- a/include/llvm/IR/OperandTraits.h
+++ b/include/llvm/IR/OperandTraits.h
@@ -12,8 +12,8 @@
// the operands in the most efficient manner.
//
-#ifndef LLVM_OPERAND_TRAITS_H
-#define LLVM_OPERAND_TRAITS_H
+#ifndef LLVM_IR_OPERANDTRAITS_H
+#define LLVM_IR_OPERANDTRAITS_H
#include "llvm/IR/User.h"
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 577b41a..13ab72c 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_OPERATOR_H
-#define LLVM_OPERATOR_H
+#ifndef LLVM_IR_OPERATOR_H
+#define LLVM_IR_OPERATOR_H
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -33,8 +33,8 @@ class ConstantExpr;
///
class Operator : public User {
private:
- // Do not implement any of these. The Operator class is intended to be used
- // as a utility, and is never itself instantiated.
+ // The Operator class is intended to be used as a utility, and is never itself
+ // instantiated.
void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION;
void *operator new(size_t s) LLVM_DELETED_FUNCTION;
Operator() LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h
index ec5c88f..561ce01 100644
--- a/include/llvm/IR/SymbolTableListTraits.h
+++ b/include/llvm/IR/SymbolTableListTraits.h
@@ -22,8 +22,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYMBOLTABLELISTTRAITS_H
-#define LLVM_SYMBOLTABLELISTTRAITS_H
+#ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H
+#define LLVM_IR_SYMBOLTABLELISTTRAITS_H
#include "llvm/ADT/ilist.h"
diff --git a/include/llvm/IR/Type.h b/include/llvm/IR/Type.h
index def4575..d89ae24 100644
--- a/include/llvm/IR/Type.h
+++ b/include/llvm/IR/Type.h
@@ -12,11 +12,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TYPE_H
-#define LLVM_TYPE_H
+#ifndef LLVM_IR_TYPE_H
+#define LLVM_IR_TYPE_H
+#include "llvm/ADT/APFloat.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
namespace llvm {
@@ -162,6 +164,18 @@ public:
getTypeID() == PPC_FP128TyID;
}
+ const fltSemantics &getFltSemantics() const {
+ switch (getTypeID()) {
+ case HalfTyID: return APFloat::IEEEhalf;
+ case FloatTyID: return APFloat::IEEEsingle;
+ case DoubleTyID: return APFloat::IEEEdouble;
+ case X86_FP80TyID: return APFloat::x87DoubleExtended;
+ case FP128TyID: return APFloat::IEEEquad;
+ case PPC_FP128TyID: return APFloat::PPCDoubleDouble;
+ default: llvm_unreachable("Invalid floating type");
+ }
+ }
+
/// isX86_MMXTy - Return true if this is X86 MMX.
bool isX86_MMXTy() const { return getTypeID() == X86_MMXTyID; }
diff --git a/include/llvm/IR/TypeBuilder.h b/include/llvm/IR/TypeBuilder.h
index 83ca2a3..80c60a0 100644
--- a/include/llvm/IR/TypeBuilder.h
+++ b/include/llvm/IR/TypeBuilder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TYPEBUILDER_H
-#define LLVM_TYPEBUILDER_H
+#ifndef LLVM_IR_TYPEBUILDER_H
+#define LLVM_IR_TYPEBUILDER_H
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
diff --git a/include/llvm/IR/Use.h b/include/llvm/IR/Use.h
index 8080445..33a69c4 100644
--- a/include/llvm/IR/Use.h
+++ b/include/llvm/IR/Use.h
@@ -22,8 +22,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_USE_H
-#define LLVM_USE_H
+#ifndef LLVM_IR_USE_H
+#define LLVM_IR_USE_H
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
@@ -66,7 +66,6 @@ public:
typedef PointerIntPair<User*, 1, unsigned> UserRef;
private:
- /// Copy ctor - do not implement
Use(const Use &U) LLVM_DELETED_FUNCTION;
/// Destructor - Only for zap()
diff --git a/include/llvm/IR/User.h b/include/llvm/IR/User.h
index 843d20b..a4d0a5d 100644
--- a/include/llvm/IR/User.h
+++ b/include/llvm/IR/User.h
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_USER_H
-#define LLVM_USER_H
+#ifndef LLVM_IR_USER_H
+#define LLVM_IR_USER_H
#include "llvm/IR/Value.h"
#include "llvm/Support/ErrorHandling.h"
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index 85fdfe3..a4f7862 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_VALUE_H
-#define LLVM_VALUE_H
+#ifndef LLVM_IR_VALUE_H
+#define LLVM_IR_VALUE_H
#include "llvm/IR/Use.h"
#include "llvm/Support/Casting.h"
diff --git a/include/llvm/IR/ValueSymbolTable.h b/include/llvm/IR/ValueSymbolTable.h
index 3ea095b..bf1fade 100644
--- a/include/llvm/IR/ValueSymbolTable.h
+++ b/include/llvm/IR/ValueSymbolTable.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_VALUE_SYMBOL_TABLE_H
-#define LLVM_VALUE_SYMBOL_TABLE_H
+#ifndef LLVM_IR_VALUESYMBOLTABLE_H
+#define LLVM_IR_VALUESYMBOLTABLE_H
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/Value.h"
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index 79037f7..e5e21f3 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -31,6 +31,10 @@ void initializeTransformUtils(PassRegistry&);
/// ScalarOpts library.
void initializeScalarOpts(PassRegistry&);
+/// initializeObjCARCOpts - Initialize all passes linked into the ObjCARCOpts
+/// library.
+void initializeObjCARCOpts(PassRegistry&);
+
/// initializeVectorization - Initialize all passes linked into the
/// Vectorize library.
void initializeVectorization(PassRegistry&);
@@ -77,6 +81,8 @@ void initializeBoundsCheckingPass(PassRegistry&);
void initializeBranchFolderPassPass(PassRegistry&);
void initializeBranchProbabilityInfoPass(PassRegistry&);
void initializeBreakCriticalEdgesPass(PassRegistry&);
+void initializeCallGraphPrinterPass(PassRegistry&);
+void initializeCallGraphViewerPass(PassRegistry&);
void initializeCFGOnlyPrinterPass(PassRegistry&);
void initializeCFGOnlyViewerPass(PassRegistry&);
void initializeCFGPrinterPass(PassRegistry&);
@@ -130,6 +136,7 @@ void initializeIPSCCPPass(PassRegistry&);
void initializeIVUsersPass(PassRegistry&);
void initializeIfConverterPass(PassRegistry&);
void initializeIndVarSimplifyPass(PassRegistry&);
+void initializeInlineCostAnalysisPass(PassRegistry&);
void initializeInstCombinerPass(PassRegistry&);
void initializeInstCountPass(PassRegistry&);
void initializeInstNamerPass(PassRegistry&);
@@ -210,6 +217,7 @@ void initializePreVerifierPass(PassRegistry&);
void initializePrintDbgInfoPass(PassRegistry&);
void initializePrintFunctionPassPass(PassRegistry&);
void initializePrintModulePassPass(PassRegistry&);
+void initializePrintBasicBlockPassPass(PassRegistry&);
void initializeProcessImplicitDefsPass(PassRegistry&);
void initializeProfileEstimatorPassPass(PassRegistry&);
void initializeProfileInfoAnalysisGroup(PassRegistry&);
diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllIR.h
index 6039a63..4c1aaca 100644
--- a/include/llvm/LinkAllVMCore.h
+++ b/include/llvm/LinkAllIR.h
@@ -1,4 +1,4 @@
-//===- LinkAllVMCore.h - Reference All VMCore Code --------------*- C++ -*-===//
+//===----- LinkAllIR.h - Reference All VMCore Code --------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_LINKALLVMCORE_H
-#define LLVM_LINKALLVMCORE_H
+#ifndef LLVM_LINKALLIR_H
+#define LLVM_LINKALLIR_H
#include "llvm/Analysis/Verifier.h"
#include "llvm/IR/InlineAsm.h"
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index d29775a..cb727f6 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -16,6 +16,7 @@
#define LLVM_LINKALLPASSES_H
#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/CallPrinter.h"
#include "llvm/Analysis/DomPrinter.h"
#include "llvm/Analysis/FindUsedTypes.h"
#include "llvm/Analysis/IntervalPartition.h"
@@ -30,6 +31,7 @@
#include "llvm/IR/Function.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/ObjCARC.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Transforms/Vectorize.h"
@@ -57,6 +59,8 @@ namespace {
(void) llvm::createBlockPlacementPass();
(void) llvm::createBoundsCheckingPass();
(void) llvm::createBreakCriticalEdgesPass();
+ (void) llvm::createCallGraphPrinterPass();
+ (void) llvm::createCallGraphViewerPass();
(void) llvm::createCFGSimplificationPass();
(void) llvm::createConstantMergePass();
(void) llvm::createConstantPropagationPass();
@@ -147,6 +151,7 @@ namespace {
(void) llvm::createMergeFunctionsPass();
(void) llvm::createPrintModulePass(0);
(void) llvm::createPrintFunctionPass("", 0);
+ (void) llvm::createPrintBasicBlockPass(0);
(void) llvm::createDbgInfoPrinterPass();
(void) llvm::createModuleDebugInfoPrinterPass();
(void) llvm::createPartialInliningPass();
diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h
index 1ebcd6b..a349806 100644
--- a/include/llvm/Linker.h
+++ b/include/llvm/Linker.h
@@ -43,14 +43,6 @@ class Linker {
/// @name Types
/// @{
public:
- /// This type is used to pass the linkage items (libraries and files) to
- /// the LinkItems function. It is composed of string/bool pairs. The string
- /// provides the name of the file or library (as with the -l option). The
- /// bool should be true for libraries and false for files, signifying
- /// "isLibrary".
- /// @brief A list of linkage items
- typedef std::vector<std::pair<std::string,bool> > ItemList;
-
/// This enumeration is used to control various optional features of the
/// linker.
enum ControlFlags {
@@ -153,93 +145,6 @@ class Linker {
/// @brief Set control flags.
void setFlags(unsigned flags) { Flags = flags; }
- /// This method is the main interface to the linker. It can be used to
- /// link a set of linkage items into a module. A linkage item is either a
- /// file name with fully qualified path, or a library for which the Linker's
- /// LibraryPath will be utilized to locate the library. The bool value in
- /// the LinkItemKind should be set to true for libraries. This function
- /// allows linking to preserve the order of specification associated with
- /// the command line, or for other purposes. Each item will be linked in
- /// turn as it occurs in \p Items.
- /// @returns true if an error occurred, false otherwise
- /// @see LinkItemKind
- /// @see getLastError
- bool LinkInItems (
- const ItemList& Items, ///< Set of libraries/files to link in
- ItemList& NativeItems ///< Output list of native files/libs
- );
-
- /// This function links the bitcode \p Files into the composite module.
- /// Note that this does not do any linking of unresolved symbols. The \p
- /// Files are all completely linked into \p HeadModule regardless of
- /// unresolved symbols. This function just loads each bitcode file and
- /// calls LinkInModule on them.
- /// @returns true if an error occurs, false otherwise
- /// @see getLastError
- /// @brief Link in multiple files.
- bool LinkInFiles (
- const std::vector<sys::Path> & Files ///< Files to link in
- );
-
- /// This function links a single bitcode file, \p File, into the composite
- /// module. Note that this does not attempt to resolve symbols. This method
- /// just loads the bitcode file and calls LinkInModule on it. If an error
- /// occurs, the Linker's error string is set.
- /// @returns true if an error occurs, false otherwise
- /// @see getLastError
- /// @brief Link in a single file.
- bool LinkInFile(
- const sys::Path& File, ///< File to link in.
- bool &is_native ///< Indicates if the file is native object file
- );
-
- /// This function provides a way to selectively link in a set of modules,
- /// found in libraries, based on the unresolved symbols in the composite
- /// module. Each item in \p Libraries should be the base name of a library,
- /// as if given with the -l option of a linker tool. The Linker's LibPaths
- /// are searched for the \p Libraries and any found will be linked in with
- /// LinkInArchive. If an error occurs, the Linker's error string is set.
- /// @see LinkInArchive
- /// @see getLastError
- /// @returns true if an error occurs, false otherwise
- /// @brief Link libraries into the module
- bool LinkInLibraries (
- const std::vector<std::string> & Libraries ///< Libraries to link in
- );
-
- /// This function provides a way to selectively link in a set of modules,
- /// found in one library, based on the unresolved symbols in the composite
- /// module.The \p Library should be the base name of a library, as if given
- /// with the -l option of a linker tool. The Linker's LibPaths are searched
- /// for the \p Library and if found, it will be linked in with via the
- /// LinkInArchive method. If an error occurs, the Linker's error string is
- /// set.
- /// @see LinkInArchive
- /// @see getLastError
- /// @returns true if an error occurs, false otherwise
- /// @brief Link one library into the module
- bool LinkInLibrary (
- StringRef Library, ///< The library to link in
- bool& is_native ///< Indicates if lib a native library
- );
-
- /// This function links one bitcode archive, \p Filename, into the module.
- /// The archive is searched to resolve outstanding symbols. Any modules in
- /// the archive that resolve outstanding symbols will be linked in. The
- /// library is searched repeatedly until no more modules that resolve
- /// symbols can be found. If an error occurs, the error string is set.
- /// To speed up this function, ensure the archive has been processed
- /// llvm-ranlib or the S option was given to llvm-ar when the archive was
- /// created. These tools add a symbol table to the archive which makes the
- /// search for undefined symbols much faster.
- /// @see getLastError
- /// @returns true if an error occurs, otherwise false.
- /// @brief Link in one archive.
- bool LinkInArchive(
- const sys::Path& Filename, ///< Filename of the archive to link
- bool& is_native ///< Indicates if archive is a native archive
- );
-
/// This method links the \p Src module into the Linker's Composite module
/// by calling LinkModules. All the other LinkIn* methods eventually
/// result in calling this method to link a Module into the Linker's
@@ -268,21 +173,10 @@ class Linker {
static bool LinkModules(Module* Dest, Module* Src, unsigned Mode,
std::string* ErrorMsg);
- /// This function looks through the Linker's LibPaths to find a library with
- /// the name \p Filename. If the library cannot be found, the returned path
- /// will be empty (i.e. sys::Path::isEmpty() will return true).
- /// @returns A sys::Path to the found library
- /// @brief Find a library from its short name.
- sys::Path FindLib(StringRef Filename);
-
/// @}
/// @name Implementation
/// @{
private:
- /// Read in and parse the bitcode file named by FN and return the
- /// Module it contains (wrapped in an auto_ptr), or 0 if an error occurs.
- std::auto_ptr<Module> LoadObject(const sys::Path& FN);
-
bool warning(StringRef message);
bool error(StringRef message);
void verbose(StringRef message);
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index 38cf060..28256b3 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TARGET_ASM_INFO_H
-#define LLVM_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFO_H
+#define LLVM_MC_MCASMINFO_H
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MachineLocation.h"
@@ -48,6 +48,11 @@ namespace llvm {
/// Default is 4.
unsigned PointerSize;
+ /// CalleeSaveStackSlotSize - Size of the stack slot reserved for
+ /// callee-saved registers, in bytes.
+ /// Default is same as pointer size.
+ unsigned CalleeSaveStackSlotSize;
+
/// IsLittleEndian - True if target is little endian.
/// Default is true.
bool IsLittleEndian;
@@ -343,7 +348,13 @@ namespace llvm {
return PointerSize;
}
- /// islittleendian - True if the target is little endian.
+ /// getCalleeSaveStackSlotSize - Get the callee-saved register stack slot
+ /// size in bytes.
+ unsigned getCalleeSaveStackSlotSize() const {
+ return CalleeSaveStackSlotSize;
+ }
+
+ /// isLittleEndian - True if the target is little endian.
bool isLittleEndian() const {
return IsLittleEndian;
}
diff --git a/include/llvm/MC/MCAsmInfoCOFF.h b/include/llvm/MC/MCAsmInfoCOFF.h
index 0ff3e12..7286151 100644
--- a/include/llvm/MC/MCAsmInfoCOFF.h
+++ b/include/llvm/MC/MCAsmInfoCOFF.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_COFF_TARGET_ASM_INFO_H
-#define LLVM_COFF_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFOCOFF_H
+#define LLVM_MC_MCASMINFOCOFF_H
#include "llvm/MC/MCAsmInfo.h"
@@ -33,4 +33,4 @@ namespace llvm {
}
-#endif // LLVM_COFF_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFOCOFF_H
diff --git a/include/llvm/MC/MCAsmInfoDarwin.h b/include/llvm/MC/MCAsmInfoDarwin.h
index af552de..3d249f9 100644
--- a/include/llvm/MC/MCAsmInfoDarwin.h
+++ b/include/llvm/MC/MCAsmInfoDarwin.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_DARWIN_TARGET_ASM_INFO_H
-#define LLVM_DARWIN_TARGET_ASM_INFO_H
+#ifndef LLVM_MC_MCASMINFODARWIN_H
+#define LLVM_MC_MCASMINFODARWIN_H
#include "llvm/MC/MCAsmInfo.h"
@@ -26,4 +26,4 @@ namespace llvm {
}
-#endif // LLVM_DARWIN_TARGET_ASM_INFO_H
+#endif // LLVM_MC_MCASMINFODARWIN_H
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index 8cb4601..3058b7b 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -60,9 +60,10 @@ public:
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
- /// \brief Invalidate the fragments after F because it has been resized.
- /// The fragment's size should have already been updated.
- void invalidateFragmentsAfter(MCFragment *F);
+ /// \brief Invalidate the fragments starting with F because it has been
+ /// resized. The fragment's size should have already been updated, but
+ /// its bundle padding will be recomputed.
+ void invalidateFragmentsFrom(MCFragment *F);
/// \brief Perform layout for a single fragment, assuming that the previous
/// fragment has already been laid out correctly, and the parent section has
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 40766b4..6aeb8b8 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -52,6 +52,7 @@ public:
enum FragmentType {
FT_Align,
FT_Data,
+ FT_CompactEncodedInst,
FT_Fill,
FT_Relaxable,
FT_Org,
@@ -113,6 +114,7 @@ public:
/// \brief Should this fragment be placed at the end of an aligned bundle?
virtual bool alignToBundleEnd() const { return false; }
+ virtual void setAlignToBundleEnd(bool V) { }
/// \brief Get the padding size that must be inserted before this fragment.
/// Used for bundling. By default, no padding is inserted.
@@ -131,6 +133,9 @@ public:
void dump();
};
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data.
+///
class MCEncodedFragment : public MCFragment {
virtual void anchor();
@@ -142,20 +147,9 @@ public:
}
virtual ~MCEncodedFragment();
- typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
- typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
-
virtual SmallVectorImpl<char> &getContents() = 0;
virtual const SmallVectorImpl<char> &getContents() const = 0;
- virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
- virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
-
- virtual fixup_iterator fixup_begin() = 0;
- virtual const_fixup_iterator fixup_begin() const = 0;
- virtual fixup_iterator fixup_end() = 0;
- virtual const_fixup_iterator fixup_end() const = 0;
-
virtual uint8_t getBundlePadding() const {
return BundlePadding;
}
@@ -166,13 +160,52 @@ public:
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
+ switch (Kind) {
+ default:
+ return false;
+ case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
+ case MCFragment::FT_Data:
+ return true;
+ }
+ }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+class MCEncodedFragmentWithFixups : public MCEncodedFragment {
+ virtual void anchor();
+
+public:
+ MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+ MCSectionData *SD = 0)
+ : MCEncodedFragment(FType, SD)
+ {
+ }
+
+ virtual ~MCEncodedFragmentWithFixups();
+
+ typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
+ typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
+
+ virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
+ virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
+
+ virtual fixup_iterator fixup_begin() = 0;
+ virtual const_fixup_iterator fixup_begin() const = 0;
+ virtual fixup_iterator fixup_end() = 0;
+ virtual const_fixup_iterator fixup_end() const = 0;
+
+ static bool classof(const MCFragment *F) {
+ MCFragment::FragmentType Kind = F->getKind();
return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data;
}
};
/// Fragment for data and encoded instructions.
///
-class MCDataFragment : public MCEncodedFragment {
+class MCDataFragment : public MCEncodedFragmentWithFixups {
virtual void anchor();
/// \brief Does this fragment contain encoded instructions anywhere in it?
@@ -187,7 +220,7 @@ class MCDataFragment : public MCEncodedFragment {
SmallVector<MCFixup, 4> Fixups;
public:
MCDataFragment(MCSectionData *SD = 0)
- : MCEncodedFragment(FT_Data, SD),
+ : MCEncodedFragmentWithFixups(FT_Data, SD),
HasInstructions(false), AlignToBundleEnd(false)
{
}
@@ -220,10 +253,43 @@ public:
}
};
+/// This is a compact (memory-size-wise) fragment for holding an encoded
+/// instruction (non-relaxable) that has no fixups registered. When applicable,
+/// it can be used instead of MCDataFragment and lead to lower memory
+/// consumption.
+///
+class MCCompactEncodedInstFragment : public MCEncodedFragment {
+ virtual void anchor();
+
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ SmallVector<char, 4> Contents;
+public:
+ MCCompactEncodedInstFragment(MCSectionData *SD = 0)
+ : MCEncodedFragment(FT_CompactEncodedInst, SD), AlignToBundleEnd(false)
+ {
+ }
+
+ virtual bool hasInstructions() const {
+ return true;
+ }
+
+ virtual SmallVectorImpl<char> &getContents() { return Contents; }
+ virtual const SmallVectorImpl<char> &getContents() const { return Contents; }
+
+ virtual bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ virtual void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
+
+ static bool classof(const MCFragment *F) {
+ return F->getKind() == MCFragment::FT_CompactEncodedInst;
+ }
+};
+
/// A relaxable fragment holds on to its MCInst, since it may need to be
/// relaxed during the assembler layout and relaxation stage.
///
-class MCRelaxableFragment : public MCEncodedFragment {
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
virtual void anchor();
/// Inst - The instruction this is a fragment for.
@@ -237,7 +303,7 @@ class MCRelaxableFragment : public MCEncodedFragment {
public:
MCRelaxableFragment(const MCInst &_Inst, MCSectionData *SD = 0)
- : MCEncodedFragment(FT_Relaxable, SD), Inst(_Inst) {
+ : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst) {
}
virtual SmallVectorImpl<char> &getContents() { return Contents; }
@@ -791,6 +857,10 @@ private:
std::vector<IndirectSymbolData> IndirectSymbols;
std::vector<DataRegionData> DataRegions;
+
+ /// The list of linker options to propagate into the object file.
+ std::vector<std::vector<std::string> > LinkerOptions;
+
/// The set of function symbols for which a .thumb_func directive has
/// been seen.
//
@@ -809,6 +879,12 @@ private:
unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
+ /// ELF specific e_header flags
+ // It would be good if there were an MCELFAssembler class to hold this.
+ // ELF header flags are used both by the integrated and standalone assemblers.
+ // Access to the flags is necessary in cases where assembler directives affect
+ // which flags to be set.
+ unsigned ELFHeaderEFlags;
private:
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
@@ -886,6 +962,10 @@ public:
/// Flag a function symbol as the target of a .thumb_func directive.
void setIsThumbFunc(const MCSymbol *Func) { ThumbFuncs.insert(Func); }
+ /// ELF e_header flags
+ unsigned getELFHeaderEFlags() const {return ELFHeaderEFlags;}
+ void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags;}
+
public:
/// Construct a new assembler instance.
///
@@ -1004,6 +1084,14 @@ public:
size_t indirect_symbol_size() const { return IndirectSymbols.size(); }
/// @}
+ /// @name Linker Option List Access
+ /// @{
+
+ std::vector<std::vector<std::string> > &getLinkerOptions() {
+ return LinkerOptions;
+ }
+
+ /// @}
/// @name Data Region List Access
/// @{
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index e92d3b9..20d52eb 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -129,6 +129,10 @@ namespace llvm {
/// non-empty.
StringRef DwarfDebugFlags;
+ /// The string to embed in as the dwarf AT_producer for the compile unit, if
+ /// non-empty.
+ StringRef DwarfDebugProducer;
+
/// Honor temporary labels, this is useful for debugging semantic
/// differences between temporary and non-temporary labels (primarily on
/// Darwin).
@@ -140,6 +144,10 @@ namespace llvm {
/// We need a deterministic iteration order, so we remember the order
/// the elements were added.
std::vector<const MCSection *> MCLineSectionOrder;
+ /// The Compile Unit ID that we are currently processing.
+ unsigned DwarfCompileUnitID;
+ /// The line table start symbol for each Compile Unit.
+ DenseMap<unsigned, MCSymbol *> MCLineTableSymbols;
void *MachOUniquingMap, *ELFUniquingMap, *COFFUniquingMap;
@@ -300,6 +308,25 @@ namespace llvm {
MCLineSections[Sec] = Line;
MCLineSectionOrder.push_back(Sec);
}
+ unsigned getDwarfCompileUnitID() {
+ return DwarfCompileUnitID;
+ }
+ void setDwarfCompileUnitID(unsigned CUIndex) {
+ DwarfCompileUnitID = CUIndex;
+ }
+ const DenseMap<unsigned, MCSymbol *> &getMCLineTableSymbols() const {
+ return MCLineTableSymbols;
+ }
+ MCSymbol *getMCLineTableSymbol(unsigned ID) const {
+ DenseMap<unsigned, MCSymbol *>::const_iterator CIter =
+ MCLineTableSymbols.find(ID);
+ if (CIter == MCLineTableSymbols.end())
+ return NULL;
+ return CIter->second;
+ }
+ void setMCLineTableSymbol(MCSymbol *Sym, unsigned ID) {
+ MCLineTableSymbols[ID] = Sym;
+ }
/// setCurrentDwarfLoc - saves the information from the currently parsed
/// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
@@ -346,6 +373,9 @@ namespace llvm {
void setDwarfDebugFlags(StringRef S) { DwarfDebugFlags = S; }
StringRef getDwarfDebugFlags() { return DwarfDebugFlags; }
+ void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; }
+ StringRef getDwarfDebugProducer() { return DwarfDebugProducer; }
+
/// @}
char *getSecureLogFile() { return SecureLogFile; }
diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h
index 1b6beb2..36fbcb0 100644
--- a/include/llvm/MC/MCDisassembler.h
+++ b/include/llvm/MC/MCDisassembler.h
@@ -6,8 +6,8 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-#ifndef MCDISASSEMBLER_H
-#define MCDISASSEMBLER_H
+#ifndef LLVM_MC_MCDISASSEMBLER_H
+#define LLVM_MC_MCDISASSEMBLER_H
#include "llvm-c/Disassembler.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h
index 3160b61..1a392e8 100644
--- a/include/llvm/MC/MCDwarf.h
+++ b/include/llvm/MC/MCDwarf.h
@@ -19,6 +19,7 @@
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Support/raw_ostream.h"
+#include <map>
#include <vector>
namespace llvm {
@@ -186,29 +187,43 @@ namespace llvm {
MCLineSection() {}
// addLineEntry - adds an entry to this MCLineSection's line entries
- void addLineEntry(const MCLineEntry &LineEntry) {
- MCLineEntries.push_back(LineEntry);
+ void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID) {
+ MCLineDivisions[CUID].push_back(LineEntry);
}
typedef std::vector<MCLineEntry> MCLineEntryCollection;
typedef MCLineEntryCollection::iterator iterator;
typedef MCLineEntryCollection::const_iterator const_iterator;
+ typedef std::map<unsigned, MCLineEntryCollection> MCLineDivisionMap;
private:
- MCLineEntryCollection MCLineEntries;
+ // A collection of MCLineEntry for each Compile Unit ID.
+ MCLineDivisionMap MCLineDivisions;
public:
- const MCLineEntryCollection *getMCLineEntries() const {
- return &MCLineEntries;
+ // Returns whether MCLineSection contains entries for a given Compile
+ // Unit ID.
+ bool containEntriesForID(unsigned CUID) const {
+ return MCLineDivisions.count(CUID);
+ }
+ // Returns the collection of MCLineEntry for a given Compile Unit ID.
+ const MCLineEntryCollection &getMCLineEntries(unsigned CUID) const {
+ MCLineDivisionMap::const_iterator CIter = MCLineDivisions.find(CUID);
+ assert(CIter != MCLineDivisions.end());
+ return CIter->second;
}
};
class MCDwarfFileTable {
public:
//
- // This emits the Dwarf file and the line tables.
+ // This emits the Dwarf file and the line tables for all Compile Units.
//
static const MCSymbol *Emit(MCStreamer *MCOS);
+ //
+ // This emits the Dwarf file and the line tables for a given Compile Unit.
+ //
+ static const MCSymbol *EmitCU(MCStreamer *MCOS, unsigned ID);
};
class MCDwarfLineAddr {
diff --git a/include/llvm/MC/MCELF.h b/include/llvm/MC/MCELF.h
index e08f1e6..7e59911 100644
--- a/include/llvm/MC/MCELF.h
+++ b/include/llvm/MC/MCELF.h
@@ -28,6 +28,8 @@ class MCELF {
static unsigned GetType(const MCSymbolData &SD);
static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
static unsigned GetVisibility(MCSymbolData &SD);
+ static void setOther(MCSymbolData &SD, unsigned Other);
+ static unsigned getOther(MCSymbolData &SD);
};
}
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 38cdc72..a59776d 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -79,7 +79,6 @@ public:
virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
bool IsPCRel, bool IsRelocWithSymbol,
int64_t Addend) const = 0;
- virtual unsigned getEFlags() const;
virtual const MCSymbol *ExplicitRelSym(const MCAssembler &Asm,
const MCValue &Target,
const MCFragment &F,
diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h
index ab20ee8..6fb2d22 100644
--- a/include/llvm/MC/MCELFStreamer.h
+++ b/include/llvm/MC/MCELFStreamer.h
@@ -28,15 +28,20 @@ class MCSymbolData;
class raw_ostream;
class MCELFStreamer : public MCObjectStreamer {
-public:
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
+protected:
+ MCELFStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *Emitter)
- : MCObjectStreamer(Context, TAB, OS, Emitter) {}
+ : MCObjectStreamer(Kind, Context, TAB, OS, Emitter) {}
+
+public:
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter)
+ : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter) {}
- MCELFStreamer(MCContext &Context, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *Emitter,
- MCAssembler *Assembler)
- : MCObjectStreamer(Context, TAB, OS, Emitter, Assembler) {}
+ MCELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, MCAssembler *Assembler)
+ : MCObjectStreamer(SK_ELFStreamer, Context, TAB, OS, Emitter,
+ Assembler) {}
virtual ~MCELFStreamer();
@@ -44,6 +49,7 @@ public:
/// @{
virtual void InitSections();
+ virtual void InitToTextSection();
virtual void ChangeSection(const MCSection *Section);
virtual void EmitLabel(MCSymbol *Symbol);
virtual void EmitDebugLabel(MCSymbol *Symbol);
@@ -59,6 +65,8 @@ public:
virtual void EmitCOFFSymbolType(int Type);
virtual void EndCOFFSymbolDef();
+ virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
@@ -80,6 +88,10 @@ public:
virtual void FinishImpl();
/// @}
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() == SK_ELFStreamer || S->getKind() == SK_ARMELFStreamer;
+ }
+
private:
virtual void EmitInstToFragment(const MCInst &Inst);
virtual void EmitInstToData(const MCInst &Inst);
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 475981f..b5bfed1 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -472,6 +472,8 @@ public:
virtual void AddValueSymbols(MCAssembler *) const = 0;
virtual const MCSection *FindAssociatedSection() const = 0;
+ virtual void fixELFSymbolsInTLSFixups(MCAssembler &) const = 0;
+
static bool classof(const MCExpr *E) {
return E->getKind() == MCExpr::Target;
}
diff --git a/include/llvm/MC/MCFixedLenDisassembler.h b/include/llvm/MC/MCFixedLenDisassembler.h
index 22b3c32..ad99943 100644
--- a/include/llvm/MC/MCFixedLenDisassembler.h
+++ b/include/llvm/MC/MCFixedLenDisassembler.h
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
// Fixed length disassembler decoder state machine driver.
//===----------------------------------------------------------------------===//
-#ifndef MCFIXEDLENDISASSEMBLER_H
-#define MCFIXEDLENDISASSEMBLER_H
+#ifndef LLVM_MC_MCFIXEDLENDISASSEMBLER_H
+#define LLVM_MC_MCFIXEDLENDISASSEMBLER_H
namespace llvm {
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index 3cd278e..3c9a588 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -196,6 +196,8 @@ public:
void WriteLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
uint32_t DataSize);
+ void WriteLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
+
// 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
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index c8444fd..c8d7484 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -97,6 +97,9 @@ protected:
const MCSection *DwarfARangesSection;
const MCSection *DwarfRangesSection;
const MCSection *DwarfMacroInfoSection;
+ // The pubnames section is no longer generated by default. The generation
+ // can be enabled by a compiler flag.
+ const MCSection *DwarfPubNamesSection;
// DWARF5 Experimental Debug Info Sections
/// DwarfAccelNamesSection, DwarfAccelObjCSection,
@@ -115,6 +118,7 @@ protected:
const MCSection *DwarfLineDWOSection;
const MCSection *DwarfLocDWOSection;
const MCSection *DwarfStrOffDWOSection;
+ const MCSection *DwarfAddrSection;
// Extra TLS Variable Data section. If the target needs to put additional
// information for a TLS variable, it'll go here.
@@ -208,6 +212,7 @@ public:
const MCSection *getDwarfInfoSection() const { return DwarfInfoSection; }
const MCSection *getDwarfLineSection() const { return DwarfLineSection; }
const MCSection *getDwarfFrameSection() const { return DwarfFrameSection; }
+ const MCSection *getDwarfPubNamesSection() const{return DwarfPubNamesSection;}
const MCSection *getDwarfPubTypesSection() const{return DwarfPubTypesSection;}
const MCSection *getDwarfDebugInlineSection() const {
return DwarfDebugInlineSection;
@@ -251,6 +256,9 @@ public:
const MCSection *getDwarfStrOffDWOSection() const {
return DwarfStrOffDWOSection;
}
+ const MCSection *getDwarfAddrSection() const {
+ return DwarfAddrSection;
+ }
const MCSection *getTLSExtraDataSection() const {
return TLSExtraDataSection;
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 0ece092..f06c49f 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -38,9 +38,9 @@ class MCObjectStreamer : public MCStreamer {
virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame);
protected:
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB,
+ MCObjectStreamer(StreamerKind Kind, MCContext &Context, MCAsmBackend &TAB,
raw_ostream &_OS, MCCodeEmitter *_Emitter,
MCAssembler *_Assembler);
~MCObjectStreamer();
@@ -86,7 +86,7 @@ public:
virtual void EmitBundleAlignMode(unsigned AlignPow2);
virtual void EmitBundleLock(bool AlignToEnd);
virtual void EmitBundleUnlock();
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0);
virtual void EmitValueToAlignment(unsigned ByteAlignment,
int64_t Value = 0,
unsigned ValueSize = 1,
@@ -103,10 +103,14 @@ public:
virtual void EmitGPRel32Value(const MCExpr *Value);
virtual void EmitGPRel64Value(const MCExpr *Value);
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace);
+ unsigned AddrSpace = 0);
virtual void FinishImpl();
/// @}
+
+ static bool classof(const MCStreamer *S) {
+ return S->getKind() >= SK_ELFStreamer && S->getKind() <= SK_WinCOFFStreamer;
+ }
};
} // end namespace llvm
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 9d5c1a7..4939a3f 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -10,6 +10,7 @@
#ifndef LLVM_MC_MCOBJECTWRITER_H
#define LLVM_MC_MCOBJECTWRITER_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/raw_ostream.h"
@@ -61,15 +62,15 @@ public:
/// @name High-Level API
/// @{
- /// Perform any late binding of symbols (for example, to assign symbol indices
- /// for use when generating relocations).
+ /// \brief Perform any late binding of symbols (for example, to assign symbol
+ /// indices for use when generating relocations).
///
/// This routine is called by the assembler after layout and relaxation is
/// complete.
virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
const MCAsmLayout &Layout) = 0;
- /// Record a relocation entry.
+ /// \brief Record a relocation entry.
///
/// This routine is called by the assembler after layout and relaxation, and
/// post layout binding. The implementation is responsible for storing
@@ -99,8 +100,7 @@ public:
bool InSet,
bool IsPCRel) const;
-
- /// Write the object file.
+ /// \brief Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
/// complete, fixups have been evaluated and applied, and relocations
@@ -176,7 +176,7 @@ public:
OS << StringRef(Zeros, N % 16);
}
- void WriteBytes(SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
+ void WriteBytes(const SmallVectorImpl<char> &ByteVec, unsigned ZeroFillSize = 0) {
WriteBytes(StringRef(ByteVec.data(), ByteVec.size()), ZeroFillSize);
}
diff --git a/include/llvm/MC/MCParser/AsmCond.h b/include/llvm/MC/MCParser/AsmCond.h
index 92a115e..a918b56 100644
--- a/include/llvm/MC/MCParser/AsmCond.h
+++ b/include/llvm/MC/MCParser/AsmCond.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ASMCOND_H
-#define ASMCOND_H
+#ifndef LLVM_MC_MCPARSER_ASMCOND_H
+#define LLVM_MC_MCPARSER_ASMCOND_H
namespace llvm {
diff --git a/include/llvm/MC/MCParser/AsmLexer.h b/include/llvm/MC/MCParser/AsmLexer.h
index e102dfb..0dab314 100644
--- a/include/llvm/MC/MCParser/AsmLexer.h
+++ b/include/llvm/MC/MCParser/AsmLexer.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef ASMLEXER_H
-#define ASMLEXER_H
+#ifndef LLVM_MC_MCPARSER_ASMLEXER_H
+#define LLVM_MC_MCPARSER_ASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 37a69e2..53b380f 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMLEXER_H
-#define LLVM_MC_MCASMLEXER_H
+#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
+#define LLVM_MC_MCPARSER_MCASMLEXER_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/MC/MCParser/MCAsmParser.h b/include/llvm/MC/MCParser/MCAsmParser.h
index b9490fa..d7e3902 100644
--- a/include/llvm/MC/MCParser/MCAsmParser.h
+++ b/include/llvm/MC/MCParser/MCAsmParser.h
@@ -7,14 +7,15 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMPARSER_H
-#define LLVM_MC_MCASMPARSER_H
+#ifndef LLVM_MC_MCPARSER_MCASMPARSER_H
+#define LLVM_MC_MCPARSER_MCASMPARSER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
-class AsmToken;
class MCAsmInfo;
class MCAsmLexer;
class MCAsmParserExtension;
@@ -22,13 +23,11 @@ class MCContext;
class MCExpr;
class MCInstPrinter;
class MCInstrInfo;
-class MCParsedAsmOperand;
class MCStreamer;
class MCTargetAsmParser;
class SMLoc;
class SMRange;
class SourceMgr;
-class StringRef;
class Twine;
/// MCAsmParserSemaCallback - Generic Sema callback for assembly parser.
@@ -36,16 +35,21 @@ class MCAsmParserSemaCallback {
public:
virtual ~MCAsmParserSemaCallback();
virtual void *LookupInlineAsmIdentifier(StringRef Name, void *Loc,
- unsigned &Size) = 0;
+ unsigned &Length, unsigned &Size,
+ unsigned &Type, bool &IsVarDecl) = 0;
+
virtual bool LookupInlineAsmField(StringRef Base, StringRef Member,
unsigned &Offset) = 0;
};
+
/// MCAsmParser - Generic assembler parser interface, for use by target specific
/// assembly parsers.
class MCAsmParser {
public:
typedef bool (*DirectiveHandler)(MCAsmParserExtension*, StringRef, SMLoc);
+ typedef std::pair<MCAsmParserExtension*, DirectiveHandler>
+ ExtensionDirectiveHandler;
private:
MCAsmParser(const MCAsmParser &) LLVM_DELETED_FUNCTION;
@@ -61,9 +65,8 @@ protected: // Can only create subclasses.
public:
virtual ~MCAsmParser();
- virtual void AddDirectiveHandler(MCAsmParserExtension *Object,
- StringRef Directive,
- DirectiveHandler Handler) = 0;
+ virtual void addDirectiveHandler(StringRef Directive,
+ ExtensionDirectiveHandler Handler) = 0;
virtual SourceMgr &getSourceManager() = 0;
@@ -89,8 +92,8 @@ public:
virtual void setParsingInlineAsm(bool V) = 0;
virtual bool isParsingInlineAsm() = 0;
- /// ParseMSInlineAsm - Parse ms-style inline assembly.
- virtual bool ParseMSInlineAsm(void *AsmLoc, std::string &AsmString,
+ /// parseMSInlineAsm - Parse ms-style inline assembly.
+ virtual bool parseMSInlineAsm(void *AsmLoc, std::string &AsmString,
unsigned &NumOutputs, unsigned &NumInputs,
SmallVectorImpl<std::pair<void *, bool> > &OpDecls,
SmallVectorImpl<std::string> &Constraints,
@@ -123,42 +126,50 @@ public:
bool TokError(const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>());
- /// ParseIdentifier - Parse an identifier or string (as a quoted identifier)
+ /// parseIdentifier - Parse an identifier or string (as a quoted identifier)
/// and set \p Res to the identifier contents.
- virtual bool ParseIdentifier(StringRef &Res) = 0;
+ virtual bool parseIdentifier(StringRef &Res) = 0;
/// \brief Parse up to the end of statement and return the contents from the
/// current token until the end of the statement; the current token on exit
/// will be either the EndOfStatement or EOF.
- virtual StringRef ParseStringToEndOfStatement() = 0;
+ virtual StringRef parseStringToEndOfStatement() = 0;
- /// EatToEndOfStatement - Skip to the end of the current statement, for error
+ /// parseEscapedString - Parse the current token as a string which may include
+ /// escaped characters and return the string contents.
+ virtual bool parseEscapedString(std::string &Data) = 0;
+
+ /// eatToEndOfStatement - Skip to the end of the current statement, for error
/// recovery.
- virtual void EatToEndOfStatement() = 0;
+ virtual void eatToEndOfStatement() = 0;
- /// ParseExpression - Parse an arbitrary expression.
+ /// parseExpression - Parse an arbitrary expression.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- bool ParseExpression(const MCExpr *&Res);
+ virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ bool parseExpression(const MCExpr *&Res);
- /// ParseParenExpression - Parse an arbitrary expression, assuming that an
+ /// parseParenExpression - Parse an arbitrary expression, assuming that an
/// initial '(' has already been consumed.
///
/// @param Res - The value of the expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
+ virtual bool parseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) = 0;
- /// ParseAbsoluteExpression - Parse an expression which must evaluate to an
+ /// parseAbsoluteExpression - Parse an expression which must evaluate to an
/// absolute value.
///
/// @param Res - The value of the absolute expression. The result is undefined
/// on error.
/// @result - False on success.
- virtual bool ParseAbsoluteExpression(int64_t &Res) = 0;
+ virtual bool parseAbsoluteExpression(int64_t &Res) = 0;
+
+ /// checkForValidSection - Ensure that we have a valid section set in the
+ /// streamer. Otherwise, report an error and switch to .text.
+ virtual void checkForValidSection() = 0;
};
/// \brief Create an MCAsmParser instance.
diff --git a/include/llvm/MC/MCParser/MCAsmParserExtension.h b/include/llvm/MC/MCParser/MCAsmParserExtension.h
index 84b33b5..2eda3a9 100644
--- a/include/llvm/MC/MCParser/MCAsmParserExtension.h
+++ b/include/llvm/MC/MCParser/MCAsmParserExtension.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMPARSEREXTENSION_H
-#define LLVM_MC_MCASMPARSEREXTENSION_H
+#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
+#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
diff --git a/include/llvm/MC/MCParser/MCParsedAsmOperand.h b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
index 60e7887..c78cd97 100644
--- a/include/llvm/MC/MCParser/MCParsedAsmOperand.h
+++ b/include/llvm/MC/MCParser/MCParsedAsmOperand.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCASMOPERAND_H
-#define LLVM_MC_MCASMOPERAND_H
+#ifndef LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
+#define LLVM_MC_MCPARSER_MCPARSEDASMOPERAND_H
namespace llvm {
class SMLoc;
@@ -70,6 +70,10 @@ public:
/// care of the rewrites. Only valid when parsing MS-style inline assembly.
virtual bool needAsmRewrite() const { return true; }
+ /// needAddressOf - Do we need to emit code to get the address of the
+ /// variable/label? Only valid when parsing MS-style inline assembly.
+ virtual bool needAddressOf() const { return false; }
+
/// isOffsetOf - Do we need to emit code to get the offset of the variable,
/// rather then the value of the variable? Only valid when parsing MS-style
/// inline assembly.
diff --git a/include/llvm/MC/MCSchedule.h b/include/llvm/MC/MCSchedule.h
index 0c71ee5..defa299 100644
--- a/include/llvm/MC/MCSchedule.h
+++ b/include/llvm/MC/MCSchedule.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_MC_MCSCHEDMODEL_H
-#define LLVM_MC_MCSCHEDMODEL_H
+#ifndef LLVM_MC_MCSCHEDULE_H
+#define LLVM_MC_MCSCHEDULE_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
@@ -155,7 +155,7 @@ public:
// Optional InstrItinerary OperandCycles provides expected latency.
// TODO: can't yet specify both min and expected latency per operand.
int MinLatency;
- static const unsigned DefaultMinLatency = -1;
+ static const int DefaultMinLatency = -1;
// LoadLatency is the expected latency of load instructions.
//
@@ -172,6 +172,16 @@ public:
unsigned HighLatency;
static const unsigned DefaultHighLatency = 10;
+ // ILPWindow is the number of cycles that the scheduler effectively ignores
+ // before attempting to hide latency. This should be zero for in-order cpus to
+ // always hide expected latency. For out-of-order cpus, it may be tweaked as
+ // desired to roughly approximate instruction buffers. The actual threshold is
+ // not very important for an OOO processor, as long as it isn't too high. A
+ // nonzero value helps avoid rescheduling to hide latency when its is fairly
+ // obviously useless and makes register pressure heuristics more effective.
+ unsigned ILPWindow;
+ static const unsigned DefaultILPWindow = 0;
+
// MispredictPenalty is the typical number of extra cycles the processor
// takes to recover from a branch misprediction.
unsigned MispredictPenalty;
@@ -196,6 +206,7 @@ public:
MinLatency(DefaultMinLatency),
LoadLatency(DefaultLoadLatency),
HighLatency(DefaultHighLatency),
+ ILPWindow(DefaultILPWindow),
MispredictPenalty(DefaultMispredictPenalty),
ProcID(0), ProcResourceTable(0), SchedClassTable(0),
NumProcResourceKinds(0), NumSchedClasses(0),
@@ -205,12 +216,12 @@ public:
}
// Table-gen driven ctor.
- MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned mp,
- unsigned pi, const MCProcResourceDesc *pr,
+ MCSchedModel(unsigned iw, int ml, unsigned ll, unsigned hl, unsigned ilp,
+ unsigned mp, unsigned pi, const MCProcResourceDesc *pr,
const MCSchedClassDesc *sc, unsigned npr, unsigned nsc,
const InstrItinerary *ii):
IssueWidth(iw), MinLatency(ml), LoadLatency(ll), HighLatency(hl),
- MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
+ ILPWindow(ilp), MispredictPenalty(mp), ProcID(pi), ProcResourceTable(pr),
SchedClassTable(sc), NumProcResourceKinds(npr), NumSchedClasses(nsc),
InstrItineraries(ii) {}
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 05a33c5..d247066 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -16,10 +16,12 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/DataTypes.h"
+#include <string>
namespace llvm {
class MCAsmBackend;
@@ -45,6 +47,23 @@ namespace llvm {
/// a .s file, and implementations that write out .o files of various formats.
///
class MCStreamer {
+ public:
+ enum StreamerKind {
+ SK_AsmStreamer,
+ SK_NullStreamer,
+ SK_RecordStreamer,
+
+ // MCObjectStreamer subclasses.
+ SK_ELFStreamer,
+ SK_ARMELFStreamer,
+ SK_MachOStreamer,
+ SK_PureStreamer,
+ SK_MipsELFStreamer,
+ SK_WinCOFFStreamer
+ };
+
+ private:
+ const StreamerKind Kind;
MCContext &Context;
MCStreamer(const MCStreamer&) LLVM_DELETED_FUNCTION;
@@ -73,7 +92,7 @@ namespace llvm {
bool AutoInitSections;
protected:
- MCStreamer(MCContext &Ctx);
+ MCStreamer(StreamerKind Kind, MCContext &Ctx);
const MCExpr *BuildSymbolDiff(MCContext &Context, const MCSymbol *A,
const MCSymbol *B);
@@ -92,6 +111,8 @@ namespace llvm {
public:
virtual ~MCStreamer();
+ StreamerKind getKind() const { return Kind; }
+
/// State management
///
virtual void reset();
@@ -234,6 +255,9 @@ namespace llvm {
/// InitSections - Create the default sections and set the initial one.
virtual void InitSections() = 0;
+ /// InitToTextSection - Create a text section and switch the streamer to it.
+ virtual void InitToTextSection() = 0;
+
/// EmitLabel - Emit a label for @p Symbol into the current section.
///
/// This corresponds to an assembler statement such as:
@@ -252,6 +276,10 @@ namespace llvm {
/// EmitAssemblerFlag - Note in the output the specified @p Flag.
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) = 0;
+ /// EmitLinkerOptions - Emit the given list @p Options of strings as linker
+ /// options into the output.
+ virtual void EmitLinkerOptions(ArrayRef<std::string> Kind) {}
+
/// EmitDataRegion - Note in the output the specified region @p Kind.
virtual void EmitDataRegion(MCDataRegionType Kind) {}
@@ -259,6 +287,9 @@ namespace llvm {
/// a Thumb mode function (ARM target only).
virtual void EmitThumbFunc(MCSymbol *Func) = 0;
+ /// getOrCreateSymbolData - Get symbol data for given symbol.
+ virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
/// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
///
/// This corresponds to an assembler statement such as:
@@ -366,7 +397,7 @@ namespace llvm {
///
/// This is used to implement assembler directives such as .byte, .ascii,
/// etc.
- virtual void EmitBytes(StringRef Data, unsigned AddrSpace) = 0;
+ virtual void EmitBytes(StringRef Data, unsigned AddrSpace = 0) = 0;
/// EmitValue - Emit the expression @p Value into the output as a native
/// integer of the given @p Size bytes.
@@ -400,8 +431,8 @@ namespace llvm {
/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
- void EmitULEB128IntValue(uint64_t Value, unsigned AddrSpace = 0,
- unsigned Padding = 0);
+ void EmitULEB128IntValue(uint64_t Value, unsigned Padding = 0,
+ unsigned AddrSpace = 0);
/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the
/// client having to pass in a MCExpr for constant integers.
@@ -429,11 +460,11 @@ namespace llvm {
/// EmitFill - Emit NumBytes bytes worth of the value specified by
/// FillValue. This implements directives such as '.space'.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue,
- unsigned AddrSpace);
+ unsigned AddrSpace = 0);
/// EmitZeros - Emit NumBytes worth of zeros. This is a convenience
/// function that just wraps EmitFill.
- void EmitZeros(uint64_t NumBytes, unsigned AddrSpace) {
+ void EmitZeros(uint64_t NumBytes, unsigned AddrSpace = 0) {
EmitFill(NumBytes, 0, AddrSpace);
}
diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h
index 483a80b..4c5b176 100644
--- a/include/llvm/MC/MCTargetAsmParser.h
+++ b/include/llvm/MC/MCTargetAsmParser.h
@@ -22,6 +22,7 @@ class MCInst;
template <typename T> class SmallVectorImpl;
enum AsmRewriteKind {
+ AOK_Align, // Rewrite align as .align.
AOK_DotOperator, // Rewrite a dot operator expression as an immediate.
// E.g., [eax].foo.bar -> [eax].8
AOK_Emit, // Rewrite _emit as .byte.
@@ -142,6 +143,15 @@ public:
MCStreamer &Out, unsigned &ErrorInfo,
bool MatchingInlineAsm) = 0;
+ /// Allow a target to add special case operand matching for things that
+ /// tblgen doesn't/can't handle effectively. For example, literal
+ /// immediates on ARM. TableGen expects a token operand, but the parser
+ /// will recognize them as immediates.
+ virtual unsigned validateTargetOperandClass(MCParsedAsmOperand *Op,
+ unsigned Kind) {
+ return Match_InvalidOperand;
+ }
+
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 8046efd..e2478f6 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -14,22 +14,78 @@
#ifndef LLVM_OBJECT_ARCHIVE_H
#define LLVM_OBJECT_ARCHIVE_H
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Object/Binary.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
namespace llvm {
namespace object {
+struct ArchiveMemberHeader {
+ char Name[16];
+ char LastModified[12];
+ char UID[6];
+ char GID[6];
+ char AccessMode[8];
+ char Size[10]; ///< Size of data, not including header or padding.
+ char Terminator[2];
+
+ ///! Get the name without looking up long names.
+ llvm::StringRef getName() const {
+ char EndCond;
+ if (Name[0] == '/' || Name[0] == '#')
+ EndCond = ' ';
+ else
+ EndCond = '/';
+ llvm::StringRef::size_type end =
+ llvm::StringRef(Name, sizeof(Name)).find(EndCond);
+ if (end == llvm::StringRef::npos)
+ end = sizeof(Name);
+ assert(end <= sizeof(Name) && end > 0);
+ // Don't include the EndCond if there is one.
+ return llvm::StringRef(Name, end);
+ }
+
+ uint64_t getSize() const {
+ uint64_t ret;
+ if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret))
+ llvm_unreachable("Size is not an integer.");
+ return ret;
+ }
+};
+
+static const ArchiveMemberHeader *ToHeader(const char *base) {
+ return reinterpret_cast<const ArchiveMemberHeader *>(base);
+}
class Archive : public Binary {
virtual void anchor();
public:
class Child {
const Archive *Parent;
+ /// \brief Includes header but not padding byte.
StringRef Data;
+ /// \brief Offset from Data to the start of the file.
+ uint16_t StartOfFile;
public:
- Child(const Archive *p, StringRef d) : Parent(p), Data(d) {}
+ Child(const Archive *p, StringRef d) : Parent(p), Data(d) {
+ if (!p || d.empty())
+ return;
+ // Setup StartOfFile and PaddingBytes.
+ StartOfFile = sizeof(ArchiveMemberHeader);
+ // Don't include attached name.
+ StringRef Name = ToHeader(Data.data())->getName();
+ if (Name.startswith("#1/")) {
+ uint64_t NameSize;
+ if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize))
+ llvm_unreachable("Long name length is not an integer");
+ StartOfFile += NameSize;
+ }
+ }
bool operator ==(const Child &other) const {
return (Parent == other.Parent) && (Data.begin() == other.Data.begin());
@@ -39,16 +95,48 @@ public:
return Data.begin() < other.Data.begin();
}
- Child getNext() const;
+ Child getNext() const {
+ size_t SpaceToSkip = Data.size();
+ // If it's odd, add 1 to make it even.
+ if (SpaceToSkip & 1)
+ ++SpaceToSkip;
+
+ const char *NextLoc = Data.data() + SpaceToSkip;
+
+ // Check to see if this is past the end of the archive.
+ if (NextLoc >= Parent->Data->getBufferEnd())
+ return Child(Parent, StringRef(0, 0));
+
+ size_t NextSize =
+ sizeof(ArchiveMemberHeader) + ToHeader(NextLoc)->getSize();
+
+ return Child(Parent, StringRef(NextLoc, NextSize));
+ }
+
error_code getName(StringRef &Result) const;
int getLastModified() const;
int getUID() const;
int getGID() const;
int getAccessMode() const;
- ///! Return the size of the archive member without the header or padding.
- uint64_t getSize() const;
+ /// \return the size of the archive member without the header or padding.
+ uint64_t getSize() const { return Data.size() - StartOfFile; }
+
+ StringRef getBuffer() const {
+ return StringRef(Data.data() + StartOfFile, getSize());
+ }
+
+ error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
+ bool FullPath = false) const {
+ StringRef Name;
+ if (error_code ec = getName(Name))
+ return ec;
+ SmallString<128> Path;
+ Result.reset(MemoryBuffer::getMemBuffer(
+ getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name +
+ ")").toStringRef(Path) : Name, false));
+ return error_code::success();
+ }
- MemoryBuffer *getBuffer() const;
error_code getAsBinary(OwningPtr<Binary> &Result) const;
};
diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h
index d555de3..8bbcd8b 100644
--- a/include/llvm/Object/Binary.h
+++ b/include/llvm/Object/Binary.h
@@ -49,8 +49,8 @@ protected:
ID_EndObjects
};
- static inline unsigned int getELFType(bool isLittleEndian, bool is64Bits) {
- if (isLittleEndian)
+ static inline unsigned int getELFType(bool isLE, bool is64Bits) {
+ if (isLE)
return is64Bits ? ID_ELF64L : ID_ELF32L;
else
return is64Bits ? ID_ELF64B : ID_ELF32B;
@@ -85,6 +85,10 @@ public:
bool isCOFF() const {
return TypeID == ID_COFF;
}
+
+ bool isLittleEndian() const {
+ return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B);
+ }
};
/// @brief Create a Binary from Source, autodetecting the file type.
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index aa26d17..d5ff6f9 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -37,6 +37,13 @@ namespace object {
using support::endianness;
+template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+struct ELFType {
+ static const endianness TargetEndianness = target_endianness;
+ static const std::size_t MaxAlignment = max_alignment;
+ static const bool Is64Bits = is64Bits;
+};
+
template<typename T, int max_align>
struct MaximumAlignment {
enum {value = AlignOf<T>::Alignment > max_align ? max_align
@@ -72,59 +79,59 @@ struct ELFDataTypeTypedefHelperCommon {
MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword;
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct ELFDataTypeTypedefHelper;
/// ELF 32bit types.
-template<endianness target_endianness, std::size_t max_alignment>
-struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, false>
- : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment> {
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, false> >
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint32_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
/// ELF 64bit types.
-template<endianness target_endianness, std::size_t max_alignment>
-struct ELFDataTypeTypedefHelper<target_endianness, max_alignment, true>
- : ELFDataTypeTypedefHelperCommon<target_endianness, max_alignment>{
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct ELFDataTypeTypedefHelper<ELFT<TargetEndianness, MaxAlign, true> >
+ : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> {
typedef uint64_t value_type;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Addr;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr;
typedef support::detail::packed_endian_specific_integral
- <value_type, target_endianness,
- MaximumAlignment<value_type, max_alignment>::value> Elf_Off;
+ <value_type, TargetEndianness,
+ MaximumAlignment<value_type, MaxAlign>::value> Elf_Off;
};
// I really don't like doing this, but the alternative is copypasta.
-#define LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits) \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Addr Elf_Addr; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Off Elf_Off; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Half Elf_Half; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Word Elf_Word; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Sword Elf_Sword; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Xword Elf_Xword; \
-typedef typename ELFDataTypeTypedefHelper \
- <target_endianness, max_alignment, is64Bits>::Elf_Sxword Elf_Sxword;
+#define LLVM_ELF_IMPORT_TYPES(ELFT) \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Addr Elf_Addr; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Off Elf_Off; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Half Elf_Half; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Word Elf_Word; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sword Elf_Sword; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Xword Elf_Xword; \
+typedef typename ELFDataTypeTypedefHelper <ELFT>::Elf_Sxword Elf_Sxword;
+
+// This is required to get template types into a macro :(
+#define LLVM_ELF_COMMA ,
// Section header.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Shdr_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Shdr_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, false> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Word sh_flags; // Section flags (SHF_*)
@@ -137,9 +144,11 @@ struct Elf_Shdr_Base<target_endianness, max_alignment, false> {
Elf_Word sh_entsize; // Size of records contained within the section
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Shdr_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Shdr_Base<ELFT<TargetEndianness, MaxAlign, true> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Word sh_name; // Section name (index into string table)
Elf_Word sh_type; // Section type (SHT_*)
Elf_Xword sh_flags; // Section flags (SHF_*)
@@ -152,11 +161,10 @@ struct Elf_Shdr_Base<target_endianness, max_alignment, true> {
Elf_Xword sh_entsize; // Size of records contained within the section
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Shdr_Impl
- : Elf_Shdr_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_entsize;
- using Elf_Shdr_Base<target_endianness, max_alignment, is64Bits>::sh_size;
+template<class ELFT>
+struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> {
+ using Elf_Shdr_Base<ELFT>::sh_entsize;
+ using Elf_Shdr_Base<ELFT>::sh_size;
/// @brief Get the number of entities this section contains if it has any.
unsigned getEntityCount() const {
@@ -166,14 +174,14 @@ struct Elf_Shdr_Impl
}
};
-template< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits>
+template<class ELFT>
struct Elf_Sym_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Sym_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, false> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Word st_name; // Symbol name (index into string table)
Elf_Addr st_value; // Value or address associated with the symbol
Elf_Word st_size; // Size of the symbol
@@ -182,9 +190,11 @@ struct Elf_Sym_Base<target_endianness, max_alignment, false> {
Elf_Half st_shndx; // Which section (header table index) it's defined in
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Sym_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Sym_Base<ELFT<TargetEndianness, MaxAlign, true> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
@@ -193,10 +203,9 @@ struct Elf_Sym_Base<target_endianness, max_alignment, true> {
Elf_Xword st_size; // Size of the symbol
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Sym_Impl
- : Elf_Sym_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Sym_Base<target_endianness, max_alignment, is64Bits>::st_info;
+template<class ELFT>
+struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
+ using Elf_Sym_Base<ELFT>::st_info;
// These accessors and mutators correspond to the ELF32_ST_BIND,
// ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
@@ -211,22 +220,21 @@ struct Elf_Sym_Impl
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
/// (.gnu.version). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Versym_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Half vs_index; // Version index with flags (e.g. VERSYM_HIDDEN)
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdaux_Impl;
/// Elf_Verdef: This is the structure of entries in the SHT_GNU_verdef section
/// (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdef_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
- typedef
- Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
+ LLVM_ELF_IMPORT_TYPES(ELFT)
+ typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
Elf_Half vd_version; // Version of this structure (e.g. VER_DEF_CURRENT)
Elf_Half vd_flags; // Bitwise flags (VER_DEF_*)
Elf_Half vd_ndx; // Version index, used in .gnu.version entries
@@ -243,18 +251,18 @@ struct Elf_Verdef_Impl {
/// Elf_Verdaux: This is the structure of auxiliary data in the SHT_GNU_verdef
/// section (.gnu.version_d). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verdaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Word vda_name; // Version name (offset in string table)
Elf_Word vda_next; // Offset to next Verdaux entry (in bytes)
};
/// Elf_Verneed: This is the structure of entries in the SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Verneed_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Half vn_version; // Version of this structure (e.g. VER_NEED_CURRENT)
Elf_Half vn_cnt; // Number of associated Vernaux entries
Elf_Word vn_file; // Library name (string table offset)
@@ -264,9 +272,9 @@ struct Elf_Verneed_Impl {
/// Elf_Vernaux: This is the structure of auxiliary data in SHT_GNU_verneed
/// section (.gnu.version_r). This structure is identical for ELF32 and ELF64.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Vernaux_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
Elf_Word vna_hash; // Hash of dependency name
Elf_Half vna_flags; // Bitwise Flags (VER_FLAG_*)
Elf_Half vna_other; // Version index, used in .gnu.version entries
@@ -276,12 +284,14 @@ struct Elf_Vernaux_Impl {
/// Elf_Dyn_Base: This structure matches the form of entries in the dynamic
/// table section (.dynamic) look like.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Dyn_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Dyn_Base<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, false> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Sword d_tag;
union {
Elf_Word d_val;
@@ -289,9 +299,11 @@ struct Elf_Dyn_Base<target_endianness, max_alignment, false> {
} d_un;
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Dyn_Base<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Dyn_Base<ELFT<TargetEndianness, MaxAlign, true> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Sxword d_tag;
union {
Elf_Xword d_val;
@@ -300,92 +312,67 @@ struct Elf_Dyn_Base<target_endianness, max_alignment, true> {
};
/// Elf_Dyn_Impl: This inherits from Elf_Dyn_Base, adding getters and setters.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-struct Elf_Dyn_Impl : Elf_Dyn_Base<target_endianness, max_alignment, is64Bits> {
- using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_tag;
- using Elf_Dyn_Base<target_endianness, max_alignment, is64Bits>::d_un;
+template<class ELFT>
+struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> {
+ using Elf_Dyn_Base<ELFT>::d_tag;
+ using Elf_Dyn_Base<ELFT>::d_un;
int64_t getTag() const { return d_tag; }
uint64_t getVal() const { return d_un.d_val; }
uint64_t getPtr() const { return d_un.ptr; }
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-class ELFObjectFile;
-
-// DynRefImpl: Reference to an entry in the dynamic table
-// This is an ELF-specific interface.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-class DynRefImpl {
- typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
- typedef ELFObjectFile<target_endianness, max_alignment, is64Bits> OwningType;
-
- DataRefImpl DynPimpl;
- const OwningType *OwningObject;
-
-public:
- DynRefImpl() : OwningObject(NULL) { }
-
- DynRefImpl(DataRefImpl DynP, const OwningType *Owner);
-
- bool operator==(const DynRefImpl &Other) const;
- bool operator <(const DynRefImpl &Other) const;
-
- error_code getNext(DynRefImpl &Result) const;
- int64_t getTag() const;
- uint64_t getVal() const;
- uint64_t getPtr() const;
-
- DataRefImpl getRawDataRefImpl() const;
-};
-
// Elf_Rel: Elf Relocation
-template< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits
- , bool isRela>
+template<class ELFT, bool isRela>
struct Elf_Rel_Base;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, false, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, false> {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, true, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, false> {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, false, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, true> {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Word r_info; // Symbol table index and type of relocation to apply
Elf_Sword r_addend; // Compute value for relocatable field by adding this
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Rel_Base<target_endianness, max_alignment, true, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, true> {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Addr r_offset; // Location (file byte offset, or program virtual addr)
Elf_Xword r_info; // Symbol table index and type of relocation to apply
Elf_Sxword r_addend; // Compute value for relocatable field by adding this.
};
-template< endianness target_endianness
- , std::size_t max_alignment
- , bool is64Bits
- , bool isRela>
+template<class ELFT, bool isRela>
struct Elf_Rel_Impl;
-template<endianness target_endianness, std::size_t max_alignment, bool isRela>
-struct Elf_Rel_Impl<target_endianness, max_alignment, true, isRela>
- : Elf_Rel_Base<target_endianness, max_alignment, true, isRela> {
- using Elf_Rel_Base<target_endianness, max_alignment, true, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, true>, isRela>
+ : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela> {
+ using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, true>, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
@@ -400,11 +387,13 @@ struct Elf_Rel_Impl<target_endianness, max_alignment, true, isRela>
}
};
-template<endianness target_endianness, std::size_t max_alignment, bool isRela>
-struct Elf_Rel_Impl<target_endianness, max_alignment, false, isRela>
- : Elf_Rel_Base<target_endianness, max_alignment, false, isRela> {
- using Elf_Rel_Base<target_endianness, max_alignment, false, isRela>::r_info;
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign, bool isRela>
+struct Elf_Rel_Impl<ELFT<TargetEndianness, MaxAlign, false>, isRela>
+ : Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela> {
+ using Elf_Rel_Base<ELFT<TargetEndianness, MaxAlign, false>, isRela>::r_info;
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
// These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
// and ELF32_R_INFO macros defined in the ELF specification:
@@ -417,9 +406,9 @@ struct Elf_Rel_Impl<target_endianness, max_alignment, false, isRela>
}
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Ehdr_Impl {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
+ LLVM_ELF_IMPORT_TYPES(ELFT)
unsigned char e_ident[ELF::EI_NIDENT]; // ELF Identification bytes
Elf_Half e_type; // Type of file (see ET_*)
Elf_Half e_machine; // Required architecture for this file (see EM_*)
@@ -442,12 +431,14 @@ struct Elf_Ehdr_Impl {
unsigned char getDataEncoding() const { return e_ident[ELF::EI_DATA]; }
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
struct Elf_Phdr_Impl;
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Phdr_Impl<target_endianness, max_alignment, false> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, false)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, false> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA false>)
Elf_Word p_type; // Type of segment
Elf_Off p_offset; // FileOffset where segment is located, in bytes
Elf_Addr p_vaddr; // Virtual Address of beginning of segment
@@ -458,9 +449,11 @@ struct Elf_Phdr_Impl<target_endianness, max_alignment, false> {
Elf_Word p_align; // Segment alignment constraint
};
-template<endianness target_endianness, std::size_t max_alignment>
-struct Elf_Phdr_Impl<target_endianness, max_alignment, true> {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, true)
+template<template<endianness, std::size_t, bool> class ELFT,
+ endianness TargetEndianness, std::size_t MaxAlign>
+struct Elf_Phdr_Impl<ELFT<TargetEndianness, MaxAlign, true> > {
+ LLVM_ELF_IMPORT_TYPES(ELFT<TargetEndianness LLVM_ELF_COMMA
+ MaxAlign LLVM_ELF_COMMA true>)
Elf_Word p_type; // Type of segment
Elf_Word p_flags; // Segment flags
Elf_Off p_offset; // FileOffset where segment is located, in bytes
@@ -471,72 +464,18 @@ struct Elf_Phdr_Impl<target_endianness, max_alignment, true> {
Elf_Xword p_align; // Segment alignment constraint
};
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
class ELFObjectFile : public ObjectFile {
- LLVM_ELF_IMPORT_TYPES(target_endianness, max_alignment, is64Bits)
-
- typedef Elf_Ehdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Ehdr;
- typedef Elf_Shdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Shdr;
- typedef Elf_Sym_Impl<target_endianness, max_alignment, is64Bits> Elf_Sym;
- typedef Elf_Dyn_Impl<target_endianness, max_alignment, is64Bits> Elf_Dyn;
- typedef Elf_Phdr_Impl<target_endianness, max_alignment, is64Bits> Elf_Phdr;
- typedef
- Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, false> Elf_Rel;
- typedef
- Elf_Rel_Impl<target_endianness, max_alignment, is64Bits, true> Elf_Rela;
- typedef
- Elf_Verdef_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdef;
- typedef
- Elf_Verdaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Verdaux;
- typedef
- Elf_Verneed_Impl<target_endianness, max_alignment, is64Bits> Elf_Verneed;
- typedef
- Elf_Vernaux_Impl<target_endianness, max_alignment, is64Bits> Elf_Vernaux;
- typedef
- Elf_Versym_Impl<target_endianness, max_alignment, is64Bits> Elf_Versym;
- typedef DynRefImpl<target_endianness, max_alignment, is64Bits> DynRef;
- typedef content_iterator<DynRef> dyn_iterator;
-
-protected:
- // This flag is used for classof, to distinguish ELFObjectFile from
- // its subclass. If more subclasses will be created, this flag will
- // have to become an enum.
- bool isDyldELFObject;
-
-private:
- typedef SmallVector<const Elf_Shdr*, 1> Sections_t;
- typedef DenseMap<unsigned, unsigned> IndexMap_t;
- typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
-
- const Elf_Ehdr *Header;
- const Elf_Shdr *SectionHeaderTable;
- const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
- const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
- const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table.
-
- // SymbolTableSections[0] always points to the dynamic string table section
- // header, or NULL if there is no dynamic string table.
- Sections_t SymbolTableSections;
- IndexMap_t SymbolTableSectionsIndexMap;
- DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
-
- const Elf_Shdr *dot_dynamic_sec; // .dynamic
- const Elf_Shdr *dot_gnu_version_sec; // .gnu.version
- const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
- const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
-
- // Pointer to SONAME entry in dynamic string table
- // This is set the first time getLoadName is called.
- mutable const char *dt_soname;
+ LLVM_ELF_IMPORT_TYPES(ELFT)
public:
/// \brief Iterate over constant sized entities.
template<class EntT>
class ELFEntityIterator {
public:
- typedef void difference_type;
+ typedef ptrdiff_t difference_type;
typedef EntT value_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef std::random_access_iterator_tag iterator_category;
typedef value_type &reference;
typedef value_type *pointer;
@@ -576,11 +515,74 @@ public:
return Tmp;
}
+ ELFEntityIterator &operator =(const ELFEntityIterator &Other) {
+ EntitySize = Other.EntitySize;
+ Current = Other.Current;
+ return *this;
+ }
+
+ difference_type operator -(const ELFEntityIterator &Other) const {
+ assert(EntitySize == Other.EntitySize &&
+ "Subtracting iterators of different EntitiySize!");
+ return (Current - Other.Current) / EntitySize;
+ }
+
+ const char *get() const { return Current; }
+
private:
- const uint64_t EntitySize;
+ uint64_t EntitySize;
const char *Current;
};
+ typedef Elf_Ehdr_Impl<ELFT> Elf_Ehdr;
+ typedef Elf_Shdr_Impl<ELFT> Elf_Shdr;
+ typedef Elf_Sym_Impl<ELFT> Elf_Sym;
+ typedef Elf_Dyn_Impl<ELFT> Elf_Dyn;
+ typedef Elf_Phdr_Impl<ELFT> Elf_Phdr;
+ typedef Elf_Rel_Impl<ELFT, false> Elf_Rel;
+ typedef Elf_Rel_Impl<ELFT, true> Elf_Rela;
+ typedef Elf_Verdef_Impl<ELFT> Elf_Verdef;
+ typedef Elf_Verdaux_Impl<ELFT> Elf_Verdaux;
+ typedef Elf_Verneed_Impl<ELFT> Elf_Verneed;
+ typedef Elf_Vernaux_Impl<ELFT> Elf_Vernaux;
+ typedef Elf_Versym_Impl<ELFT> Elf_Versym;
+ typedef ELFEntityIterator<const Elf_Dyn> Elf_Dyn_iterator;
+ typedef ELFEntityIterator<const Elf_Sym> Elf_Sym_iterator;
+ typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
+ typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
+
+protected:
+ // This flag is used for classof, to distinguish ELFObjectFile from
+ // its subclass. If more subclasses will be created, this flag will
+ // have to become an enum.
+ bool isDyldELFObject;
+
+private:
+ typedef SmallVector<const Elf_Shdr *, 2> Sections_t;
+ typedef DenseMap<unsigned, unsigned> IndexMap_t;
+ typedef DenseMap<const Elf_Shdr*, SmallVector<uint32_t, 1> > RelocMap_t;
+
+ const Elf_Ehdr *Header;
+ const Elf_Shdr *SectionHeaderTable;
+ const Elf_Shdr *dot_shstrtab_sec; // Section header string table.
+ const Elf_Shdr *dot_strtab_sec; // Symbol header string table.
+ const Elf_Shdr *dot_dynstr_sec; // Dynamic symbol string table.
+
+ // SymbolTableSections[0] always points to the dynamic string table section
+ // header, or NULL if there is no dynamic string table.
+ Sections_t SymbolTableSections;
+ IndexMap_t SymbolTableSectionsIndexMap;
+ DenseMap<const Elf_Sym*, ELF::Elf64_Word> ExtendedSymbolTable;
+
+ const Elf_Shdr *dot_dynamic_sec; // .dynamic
+ const Elf_Shdr *dot_gnu_version_sec; // .gnu.version
+ const Elf_Shdr *dot_gnu_version_r_sec; // .gnu.version_r
+ const Elf_Shdr *dot_gnu_version_d_sec; // .gnu.version_d
+
+ // Pointer to SONAME entry in dynamic string table
+ // This is set the first time getLoadName is called.
+ mutable const char *dt_soname;
+
private:
// Records for each version index the corresponding Verdef or Vernaux entry.
// This is filled the first time LoadVersionMap() is called.
@@ -617,6 +619,7 @@ private:
return getSection(Rel.w.b);
}
+public:
bool isRelocationHasAddend(DataRefImpl Rel) const;
template<typename T>
const T *getEntry(uint16_t Section, uint32_t Entry) const;
@@ -661,9 +664,6 @@ protected:
section_iterator &Res) const;
virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const;
- friend class DynRefImpl<target_endianness, max_alignment, is64Bits>;
- virtual error_code getDynNext(DataRefImpl DynData, DynRef &Result) const;
-
virtual error_code getLibraryNext(DataRefImpl Data, LibraryRef &Result) const;
virtual error_code getLibraryPath(DataRefImpl Data, StringRef &Res) const;
@@ -717,11 +717,34 @@ public:
virtual library_iterator begin_libraries_needed() const;
virtual library_iterator end_libraries_needed() const;
- virtual dyn_iterator begin_dynamic_table() const;
- virtual dyn_iterator end_dynamic_table() const;
+ const Elf_Shdr *getDynamicSymbolTableSectionHeader() const {
+ return SymbolTableSections[0];
+ }
- typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter;
- typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter;
+ const Elf_Shdr *getDynamicStringTableSectionHeader() const {
+ return dot_dynstr_sec;
+ }
+
+ Elf_Dyn_iterator begin_dynamic_table() const;
+ /// \param NULLEnd use one past the first DT_NULL entry as the end instead of
+ /// the section size.
+ Elf_Dyn_iterator end_dynamic_table(bool NULLEnd = false) const;
+
+ Elf_Sym_iterator begin_elf_dynamic_symbols() const {
+ const Elf_Shdr *DynSymtab = SymbolTableSections[0];
+ if (DynSymtab)
+ return Elf_Sym_iterator(DynSymtab->sh_entsize,
+ (const char *)base() + DynSymtab->sh_offset);
+ return Elf_Sym_iterator(0, 0);
+ }
+
+ Elf_Sym_iterator end_elf_dynamic_symbols() const {
+ const Elf_Shdr *DynSymtab = SymbolTableSections[0];
+ if (DynSymtab)
+ return Elf_Sym_iterator(DynSymtab->sh_entsize, (const char *)base() +
+ DynSymtab->sh_offset + DynSymtab->sh_size);
+ return Elf_Sym_iterator(0, 0);
+ }
Elf_Rela_Iter beginELFRela(const Elf_Shdr *sec) const {
return Elf_Rela_Iter(sec->sh_entsize,
@@ -777,16 +800,15 @@ public:
// Methods for type inquiry through isa, cast, and dyn_cast
bool isDyldType() const { return isDyldELFObject; }
static inline bool classof(const Binary *v) {
- return v->getType() == getELFType(target_endianness == support::little,
- is64Bits);
+ return v->getType() == getELFType(ELFT::TargetEndianness == support::little,
+ ELFT::Is64Bits);
}
};
// Iterate through the version definitions, and place each Elf_Verdef
// in the VersionMap according to its index.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
- LoadVersionDefs(const Elf_Shdr *sec) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionDefs(const Elf_Shdr *sec) const {
unsigned vd_size = sec->sh_size; // Size of section in bytes
unsigned vd_count = sec->sh_info; // Number of Verdef entries
const char *sec_start = (const char*)base() + sec->sh_offset;
@@ -810,9 +832,8 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
// Iterate through the versions needed section, and place each Elf_Vernaux
// in the VersionMap according to its index.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
- LoadVersionNeeds(const Elf_Shdr *sec) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const {
unsigned vn_size = sec->sh_size; // Size of section in bytes
unsigned vn_count = sec->sh_info; // Number of Verneed entries
const char *sec_start = (const char*)base() + sec->sh_offset;
@@ -843,9 +864,8 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>::
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::LoadVersionMap() const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::LoadVersionMap() const {
// If there is no dynamic symtab or version table, there is nothing to do.
if (SymbolTableSections[0] == NULL || dot_gnu_version_sec == NULL)
return;
@@ -866,9 +886,9 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>
LoadVersionNeeds(dot_gnu_version_r_sec);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::validateSymbol(DataRefImpl Symb) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::validateSymbol(DataRefImpl Symb) const {
+#ifndef NDEBUG
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
// FIXME: We really need to do proper error handling in the case of an invalid
@@ -883,12 +903,12 @@ void ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ SymbolTableSection->sh_size)))
// FIXME: Proper error handling.
report_fatal_error("Symb must point to a valid symbol!");
+#endif
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolNext(DataRefImpl Symb,
- SymbolRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolNext(DataRefImpl Symb,
+ SymbolRef &Result) const {
validateSymbol(Symb);
const Elf_Shdr *SymbolTableSection = SymbolTableSections[Symb.d.b];
@@ -913,20 +933,18 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolName(DataRefImpl Symb,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb,
+ StringRef &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
return getSymbolName(SymbolTableSections[Symb.d.b], symb, Result);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolVersion(SymbolRef SymRef,
- StringRef &Version,
- bool &IsDefault) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef,
+ StringRef &Version,
+ bool &IsDefault) const {
DataRefImpl Symb = SymRef.getRawDataRefImpl();
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -934,19 +952,17 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
Version, IsDefault);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-ELF::Elf64_Word ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolTableIndex(const Elf_Sym *symb) const {
+template<class ELFT>
+ELF::Elf64_Word ELFObjectFile<ELFT>
+ ::getSymbolTableIndex(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return ExtendedSymbolTable.lookup(symb);
return symb->st_shndx;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSection(const Elf_Sym *symb) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getSection(const Elf_Sym *symb) const {
if (symb->st_shndx == ELF::SHN_XINDEX)
return getSection(ExtendedSymbolTable.lookup(symb));
if (symb->st_shndx >= ELF::SHN_LORESERVE)
@@ -954,38 +970,31 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
return getSection(symb->st_shndx);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSection(section_iterator &It) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getElfSection(section_iterator &It) const {
llvm::object::DataRefImpl ShdrRef = It->getRawDataRefImpl();
return reinterpret_cast<const Elf_Shdr *>(ShdrRef.p);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Sym *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSymbol(symbol_iterator &It) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getElfSymbol(symbol_iterator &It) const {
return getSymbol(It->getRawDataRefImpl());
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Sym *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getElfSymbol(uint32_t index) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getElfSymbol(uint32_t index) const {
DataRefImpl SymbolData;
SymbolData.d.a = index;
SymbolData.d.b = 1;
return getSymbol(SymbolData);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolFileOffset(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolFileOffset(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section;
@@ -1003,7 +1012,7 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
switch (symb->getType()) {
case ELF::STT_SECTION:
- Result = Section ? Section->sh_addr : UnknownAddressOrSize;
+ Result = Section ? Section->sh_offset : UnknownAddressOrSize;
return object_error::success;
case ELF::STT_FUNC:
case ELF::STT_OBJECT:
@@ -1017,10 +1026,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolAddress(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section;
@@ -1061,10 +1069,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolSize(DataRefImpl Symb,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb,
+ uint64_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
if (symb->st_size == 0)
@@ -1073,10 +1080,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolNMTypeChar(DataRefImpl Symb,
- char &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolNMTypeChar(DataRefImpl Symb,
+ char &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *Section = getSection(symb);
@@ -1138,10 +1144,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolType(DataRefImpl Symb,
- SymbolRef::Type &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb,
+ SymbolRef::Type &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -1170,10 +1175,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolFlags(DataRefImpl Symb,
- uint32_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb,
+ uint32_t &Result) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
@@ -1205,10 +1209,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolSection(DataRefImpl Symb,
- section_iterator &Res) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb,
+ section_iterator &Res) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
const Elf_Shdr *sec = getSection(symb);
@@ -1222,19 +1225,18 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolValue(DataRefImpl Symb,
- uint64_t &Val) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolValue(DataRefImpl Symb,
+ uint64_t &Val) const {
validateSymbol(Symb);
const Elf_Sym *symb = getSymbol(Symb);
Val = symb->st_value;
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionNext(DataRefImpl Sec, SectionRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionNext(DataRefImpl Sec,
+ SectionRef &Result) const {
const uint8_t *sec = reinterpret_cast<const uint8_t *>(Sec.p);
sec += Header->e_shentsize;
Sec.p = reinterpret_cast<intptr_t>(sec);
@@ -1242,65 +1244,58 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionName(DataRefImpl Sec,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec,
+ StringRef &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
Result = StringRef(getString(dot_shstrtab_sec, sec->sh_name));
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionAddress(DataRefImpl Sec,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionAddress(DataRefImpl Sec,
+ uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
Result = sec->sh_addr;
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionSize(DataRefImpl Sec,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionSize(DataRefImpl Sec,
+ uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
Result = sec->sh_size;
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionContents(DataRefImpl Sec,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec,
+ StringRef &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
const char *start = (const char*)base() + sec->sh_offset;
Result = StringRef(start, sec->sh_size);
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionContents(const Elf_Shdr *Sec,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionContents(const Elf_Shdr *Sec,
+ StringRef &Result) const {
const char *start = (const char*)base() + Sec->sh_offset;
Result = StringRef(start, Sec->sh_size);
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionAlignment(DataRefImpl Sec,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionAlignment(DataRefImpl Sec,
+ uint64_t &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
Result = sec->sh_addralign;
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionText(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionText(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_flags & ELF::SHF_EXECINSTR)
Result = true;
@@ -1309,10 +1304,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionData(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionData(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
&& sec->sh_type == ELF::SHT_PROGBITS)
@@ -1322,10 +1316,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionBSS(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionBSS(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_flags & (ELF::SHF_ALLOC | ELF::SHF_WRITE)
&& sec->sh_type == ELF::SHT_NOBITS)
@@ -1335,10 +1328,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionRequiredForExecution(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionRequiredForExecution(
+ DataRefImpl Sec, bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_flags & ELF::SHF_ALLOC)
Result = true;
@@ -1347,10 +1339,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionVirtual(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionVirtual(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_type == ELF::SHT_NOBITS)
Result = true;
@@ -1359,10 +1350,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionZeroInit(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionZeroInit(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
// For ELF, all zero-init sections are virtual (that is, they occupy no space
// in the object image) and vice versa.
@@ -1370,10 +1360,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::isSectionReadOnlyData(DataRefImpl Sec,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::isSectionReadOnlyData(DataRefImpl Sec,
+ bool &Result) const {
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
if (sec->sh_flags & ELF::SHF_WRITE || sec->sh_flags & ELF::SHF_EXECINSTR)
Result = false;
@@ -1382,19 +1371,18 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::sectionContainsSymbol(DataRefImpl Sec,
- DataRefImpl Symb,
- bool &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::sectionContainsSymbol(DataRefImpl Sec,
+ DataRefImpl Symb,
+ bool &Result) const {
// FIXME: Unimplemented.
Result = false;
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionRelBegin(DataRefImpl Sec) const {
+template<class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::getSectionRelBegin(DataRefImpl Sec) const {
DataRefImpl RelData;
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
@@ -1406,9 +1394,9 @@ relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
return relocation_iterator(RelocationRef(RelData, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionRelEnd(DataRefImpl Sec) const {
+template<class ELFT>
+relocation_iterator
+ELFObjectFile<ELFT>::getSectionRelEnd(DataRefImpl Sec) const {
DataRefImpl RelData;
const Elf_Shdr *sec = reinterpret_cast<const Elf_Shdr *>(Sec.p);
typename RelocMap_t::const_iterator ittr = SectionRelocMap.find(sec);
@@ -1424,10 +1412,9 @@ relocation_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
// Relocations
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationNext(DataRefImpl Rel,
- RelocationRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationNext(DataRefImpl Rel,
+ RelocationRef &Result) const {
++Rel.w.c;
const Elf_Shdr *relocsec = getSection(Rel.w.b);
if (Rel.w.c >= (relocsec->sh_size / relocsec->sh_entsize)) {
@@ -1453,10 +1440,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationSymbol(DataRefImpl Rel,
- SymbolRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel,
+ SymbolRef &Result) const {
uint32_t symbolIdx;
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
@@ -1481,10 +1467,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationAddress(DataRefImpl Rel,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel,
+ uint64_t &Result) const {
uint64_t offset;
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
@@ -1504,10 +1489,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationOffset(DataRefImpl Rel,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel,
+ uint64_t &Result) const {
uint64_t offset;
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
@@ -1527,10 +1511,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationType(DataRefImpl Rel,
- uint64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel,
+ uint64_t &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
default :
@@ -1550,10 +1533,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
#define LLVM_ELF_SWITCH_RELOC_TYPE_NAME(enum) \
case ELF::enum: res = #enum; break;
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationTypeName(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationTypeName(
+ DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
uint32_t type;
StringRef res;
@@ -1654,6 +1636,86 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
res = "Unknown";
}
break;
+ case ELF::EM_AARCH64:
+ switch (type) {
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_NONE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ABS16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL64);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL32);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_PREL16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G0_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G1_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G2_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_UABS_G3);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G0);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_MOVW_SABS_G2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD_PREL_LO19);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_LO21);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_PREL_PG_HI21);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADD_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST8_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TSTBR14);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CONDBR19);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_JUMP26);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_CALL26);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST16_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST32_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST64_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LDST128_ABS_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_ADR_GOT_PAGE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_LD64_GOT_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_HI12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSIE_LD_GOTTPREL_PREL19);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G1_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_MOVW_TPREL_G0_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_HI12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_ADD_TPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADR_PAGE);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_LD64_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_ADD_LO12_NC);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_AARCH64_TLSDESC_CALL);
+
+ default:
+ res = "Unknown";
+ }
+ break;
case ELF::EM_ARM:
switch (type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_ARM_NONE);
@@ -1892,10 +1954,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
#undef LLVM_ELF_SWITCH_RELOC_TYPE_NAME
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationAdditionalInfo(DataRefImpl Rel,
- int64_t &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationAdditionalInfo(
+ DataRefImpl Rel, int64_t &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
switch (sec->sh_type) {
default :
@@ -1911,10 +1972,9 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRelocationValueString(DataRefImpl Rel,
- SmallVectorImpl<char> &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getRelocationValueString(
+ DataRefImpl Rel, SmallVectorImpl<char> &Result) const {
const Elf_Shdr *sec = getSection(Rel.w.b);
uint8_t type;
StringRef res;
@@ -1969,6 +2029,7 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
res = "Unknown";
}
break;
+ case ELF::EM_AARCH64:
case ELF::EM_ARM:
case ELF::EM_HEXAGON:
res = symname;
@@ -1982,20 +2043,21 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
// Verify that the last byte in the string table in a null.
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-void ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::VerifyStrTab(const Elf_Shdr *sh) const {
+template<class ELFT>
+void ELFObjectFile<ELFT>::VerifyStrTab(const Elf_Shdr *sh) const {
const char *strtab = (const char*)base() + sh->sh_offset;
if (strtab[sh->sh_size - 1] != 0)
// FIXME: Proper error handling.
report_fatal_error("String table must end with a null terminator!");
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
- : ObjectFile(getELFType(target_endianness == support::little, is64Bits),
- Object, ec)
+template<class ELFT>
+ELFObjectFile<ELFT>::ELFObjectFile(MemoryBuffer *Object, error_code &ec)
+ : ObjectFile(getELFType(
+ static_cast<endianness>(ELFT::TargetEndianness) == support::little,
+ ELFT::Is64Bits),
+ Object,
+ ec)
, isDyldELFObject(false)
, SectionHeaderTable(0)
, dot_shstrtab_sec(0)
@@ -2153,9 +2215,8 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
// Get the symbol table index in the symtab section given a symbol
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolIndex(const Elf_Sym *Sym) const {
+template<class ELFT>
+uint64_t ELFObjectFile<ELFT>::getSymbolIndex(const Elf_Sym *Sym) const {
assert(SymbolTableSections.size() == 1 && "Only one symbol table supported!");
const Elf_Shdr *SymTab = *SymbolTableSections.begin();
uintptr_t SymLoc = uintptr_t(Sym);
@@ -2167,9 +2228,8 @@ uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
return SymOffset / SymTab->sh_entsize;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::begin_symbols() const {
+template<class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::begin_symbols() const {
DataRefImpl SymbolData;
if (SymbolTableSections.size() <= 1) {
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
@@ -2181,18 +2241,16 @@ symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::end_symbols() const {
+template<class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::end_symbols() const {
DataRefImpl SymbolData;
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
SymbolData.d.b = std::numeric_limits<uint32_t>::max();
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::begin_dynamic_symbols() const {
+template<class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::begin_dynamic_symbols() const {
DataRefImpl SymbolData;
if (SymbolTableSections[0] == NULL) {
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
@@ -2204,26 +2262,23 @@ symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-symbol_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::end_dynamic_symbols() const {
+template<class ELFT>
+symbol_iterator ELFObjectFile<ELFT>::end_dynamic_symbols() const {
DataRefImpl SymbolData;
SymbolData.d.a = std::numeric_limits<uint32_t>::max();
SymbolData.d.b = std::numeric_limits<uint32_t>::max();
return symbol_iterator(SymbolRef(SymbolData, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-section_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::begin_sections() const {
+template<class ELFT>
+section_iterator ELFObjectFile<ELFT>::begin_sections() const {
DataRefImpl ret;
ret.p = reinterpret_cast<intptr_t>(base() + Header->e_shoff);
return section_iterator(SectionRef(ret, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-section_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::end_sections() const {
+template<class ELFT>
+section_iterator ELFObjectFile<ELFT>::end_sections() const {
DataRefImpl ret;
ret.p = reinterpret_cast<intptr_t>(base()
+ Header->e_shoff
@@ -2231,58 +2286,46 @@ section_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
return section_iterator(SectionRef(ret, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-typename ELFObjectFile<target_endianness, max_alignment, is64Bits>::dyn_iterator
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::begin_dynamic_table() const {
- DataRefImpl DynData;
- if (dot_dynamic_sec == NULL || dot_dynamic_sec->sh_size == 0) {
- DynData.d.a = std::numeric_limits<uint32_t>::max();
- } else {
- DynData.d.a = 0;
- }
- return dyn_iterator(DynRef(DynData, this));
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-typename ELFObjectFile<target_endianness, max_alignment, is64Bits>::dyn_iterator
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::end_dynamic_table() const {
- DataRefImpl DynData;
- DynData.d.a = std::numeric_limits<uint32_t>::max();
- return dyn_iterator(DynRef(DynData, this));
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getDynNext(DataRefImpl DynData,
- DynRef &Result) const {
- ++DynData.d.a;
-
- // Check to see if we are at the end of .dynamic
- if (DynData.d.a >= dot_dynamic_sec->getEntityCount()) {
- // We are at the end. Return the terminator.
- DynData.d.a = std::numeric_limits<uint32_t>::max();
+template<class ELFT>
+typename ELFObjectFile<ELFT>::Elf_Dyn_iterator
+ELFObjectFile<ELFT>::begin_dynamic_table() const {
+ if (dot_dynamic_sec)
+ return Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
+ (const char *)base() + dot_dynamic_sec->sh_offset);
+ return Elf_Dyn_iterator(0, 0);
+}
+
+template<class ELFT>
+typename ELFObjectFile<ELFT>::Elf_Dyn_iterator
+ELFObjectFile<ELFT>::end_dynamic_table(bool NULLEnd) const {
+ if (dot_dynamic_sec) {
+ Elf_Dyn_iterator Ret(dot_dynamic_sec->sh_entsize,
+ (const char *)base() + dot_dynamic_sec->sh_offset +
+ dot_dynamic_sec->sh_size);
+
+ if (NULLEnd) {
+ Elf_Dyn_iterator Start = begin_dynamic_table();
+ for (; Start != Ret && Start->getTag() != ELF::DT_NULL; ++Start)
+ ;
+ // Include the DT_NULL.
+ if (Start != Ret)
+ ++Start;
+ Ret = Start;
+ }
+ return Ret;
}
-
- Result = DynRef(DynData, this);
- return object_error::success;
+ return Elf_Dyn_iterator(0, 0);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-StringRef
-ELFObjectFile<target_endianness, max_alignment, is64Bits>::getLoadName() const {
+template<class ELFT>
+StringRef ELFObjectFile<ELFT>::getLoadName() const {
if (!dt_soname) {
// Find the DT_SONAME entry
- dyn_iterator it = begin_dynamic_table();
- dyn_iterator ie = end_dynamic_table();
- error_code ec;
- while (it != ie) {
+ Elf_Dyn_iterator it = begin_dynamic_table();
+ Elf_Dyn_iterator ie = end_dynamic_table();
+ for (; it != ie; ++it) {
if (it->getTag() == ELF::DT_SONAME)
break;
- it.increment(ec);
- if (ec)
- report_fatal_error("dynamic table iteration failed");
}
if (it != ie) {
if (dot_dynstr_sec == NULL)
@@ -2295,57 +2338,46 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>::getLoadName() const {
return dt_soname;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-library_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::begin_libraries_needed() const {
+template<class ELFT>
+library_iterator ELFObjectFile<ELFT>::begin_libraries_needed() const {
// Find the first DT_NEEDED entry
- dyn_iterator i = begin_dynamic_table();
- dyn_iterator e = end_dynamic_table();
- error_code ec;
- while (i != e) {
+ Elf_Dyn_iterator i = begin_dynamic_table();
+ Elf_Dyn_iterator e = end_dynamic_table();
+ for (; i != e; ++i) {
if (i->getTag() == ELF::DT_NEEDED)
break;
- i.increment(ec);
- if (ec)
- report_fatal_error("dynamic table iteration failed");
}
- // Use the same DataRefImpl format as DynRef.
- return library_iterator(LibraryRef(i->getRawDataRefImpl(), this));
+
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(i.get());
+ return library_iterator(LibraryRef(DRI, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getLibraryNext(DataRefImpl Data,
- LibraryRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getLibraryNext(DataRefImpl Data,
+ LibraryRef &Result) const {
// Use the same DataRefImpl format as DynRef.
- dyn_iterator i = dyn_iterator(DynRef(Data, this));
- dyn_iterator e = end_dynamic_table();
+ Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
+ reinterpret_cast<const char *>(Data.p));
+ Elf_Dyn_iterator e = end_dynamic_table();
// Skip the current dynamic table entry.
- error_code ec;
- if (i != e) {
- i.increment(ec);
- // TODO: proper error handling
- if (ec)
- report_fatal_error("dynamic table iteration failed");
- }
+ ++i;
// Find the next DT_NEEDED entry.
- while (i != e) {
- if (i->getTag() == ELF::DT_NEEDED)
- break;
- i.increment(ec);
- if (ec)
- report_fatal_error("dynamic table iteration failed");
- }
- Result = LibraryRef(i->getRawDataRefImpl(), this);
+ for (; i != e && i->getTag() != ELF::DT_NEEDED; ++i);
+
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(i.get());
+ Result = LibraryRef(DRI, this);
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getLibraryPath(DataRefImpl Data, StringRef &Res) const {
- dyn_iterator i = dyn_iterator(DynRef(Data, this));
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getLibraryPath(DataRefImpl Data,
+ StringRef &Res) const {
+ Elf_Dyn_iterator i = Elf_Dyn_iterator(dot_dynamic_sec->sh_entsize,
+ reinterpret_cast<const char *>(Data.p));
if (i == end_dynamic_table())
report_fatal_error("getLibraryPath() called on iterator end");
@@ -2363,23 +2395,21 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-library_iterator ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::end_libraries_needed() const {
- dyn_iterator e = end_dynamic_table();
- // Use the same DataRefImpl format as DynRef.
- return library_iterator(LibraryRef(e->getRawDataRefImpl(), this));
+template<class ELFT>
+library_iterator ELFObjectFile<ELFT>::end_libraries_needed() const {
+ Elf_Dyn_iterator e = end_dynamic_table();
+ DataRefImpl DRI;
+ DRI.p = reinterpret_cast<uintptr_t>(e.get());
+ return library_iterator(LibraryRef(DRI, this));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-uint8_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getBytesInAddress() const {
- return is64Bits ? 8 : 4;
+template<class ELFT>
+uint8_t ELFObjectFile<ELFT>::getBytesInAddress() const {
+ return ELFT::Is64Bits ? 8 : 4;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-StringRef ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getFileFormatName() const {
+template<class ELFT>
+StringRef ELFObjectFile<ELFT>::getFileFormatName() const {
switch(Header->e_ident[ELF::EI_CLASS]) {
case ELF::ELFCLASS32:
switch(Header->e_machine) {
@@ -2391,6 +2421,8 @@ StringRef ELFObjectFile<target_endianness, max_alignment, is64Bits>
return "ELF32-arm";
case ELF::EM_HEXAGON:
return "ELF32-hexagon";
+ case ELF::EM_MIPS:
+ return "ELF32-mips";
default:
return "ELF32-unknown";
}
@@ -2400,6 +2432,8 @@ StringRef ELFObjectFile<target_endianness, max_alignment, is64Bits>
return "ELF64-i386";
case ELF::EM_X86_64:
return "ELF64-x86-64";
+ case ELF::EM_AARCH64:
+ return "ELF64-aarch64";
case ELF::EM_PPC64:
return "ELF64-ppc64";
default:
@@ -2411,20 +2445,21 @@ StringRef ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-unsigned ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getArch() const {
+template<class ELFT>
+unsigned ELFObjectFile<ELFT>::getArch() const {
switch(Header->e_machine) {
case ELF::EM_386:
return Triple::x86;
case ELF::EM_X86_64:
return Triple::x86_64;
+ case ELF::EM_AARCH64:
+ return Triple::aarch64;
case ELF::EM_ARM:
return Triple::arm;
case ELF::EM_HEXAGON:
return Triple::hexagon;
case ELF::EM_MIPS:
- return (target_endianness == support::little) ?
+ return (ELFT::TargetEndianness == support::little) ?
Triple::mipsel : Triple::mips;
case ELF::EM_PPC64:
return Triple::ppc64;
@@ -2433,9 +2468,8 @@ unsigned ELFObjectFile<target_endianness, max_alignment, is64Bits>
}
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getNumSections() const {
+template<class ELFT>
+uint64_t ELFObjectFile<ELFT>::getNumSections() const {
assert(Header && "Header not initialized!");
if (Header->e_shnum == ELF::SHN_UNDEF) {
assert(SectionHeaderTable && "SectionHeaderTable not initialized!");
@@ -2444,10 +2478,9 @@ uint64_t ELFObjectFile<target_endianness, max_alignment, is64Bits>
return Header->e_shnum;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
uint64_t
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getStringTableIndex() const {
+ELFObjectFile<ELFT>::getStringTableIndex() const {
if (Header->e_shnum == ELF::SHN_UNDEF) {
if (Header->e_shstrndx == ELF::SHN_HIRESERVE)
return SectionHeaderTable->sh_link;
@@ -2457,62 +2490,44 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
return Header->e_shstrndx;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
template<typename T>
inline const T *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getEntry(uint16_t Section, uint32_t Entry) const {
+ELFObjectFile<ELFT>::getEntry(uint16_t Section, uint32_t Entry) const {
return getEntry<T>(getSection(Section), Entry);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+template<class ELFT>
template<typename T>
inline const T *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getEntry(const Elf_Shdr * Section, uint32_t Entry) const {
+ELFObjectFile<ELFT>::getEntry(const Elf_Shdr * Section, uint32_t Entry) const {
return reinterpret_cast<const T *>(
base()
+ Section->sh_offset
+ (Entry * Section->sh_entsize));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Sym *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbol(DataRefImpl Symb) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Sym *
+ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const {
return getEntry<Elf_Sym>(SymbolTableSections[Symb.d.b], Symb.d.a);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Dyn *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getDyn(DataRefImpl DynData) const {
- return getEntry<Elf_Dyn>(dot_dynamic_sec, DynData.d.a);
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Rel *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRel(DataRefImpl Rel) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rel *
+ELFObjectFile<ELFT>::getRel(DataRefImpl Rel) const {
return getEntry<Elf_Rel>(Rel.w.b, Rel.w.c);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Rela *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getRela(DataRefImpl Rela) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Rela *
+ELFObjectFile<ELFT>::getRela(DataRefImpl Rela) const {
return getEntry<Elf_Rela>(Rela.w.b, Rela.w.c);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSection(DataRefImpl Symb) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getSection(DataRefImpl Symb) const {
const Elf_Shdr *sec = getSection(Symb.d.b);
if (sec->sh_type != ELF::SHT_SYMTAB || sec->sh_type != ELF::SHT_DYNSYM)
// FIXME: Proper error handling.
@@ -2520,11 +2535,9 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
return sec;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const typename ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::Elf_Shdr *
-ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSection(uint32_t index) const {
+template<class ELFT>
+const typename ELFObjectFile<ELFT>::Elf_Shdr *
+ELFObjectFile<ELFT>::getSection(uint32_t index) const {
if (index == 0)
return 0;
if (!SectionHeaderTable || index >= getNumSections())
@@ -2536,17 +2549,15 @@ ELFObjectFile<target_endianness, max_alignment, is64Bits>
+ (index * Header->e_shentsize));
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const char *ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getString(uint32_t section,
- ELF::Elf32_Word offset) const {
+template<class ELFT>
+const char *ELFObjectFile<ELFT>::getString(uint32_t section,
+ ELF::Elf32_Word offset) const {
return getString(getSection(section), offset);
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-const char *ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getString(const Elf_Shdr *section,
- ELF::Elf32_Word offset) const {
+template<class ELFT>
+const char *ELFObjectFile<ELFT>::getString(const Elf_Shdr *section,
+ ELF::Elf32_Word offset) const {
assert(section && section->sh_type == ELF::SHT_STRTAB && "Invalid section!");
if (offset >= section->sh_size)
// FIXME: Proper error handling.
@@ -2554,11 +2565,10 @@ const char *ELFObjectFile<target_endianness, max_alignment, is64Bits>
return (const char *)base() + section->sh_offset + offset;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolName(const Elf_Shdr *section,
- const Elf_Sym *symb,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolName(const Elf_Shdr *section,
+ const Elf_Sym *symb,
+ StringRef &Result) const {
if (symb->st_name == 0) {
const Elf_Shdr *section = getSection(symb);
if (!section)
@@ -2578,20 +2588,18 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSectionName(const Elf_Shdr *section,
- StringRef &Result) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSectionName(const Elf_Shdr *section,
+ StringRef &Result) const {
Result = StringRef(getString(dot_shstrtab_sec, section->sh_name));
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
- ::getSymbolVersion(const Elf_Shdr *section,
- const Elf_Sym *symb,
- StringRef &Version,
- bool &IsDefault) const {
+template<class ELFT>
+error_code ELFObjectFile<ELFT>::getSymbolVersion(const Elf_Shdr *section,
+ const Elf_Sym *symb,
+ StringRef &Version,
+ bool &IsDefault) const {
// Handle non-dynamic symbols.
if (section != SymbolTableSections[0]) {
// Non-dynamic symbols can have versions in their names
@@ -2669,54 +2677,6 @@ error_code ELFObjectFile<target_endianness, max_alignment, is64Bits>
return object_error::success;
}
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::DynRefImpl(DataRefImpl DynP, const OwningType *Owner)
- : DynPimpl(DynP)
- , OwningObject(Owner) {}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline bool DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::operator==(const DynRefImpl &Other) const {
- return DynPimpl == Other.DynPimpl;
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline bool DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::operator <(const DynRefImpl &Other) const {
- return DynPimpl < Other.DynPimpl;
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline error_code DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::getNext(DynRefImpl &Result) const {
- return OwningObject->getDynNext(DynPimpl, Result);
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline int64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::getTag() const {
- return OwningObject->getDyn(DynPimpl)->d_tag;
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline uint64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::getVal() const {
- return OwningObject->getDyn(DynPimpl)->d_un.d_val;
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline uint64_t DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::getPtr() const {
- return OwningObject->getDyn(DynPimpl)->d_un.d_ptr;
-}
-
-template<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
-inline DataRefImpl DynRefImpl<target_endianness, max_alignment, is64Bits>
- ::getRawDataRefImpl() const {
- return DynPimpl;
-}
-
/// This is a generic interface for retrieving GNU symbol version
/// information from an ELFObjectFile.
static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
@@ -2724,23 +2684,23 @@ static inline error_code GetELFSymbolVersion(const ObjectFile *Obj,
StringRef &Version,
bool &IsDefault) {
// Little-endian 32-bit
- if (const ELFObjectFile<support::little, 4, false> *ELFObj =
- dyn_cast<ELFObjectFile<support::little, 4, false> >(Obj))
+ if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj =
+ dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Big-endian 32-bit
- if (const ELFObjectFile<support::big, 4, false> *ELFObj =
- dyn_cast<ELFObjectFile<support::big, 4, false> >(Obj))
+ if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj =
+ dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Little-endian 64-bit
- if (const ELFObjectFile<support::little, 8, true> *ELFObj =
- dyn_cast<ELFObjectFile<support::little, 8, true> >(Obj))
+ if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj =
+ dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
// Big-endian 64-bit
- if (const ELFObjectFile<support::big, 8, true> *ELFObj =
- dyn_cast<ELFObjectFile<support::big, 8, true> >(Obj))
+ if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj =
+ dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj))
return ELFObj->getSymbolVersion(Sym, Version, IsDefault);
llvm_unreachable("Object passed to GetELFSymbolVersion() is not ELF");
diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h
index a17d58d..ffca391 100644
--- a/include/llvm/Object/MachOFormat.h
+++ b/include/llvm/Object/MachOFormat.h
@@ -64,7 +64,10 @@ namespace mach {
CSARM_V7 = 9,
CSARM_V7F = 10,
CSARM_V7S = 11,
- CSARM_V7K = 12
+ CSARM_V7K = 12,
+ CSARM_V6M = 14,
+ CSARM_V7M = 15,
+ CSARM_V7EM = 16
};
/// \brief PowerPC Machine Subtypes.
@@ -145,7 +148,8 @@ namespace macho {
LCT_CodeSignature = 0x1d,
LCT_SegmentSplitInfo = 0x1e,
LCT_FunctionStarts = 0x26,
- LCT_DataInCode = 0x29
+ LCT_DataInCode = 0x29,
+ LCT_LinkerOptions = 0x2D
};
/// \brief Load command structure.
@@ -233,6 +237,14 @@ namespace macho {
uint32_t DataSize;
};
+ struct LinkerOptionsLoadCommand {
+ uint32_t Type;
+ uint32_t Size;
+ uint32_t Count;
+ // Load command is followed by Count number of zero-terminated UTF8 strings,
+ // and then zero-filled to be 4-byte aligned.
+ };
+
/// @}
/// @name Section Data
/// @{
diff --git a/include/llvm/Object/MachOObject.h b/include/llvm/Object/MachOObject.h
index e32a85d..9e4ab19 100644
--- a/include/llvm/Object/MachOObject.h
+++ b/include/llvm/Object/MachOObject.h
@@ -153,6 +153,9 @@ public:
void ReadLinkeditDataLoadCommand(
const LoadCommandInfo &LCI,
InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
+ void ReadLinkerOptionsLoadCommand(
+ const LoadCommandInfo &LCI,
+ InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
void ReadIndirectSymbolTableEntry(
const macho::DysymtabLoadCommand &DLC,
unsigned Index,
diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h
index e63f554..6a66653 100644
--- a/include/llvm/Object/ObjectFile.h
+++ b/include/llvm/Object/ObjectFile.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_OBJECT_OBJECT_FILE_H
-#define LLVM_OBJECT_OBJECT_FILE_H
+#ifndef LLVM_OBJECT_OBJECTFILE_H
+#define LLVM_OBJECT_OBJECTFILE_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/Binary.h"
diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h
index 2c2dd03..2dcbdf9 100644
--- a/include/llvm/Object/RelocVisitor.h
+++ b/include/llvm/Object/RelocVisitor.h
@@ -13,13 +13,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef _LLVM_OBJECT_RELOCVISITOR
-#define _LLVM_OBJECT_RELOCVISITOR
+#ifndef LLVM_OBJECT_RELOCVISITOR_H
+#define LLVM_OBJECT_RELOCVISITOR_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Object/ELF.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
namespace llvm {
@@ -40,7 +40,7 @@ struct RelocToApply {
/// @brief Base class for object file relocation visitors.
class RelocVisitor {
public:
- explicit RelocVisitor(llvm::StringRef FileFormat)
+ explicit RelocVisitor(StringRef FileFormat)
: FileFormat(FileFormat), HasError(false) {}
// TODO: Should handle multiple applied relocations via either passing in the
@@ -76,14 +76,41 @@ public:
HasError = true;
return RelocToApply();
}
+ } else if (FileFormat == "ELF64-ppc64") {
+ switch (RelocType) {
+ case llvm::ELF::R_PPC64_ADDR32:
+ return visitELF_PPC64_ADDR32(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF32-mips") {
+ switch (RelocType) {
+ case llvm::ELF::R_MIPS_32:
+ return visitELF_MIPS_32(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
+ } else if (FileFormat == "ELF64-aarch64") {
+ switch (RelocType) {
+ case llvm::ELF::R_AARCH64_ABS32:
+ return visitELF_AARCH64_ABS32(R, Value);
+ case llvm::ELF::R_AARCH64_ABS64:
+ return visitELF_AARCH64_ABS64(R, Value);
+ default:
+ HasError = true;
+ return RelocToApply();
+ }
}
+ HasError = true;
return RelocToApply();
}
bool error() { return HasError; }
private:
- llvm::StringRef FileFormat;
+ StringRef FileFormat;
bool HasError;
/// Operations
@@ -139,6 +166,42 @@ private:
int32_t Res = (Value + Addend) & 0xFFFFFFFF;
return RelocToApply(Res, 4);
}
+
+ /// PPC64 ELF
+ RelocToApply visitELF_PPC64_ADDR32(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+
+ /// MIPS ELF
+ RelocToApply visitELF_MIPS_32(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ uint32_t Res = (Value + Addend) & 0xFFFFFFFF;
+ return RelocToApply(Res, 4);
+ }
+
+ // AArch64 ELF
+ RelocToApply visitELF_AARCH64_ABS32(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ int64_t Res = Value + Addend;
+
+ // Overflow check allows for both signed and unsigned interpretation.
+ if (Res < INT32_MIN || Res > UINT32_MAX)
+ HasError = true;
+
+ return RelocToApply(static_cast<uint32_t>(Res), 4);
+ }
+
+ RelocToApply visitELF_AARCH64_ABS64(RelocationRef R, uint64_t Value) {
+ int64_t Addend;
+ R.getAdditionalInfo(Addend);
+ return RelocToApply(Value + Addend, 8);
+ }
+
};
}
diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h
index baa4b6a..6b8ed3f 100644
--- a/include/llvm/Option/Arg.h
+++ b/include/llvm/Option/Arg.h
@@ -12,8 +12,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_ARG_H_
-#define LLVM_SUPPORT_ARG_H_
+#ifndef LLVM_OPTION_ARG_H
+#define LLVM_OPTION_ARG_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index 378b58a..d3accfe 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_ARGLIST_H_
-#define LLVM_SUPPORT_ARGLIST_H_
+#ifndef LLVM_OPTION_ARGLIST_H
+#define LLVM_OPTION_ARGLIST_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h
index 3bc9bb2..02bc6b1 100644
--- a/include/llvm/Option/OptSpecifier.h
+++ b/include/llvm/Option/OptSpecifier.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_OPTSPECIFIER_H
-#define LLVM_SUPPORT_OPTSPECIFIER_H
+#ifndef LLVM_OPTION_OPTSPECIFIER_H
+#define LLVM_OPTION_OPTSPECIFIER_H
namespace llvm {
namespace opt {
@@ -19,7 +19,7 @@ namespace opt {
unsigned ID;
private:
- explicit OptSpecifier(bool); // DO NOT IMPLEMENT
+ explicit OptSpecifier(bool) LLVM_DELETED_FUNCTION;
public:
OptSpecifier() : ID(0) {}
diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h
index 930549f..a93acbf 100644
--- a/include/llvm/Option/OptTable.h
+++ b/include/llvm/Option/OptTable.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_OPTTABLE_H
-#define LLVM_SUPPORT_OPTTABLE_H
+#ifndef LLVM_OPTION_OPTTABLE_H
+#define LLVM_OPTION_OPTTABLE_H
#include "llvm/ADT/StringSet.h"
#include "llvm/Option/OptSpecifier.h"
diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h
index ee5eec4..541aa8d 100644
--- a/include/llvm/Option/Option.h
+++ b/include/llvm/Option/Option.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_OPTION_H_
-#define LLVM_SUPPORT_OPTION_H_
+#ifndef LLVM_OPTION_OPTION_H
+#define LLVM_OPTION_OPTION_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
index 1cc5741..a581802 100644
--- a/include/llvm/PassAnalysisSupport.h
+++ b/include/llvm/PassAnalysisSupport.h
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
-#define LLVM_PASS_ANALYSIS_SUPPORT_H
+#ifndef LLVM_PASSANALYSISSUPPORT_H
+#define LLVM_PASSANALYSISSUPPORT_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
index fac7928..7afb0a0 100644
--- a/include/llvm/PassManagers.h
+++ b/include/llvm/PassManagers.h
@@ -352,7 +352,7 @@ public:
return PMT_Unknown;
}
- std::map<AnalysisID, Pass*> *getAvailableAnalysis() {
+ DenseMap<AnalysisID, Pass*> *getAvailableAnalysis() {
return &AvailableAnalysis;
}
@@ -375,8 +375,7 @@ protected:
// Collection of Analysis provided by Parent pass manager and
// used by current pass manager. At at time there can not be more
// then PMT_Last active pass mangers.
- std::map<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
-
+ DenseMap<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
/// or higher is specified.
@@ -390,7 +389,7 @@ private:
// pass. If a pass requires an analysis which is not available then
// the required analysis pass is scheduled to run before the pass itself is
// scheduled to run.
- std::map<AnalysisID, Pass*> AvailableAnalysis;
+ DenseMap<AnalysisID, Pass*> AvailableAnalysis;
// Collection of higher level analysis used by the pass managed by
// this manager.
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
index 3633f47..ccc7934 100644
--- a/include/llvm/PassSupport.h
+++ b/include/llvm/PassSupport.h
@@ -18,8 +18,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_PASS_SUPPORT_H
-#define LLVM_PASS_SUPPORT_H
+#ifndef LLVM_PASSSUPPORT_H
+#define LLVM_PASSSUPPORT_H
#include "Pass.h"
#include "llvm/InitializePasses.h"
diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h
index 0894316..bba3424 100644
--- a/include/llvm/Support/AlignOf.h
+++ b/include/llvm/Support/AlignOf.h
@@ -169,17 +169,20 @@ LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128)
namespace detail {
template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char>
+ typename T2 = char, typename T3 = char, typename T4 = char,
+ typename T5 = char, typename T6 = char, typename T7 = char>
class AlignerImpl {
- T1 t1; T2 t2; T3 t3; T4 t4;
+ T1 t1; T2 t2; T3 t3; T4 t4; T5 t5; T6 t6; T7 t7;
AlignerImpl(); // Never defined or instantiated.
};
template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char>
+ typename T2 = char, typename T3 = char, typename T4 = char,
+ typename T5 = char, typename T6 = char, typename T7 = char>
union SizerImpl {
- char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)];
+ char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)],
+ arr5[sizeof(T5)], arr6[sizeof(T6)], arr7[sizeof(T7)];
};
} // end namespace detail
@@ -188,14 +191,14 @@ union SizerImpl {
///
/// These types may be arrays, structs, or any other types. The goal is to
/// expose a char array buffer member which can be used as suitable storage for
-/// a placement new of any of these types. Support for more than four types can
+/// a placement new of any of these types. Support for more than seven types can
/// be added at the cost of more boiler plate.
template <typename T1,
- typename T2 = char, typename T3 = char, typename T4 = char>
-struct AlignedCharArrayUnion :
- llvm::AlignedCharArray<AlignOf<detail::AlignerImpl<T1, T2, T3, T4> >
- ::Alignment,
- sizeof(detail::SizerImpl<T1, T2, T3, T4>)> {
+ typename T2 = char, typename T3 = char, typename T4 = char,
+ typename T5 = char, typename T6 = char, typename T7 = char>
+struct AlignedCharArrayUnion : llvm::AlignedCharArray<
+ AlignOf<detail::AlignerImpl<T1, T2, T3, T4, T5, T6, T7> >::Alignment,
+ sizeof(detail::SizerImpl<T1, T2, T3, T4, T5, T6, T7>)> {
};
} // end namespace llvm
#endif
diff --git a/include/llvm/Support/ArrayRecycler.h b/include/llvm/Support/ArrayRecycler.h
index 0fbe79c..c7e0cba 100644
--- a/include/llvm/Support/ArrayRecycler.h
+++ b/include/llvm/Support/ArrayRecycler.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_ARRAY_RECYCLER_H
-#define LLVM_SUPPORT_ARRAY_RECYCLER_H
+#ifndef LLVM_SUPPORT_ARRAYRECYCLER_H
+#define LLVM_SUPPORT_ARRAYRECYCLER_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MathExtras.h"
diff --git a/include/llvm/Support/Atomic.h b/include/llvm/Support/Atomic.h
index 1a6c606..9ec23e8 100644
--- a/include/llvm/Support/Atomic.h
+++ b/include/llvm/Support/Atomic.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_ATOMIC_H
-#define LLVM_SYSTEM_ATOMIC_H
+#ifndef LLVM_SUPPORT_ATOMIC_H
+#define LLVM_SUPPORT_ATOMIC_H
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/COFF.h b/include/llvm/Support/COFF.h
index ba8adb0..02c44cd 100644
--- a/include/llvm/Support/COFF.h
+++ b/include/llvm/Support/COFF.h
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_WIN_COFF_H
-#define LLVM_SUPPORT_WIN_COFF_H
+#ifndef LLVM_SUPPORT_COFF_H
+#define LLVM_SUPPORT_COFF_H
#include "llvm/Support/DataTypes.h"
#include <cassert>
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
index 0c71882..80f09db 100644
--- a/include/llvm/Support/Casting.h
+++ b/include/llvm/Support/Casting.h
@@ -55,8 +55,8 @@ struct isa_impl {
/// \brief Always allow upcasts, and perform no dynamic check for them.
template <typename To, typename From>
struct isa_impl<To, From,
- typename llvm::enable_if_c<
- llvm::is_base_of<To, From>::value
+ typename enable_if<
+ llvm::is_base_of<To, From>
>::type
> {
static inline bool doit(const From &) { return true; }
@@ -204,12 +204,35 @@ template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
// cast<Instruction>(myVal)->getParent()
//
template <class X, class Y>
-inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
+inline typename enable_if_c<
+ !is_same<Y, typename simplify_type<Y>::SimpleType>::value,
+ typename cast_retty<X, Y>::ret_type
+>::type cast(const Y &Val) {
assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
return cast_convert_val<X, Y,
typename simplify_type<Y>::SimpleType>::doit(Val);
}
+template <class X, class Y>
+inline typename enable_if<
+ is_same<Y, typename simplify_type<Y>::SimpleType>,
+ typename cast_retty<X, Y>::ret_type
+>::type cast(Y &Val) {
+ assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+ return cast_convert_val<X, Y,
+ typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+template <class X, class Y>
+inline typename enable_if<
+ is_same<Y, typename simplify_type<Y>::SimpleType>,
+ typename cast_retty<X, Y*>::ret_type
+>::type cast(Y *Val) {
+ assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+ return cast_convert_val<X, Y*,
+ typename simplify_type<Y*>::SimpleType>::doit(Val);
+}
+
// cast_or_null<X> - Functionally identical to cast, except that a null value is
// accepted.
//
@@ -230,8 +253,27 @@ inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
//
template <class X, class Y>
-inline typename cast_retty<X, Y>::ret_type dyn_cast(const Y &Val) {
- return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+inline typename enable_if_c<
+ !is_same<Y, typename simplify_type<Y>::SimpleType>::value,
+ typename cast_retty<X, Y>::ret_type
+>::type dyn_cast(const Y &Val) {
+ return isa<X>(Val) ? cast<X>(Val) : 0;
+}
+
+template <class X, class Y>
+inline typename enable_if<
+ is_same<Y, typename simplify_type<Y>::SimpleType>,
+ typename cast_retty<X, Y>::ret_type
+>::type dyn_cast(Y &Val) {
+ return isa<X>(Val) ? cast<X>(Val) : 0;
+}
+
+template <class X, class Y>
+inline typename enable_if<
+ is_same<Y, typename simplify_type<Y>::SimpleType>,
+ typename cast_retty<X, Y*>::ret_type
+>::type dyn_cast(Y *Val) {
+ return isa<X>(Val) ? cast<X>(Val) : 0;
}
// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 0ab39fc..bf7823e 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -469,8 +469,7 @@ public:
template<class Opt>
void apply(Opt &O) const {
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
Values[i].second.second);
}
@@ -629,8 +628,7 @@ public:
else
ArgVal = ArgName;
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
if (Values[i].Name == ArgVal) {
V = Values[i].V.getValue();
return false;
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
index b32939e..25f42a9 100644
--- a/include/llvm/Support/Compiler.h
+++ b/include/llvm/Support/Compiler.h
@@ -15,6 +15,8 @@
#ifndef LLVM_SUPPORT_COMPILER_H
#define LLVM_SUPPORT_COMPILER_H
+#include "llvm/Config/llvm-config.h"
+
#ifndef __has_feature
# define __has_feature(x) 0
#endif
@@ -42,6 +44,43 @@
#define LLVM_HAS_RVALUE_REFERENCE_THIS 0
#endif
+/// \macro LLVM_HAS_CXX11_TYPETRAITS
+/// \brief Does the compiler have the C++11 type traits.
+///
+/// #include <type_traits>
+///
+/// * enable_if
+/// * {true,false}_type
+/// * is_constructible
+/// * etc...
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
+ || (defined(_MSC_VER) && _MSC_VER >= 1700)
+#define LLVM_HAS_CXX11_TYPETRAITS 1
+#else
+#define LLVM_HAS_CXX11_TYPETRAITS 0
+#endif
+
+/// \macro LLVM_HAS_CXX11_STDLIB
+/// \brief Does the compiler have the C++11 standard library.
+///
+/// Implies LLVM_HAS_RVALUE_REFERENCES, LLVM_HAS_CXX11_TYPETRAITS
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) \
+ || (defined(_MSC_VER) && _MSC_VER >= 1700)
+#define LLVM_HAS_CXX11_STDLIB 1
+#else
+#define LLVM_HAS_CXX11_STDLIB 0
+#endif
+
+/// \macro LLVM_HAS_VARIADIC_TEMPLATES
+/// \brief Does this compiler support variadic templates.
+///
+/// Implies LLVM_HAS_RVALUE_REFERENCES and the existence of std::forward.
+#if __has_feature(cxx_variadic_templates)
+# define LLVM_HAS_VARIADIC_TEMPLATES 1
+#else
+# define LLVM_HAS_VARIADIC_TEMPLATES 0
+#endif
+
/// llvm_move - Expands to ::std::move if the compiler supports
/// r-value references; otherwise, expands to the argument.
#if LLVM_HAS_RVALUE_REFERENCES
@@ -81,7 +120,8 @@
/// LLVM_FINAL - Expands to 'final' if the compiler supports it.
/// Use to mark classes or virtual methods as final.
-#if (__has_feature(cxx_override_control))
+#if __has_feature(cxx_override_control) \
+ || (defined(_MSC_VER) && _MSC_VER >= 1700)
#define LLVM_FINAL final
#else
#define LLVM_FINAL
@@ -89,12 +129,19 @@
/// LLVM_OVERRIDE - Expands to 'override' if the compiler supports it.
/// Use to mark virtual methods as overriding a base class method.
-#if (__has_feature(cxx_override_control))
+#if __has_feature(cxx_override_control) \
+ || (defined(_MSC_VER) && _MSC_VER >= 1700)
#define LLVM_OVERRIDE override
#else
#define LLVM_OVERRIDE
#endif
+#if __has_feature(cxx_constexpr) || defined(__GXX_EXPERIMENTAL_CXX0X__)
+# define LLVM_CONSTEXPR constexpr
+#else
+# define LLVM_CONSTEXPR
+#endif
+
/// LLVM_LIBRARY_VISIBILITY - If a class marked with this attribute is linked
/// into a shared library, then the class should be private to the library and
/// not accessible from outside it. Can also be used to mark variables and
@@ -249,4 +296,59 @@
# define LLVM_ASSUME_ALIGNED(p, a) (p)
#endif
+/// \macro LLVM_FUNCTION_NAME
+/// \brief Expands to __func__ on compilers which support it. Otherwise,
+/// expands to a compiler-dependent replacement.
+#if defined(_MSC_VER)
+# define LLVM_FUNCTION_NAME __FUNCTION__
+#else
+# define LLVM_FUNCTION_NAME __func__
+#endif
+
+#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H)
+# include <sanitizer/msan_interface.h>
+#else
+# define __msan_allocated_memory(p, size)
+# define __msan_unpoison(p, size)
+#endif
+
+/// \macro LLVM_MEMORY_SANITIZER_BUILD
+/// \brief Whether LLVM itself is built with MemorySanitizer instrumentation.
+#if __has_feature(memory_sanitizer)
+# define LLVM_MEMORY_SANITIZER_BUILD 1
+#else
+# define LLVM_MEMORY_SANITIZER_BUILD 0
+#endif
+
+/// \macro LLVM_ADDRESS_SANITIZER_BUILD
+/// \brief Whether LLVM itself is built with AddressSanitizer instrumentation.
+#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+# define LLVM_ADDRESS_SANITIZER_BUILD 1
+#else
+# define LLVM_ADDRESS_SANITIZER_BUILD 0
+#endif
+
+/// \macro LLVM_IS_UNALIGNED_ACCESS_FAST
+/// \brief Is unaligned memory access fast on the host machine.
+///
+/// Don't specialize on alignment for platforms where unaligned memory accesses
+/// generates the same code as aligned memory accesses for common types.
+#if defined(_M_AMD64) || defined(_M_IX86) || defined(__amd64) || \
+ defined(__amd64__) || defined(__x86_64) || defined(__x86_64__) || \
+ defined(_X86_) || defined(__i386) || defined(__i386__)
+# define LLVM_IS_UNALIGNED_ACCESS_FAST 1
+#else
+# define LLVM_IS_UNALIGNED_ACCESS_FAST 0
+#endif
+
+/// \macro LLVM_EXPLICIT
+/// \brief Expands to explicit on compilers which support explicit conversion
+/// operators. Otherwise expands to nothing.
+#if (__has_feature(cxx_explicit_conversions) \
+ || defined(__GXX_EXPERIMENTAL_CXX0X__))
+#define LLVM_EXPLICIT explicit
+#else
+#define LLVM_EXPLICIT
+#endif
+
#endif
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
index 90dd69f..0f29256 100644
--- a/include/llvm/Support/ConstantRange.h
+++ b/include/llvm/Support/ConstantRange.h
@@ -29,8 +29,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
-#define LLVM_SUPPORT_CONSTANT_RANGE_H
+#ifndef LLVM_SUPPORT_CONSTANTRANGE_H
+#define LLVM_SUPPORT_CONSTANTRANGE_H
#include "llvm/ADT/APInt.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/ConvertUTF.h b/include/llvm/Support/ConvertUTF.h
new file mode 100644
index 0000000..1eae6d6
--- /dev/null
+++ b/include/llvm/Support/ConvertUTF.h
@@ -0,0 +1,228 @@
+/*===--- ConvertUTF.h - Universal Character Names conversions ---------------===
+ *
+ * The LLVM Compiler Infrastructure
+ *
+ * This file is distributed under the University of Illinois Open Source
+ * License. See LICENSE.TXT for details.
+ *
+ *==------------------------------------------------------------------------==*/
+/*
+ * Copyright 2001-2004 Unicode, Inc.
+ *
+ * Disclaimer
+ *
+ * This source code is provided as is by Unicode, Inc. No claims are
+ * made as to fitness for any particular purpose. No warranties of any
+ * kind are expressed or implied. The recipient agrees to determine
+ * applicability of information provided. If this file has been
+ * purchased on magnetic or optical media from Unicode, Inc., the
+ * sole remedy for any claim will be exchange of defective media
+ * within 90 days of receipt.
+ *
+ * Limitations on Rights to Redistribute This Code
+ *
+ * Unicode, Inc. hereby grants the right to freely use the information
+ * supplied in this file in the creation of products supporting the
+ * Unicode Standard, and to make copies of this file in any form
+ * for internal or external distribution as long as this notice
+ * remains attached.
+ */
+
+/* ---------------------------------------------------------------------
+
+ Conversions between UTF32, UTF-16, and UTF-8. Header file.
+
+ Several funtions are included here, forming a complete set of
+ conversions between the three formats. UTF-7 is not included
+ here, but is handled in a separate source file.
+
+ Each of these routines takes pointers to input buffers and output
+ buffers. The input buffers are const.
+
+ Each routine converts the text between *sourceStart and sourceEnd,
+ putting the result into the buffer between *targetStart and
+ targetEnd. Note: the end pointers are *after* the last item: e.g.
+ *(sourceEnd - 1) is the last item.
+
+ The return result indicates whether the conversion was successful,
+ and if not, whether the problem was in the source or target buffers.
+ (Only the first encountered problem is indicated.)
+
+ After the conversion, *sourceStart and *targetStart are both
+ updated to point to the end of last text successfully converted in
+ the respective buffers.
+
+ Input parameters:
+ sourceStart - pointer to a pointer to the source buffer.
+ The contents of this are modified on return so that
+ it points at the next thing to be converted.
+ targetStart - similarly, pointer to pointer to the target buffer.
+ sourceEnd, targetEnd - respectively pointers to the ends of the
+ two buffers, for overflow checking only.
+
+ These conversion functions take a ConversionFlags argument. When this
+ flag is set to strict, both irregular sequences and isolated surrogates
+ will cause an error. When the flag is set to lenient, both irregular
+ sequences and isolated surrogates are converted.
+
+ Whether the flag is strict or lenient, all illegal sequences will cause
+ an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>,
+ or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code
+ must check for illegal sequences.
+
+ When the flag is set to lenient, characters over 0x10FFFF are converted
+ to the replacement character; otherwise (when the flag is set to strict)
+ they constitute an error.
+
+ Output parameters:
+ The value "sourceIllegal" is returned from some routines if the input
+ sequence is malformed. When "sourceIllegal" is returned, the source
+ value will point to the illegal value that caused the problem. E.g.,
+ in UTF-8 when a sequence is malformed, it points to the start of the
+ malformed sequence.
+
+ Author: Mark E. Davis, 1994.
+ Rev History: Rick McGowan, fixes & updates May 2001.
+ Fixes & updates, Sept 2001.
+
+------------------------------------------------------------------------ */
+
+#ifndef CLANG_BASIC_CONVERTUTF_H
+#define CLANG_BASIC_CONVERTUTF_H
+
+/* ---------------------------------------------------------------------
+ The following 4 definitions are compiler-specific.
+ The C standard does not guarantee that wchar_t has at least
+ 16 bits, so wchar_t is no less portable than unsigned short!
+ All should be unsigned values to avoid sign extension during
+ bit mask & shift operations.
+------------------------------------------------------------------------ */
+
+typedef unsigned int UTF32; /* at least 32 bits */
+typedef unsigned short UTF16; /* at least 16 bits */
+typedef unsigned char UTF8; /* typically 8 bits */
+typedef unsigned char Boolean; /* 0 or 1 */
+
+/* Some fundamental constants */
+#define UNI_REPLACEMENT_CHAR (UTF32)0x0000FFFD
+#define UNI_MAX_BMP (UTF32)0x0000FFFF
+#define UNI_MAX_UTF16 (UTF32)0x0010FFFF
+#define UNI_MAX_UTF32 (UTF32)0x7FFFFFFF
+#define UNI_MAX_LEGAL_UTF32 (UTF32)0x0010FFFF
+
+#define UNI_MAX_UTF8_BYTES_PER_CODE_POINT 4
+
+typedef enum {
+ conversionOK, /* conversion successful */
+ sourceExhausted, /* partial character in source, but hit end */
+ targetExhausted, /* insuff. room in target for conversion */
+ sourceIllegal /* source sequence is illegal/malformed */
+} ConversionResult;
+
+typedef enum {
+ strictConversion = 0,
+ lenientConversion
+} ConversionFlags;
+
+/* This is for C++ and does no harm in C */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ConversionResult ConvertUTF8toUTF16 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF8toUTF32 (
+ const UTF8** sourceStart, const UTF8* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF8 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF8 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF8** targetStart, UTF8* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF16toUTF32 (
+ const UTF16** sourceStart, const UTF16* sourceEnd,
+ UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags);
+
+ConversionResult ConvertUTF32toUTF16 (
+ const UTF32** sourceStart, const UTF32* sourceEnd,
+ UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags);
+
+Boolean isLegalUTF8Sequence(const UTF8 *source, const UTF8 *sourceEnd);
+
+Boolean isLegalUTF8String(const UTF8 **source, const UTF8 *sourceEnd);
+
+unsigned getNumBytesForUTF8(UTF8 firstByte);
+
+#ifdef __cplusplus
+}
+
+/*************************************************************************/
+/* Below are LLVM-specific wrappers of the functions above. */
+
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+
+/**
+ * Convert an UTF8 StringRef to UTF8, UTF16, or UTF32 depending on
+ * WideCharWidth. The converted data is written to ResultPtr, which needs to
+ * point to at least WideCharWidth * (Source.Size() + 1) bytes. On success,
+ * ResultPtr will point one after the end of the copied string. On failure,
+ * ResultPtr will not be changed, and ErrorPtr will be set to the location of
+ * the first character which could not be converted.
+ * \return true on success.
+ */
+bool ConvertUTF8toWide(unsigned WideCharWidth, llvm::StringRef Source,
+ char *&ResultPtr, const UTF8 *&ErrorPtr);
+
+/**
+ * Convert an Unicode code point to UTF8 sequence.
+ *
+ * \param Source a Unicode code point.
+ * \param [in,out] ResultPtr pointer to the output buffer, needs to be at least
+ * \c UNI_MAX_UTF8_BYTES_PER_CODE_POINT bytes. On success \c ResultPtr is
+ * updated one past end of the converted sequence.
+ *
+ * \returns true on success.
+ */
+bool ConvertCodePointToUTF8(unsigned Source, char *&ResultPtr);
+
+/**
+ * Convert the first UTF8 sequence in the given source buffer to a UTF32
+ * code point.
+ *
+ * \param [in,out] source A pointer to the source buffer. If the conversion
+ * succeeds, this pointer will be updated to point to the byte just past the
+ * end of the converted sequence.
+ * \param sourceEnd A pointer just past the end of the source buffer.
+ * \param [out] target The converted code
+ * \param flags Whether the conversion is strict or lenient.
+ *
+ * \returns conversionOK on success
+ *
+ * \sa ConvertUTF8toUTF32
+ */
+static inline ConversionResult convertUTF8Sequence(const UTF8 **source,
+ const UTF8 *sourceEnd,
+ UTF32 *target,
+ ConversionFlags flags) {
+ if (*source == sourceEnd)
+ return sourceExhausted;
+ unsigned size = getNumBytesForUTF8(**source);
+ if ((ptrdiff_t)size > sourceEnd - *source)
+ return sourceExhausted;
+ return ConvertUTF8toUTF32(source, *source + size, &target, target + 1, flags);
+}
+} /* end namespace llvm */
+
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#endif
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
index 483f267..95e37c0 100644
--- a/include/llvm/Support/DOTGraphTraits.h
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -79,6 +79,11 @@ public:
return false;
}
+ template<typename GraphType>
+ static std::string getNodeDescription(const void *, const GraphType &) {
+ return "";
+ }
+
/// If you want to specify custom node attributes, this is the place to do so
///
template<typename GraphType>
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index a3ae782..e8a19cd 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -18,22 +18,24 @@ namespace llvm {
class DataExtractor {
StringRef Data;
uint8_t IsLittleEndian;
- uint8_t PointerSize;
+ uint8_t AddressSize;
public:
/// Construct with a buffer that is owned by the caller.
///
/// This constructor allows us to use data that is owned by the
/// caller. The data must stay around as long as this object is
/// valid.
- DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t PointerSize)
- : Data(Data), IsLittleEndian(IsLittleEndian), PointerSize(PointerSize) {}
+ DataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize)
+ : Data(Data), IsLittleEndian(IsLittleEndian), AddressSize(AddressSize) {}
- /// getData - Get the data pointed to by this extractor.
+ /// \brief Get the data pointed to by this extractor.
StringRef getData() const { return Data; }
- /// isLittleEndian - Get the endianess for this extractor.
+ /// \brief Get the endianess for this extractor.
bool isLittleEndian() const { return IsLittleEndian; }
- /// getAddressSize - Get the address size for this extractor.
- uint8_t getAddressSize() const { return PointerSize; }
+ /// \brief Get the address size for this extractor.
+ uint8_t getAddressSize() const { return AddressSize; }
+ /// \brief Set the address size for this extractor.
+ void setAddressSize(uint8_t Size) { AddressSize = Size; }
/// Extract a C string from \a *offset_ptr.
///
@@ -113,7 +115,7 @@ public:
///
/// Extract a single pointer from the data and update the offset
/// pointed to by \a offset_ptr. The size of the extracted pointer
- /// comes from the \a m_addr_size member variable and should be
+ /// is \a getAddressSize(), so the address size has to be
/// set correctly prior to extracting any pointer values.
///
/// @param[in,out] offset_ptr
@@ -126,7 +128,7 @@ public:
/// @return
/// The extracted pointer value as a 64 integer.
uint64_t getAddress(uint32_t *offset_ptr) const {
- return getUnsigned(offset_ptr, PointerSize);
+ return getUnsigned(offset_ptr, AddressSize);
}
/// Extract a uint8_t value from \a *offset_ptr.
diff --git a/include/llvm/Support/DataStream.h b/include/llvm/Support/DataStream.h
index fedb0c9..8bc4133 100644
--- a/include/llvm/Support/DataStream.h
+++ b/include/llvm/Support/DataStream.h
@@ -14,8 +14,8 @@
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_DATASTREAM_H_
-#define LLVM_SUPPORT_DATASTREAM_H_
+#ifndef LLVM_SUPPORT_DATASTREAM_H
+#define LLVM_SUPPORT_DATASTREAM_H
#include <string>
diff --git a/include/llvm/Support/DebugLoc.h b/include/llvm/Support/DebugLoc.h
index 0498075..3596be8 100644
--- a/include/llvm/Support/DebugLoc.h
+++ b/include/llvm/Support/DebugLoc.h
@@ -109,4 +109,4 @@ namespace llvm {
};
} // end namespace llvm
-#endif /* LLVM_DEBUGLOC_H */
+#endif /* LLVM_SUPPORT_DEBUGLOC_H */
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
index c703da5..b52914f 100644
--- a/include/llvm/Support/Dwarf.h
+++ b/include/llvm/Support/Dwarf.h
@@ -16,6 +16,9 @@
#ifndef LLVM_SUPPORT_DWARF_H
#define LLVM_SUPPORT_DWARF_H
+#include "llvm/Support/DataTypes.h"
+
+
namespace llvm {
//===----------------------------------------------------------------------===//
@@ -53,10 +56,16 @@ enum llvm_dwarf_constants {
DW_TAG_user_base = 0x1000, // Recommended base for user tags.
- DW_CIE_VERSION = 1, // Common frame information version.
- DW_CIE_ID = 0xffffffff // Common frame information mark.
+ DW_CIE_VERSION = 1 // Common frame information version.
};
+
+// Special ID values that distinguish a CIE from a FDE in DWARF CFI.
+// Not inside an enum because a 64-bit value is needed.
+const uint32_t DW_CIE_ID = UINT32_MAX;
+const uint64_t DW64_CIE_ID = UINT64_MAX;
+
+
enum dwarf_constants {
DWARF_VERSION = 2,
diff --git a/include/llvm/Support/DynamicLibrary.h b/include/llvm/Support/DynamicLibrary.h
index 0f59cbf..1e2d16c 100644
--- a/include/llvm/Support/DynamicLibrary.h
+++ b/include/llvm/Support/DynamicLibrary.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
-#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#ifndef LLVM_SYSTEM_DYNAMICLIBRARY_H
+#define LLVM_SYSTEM_DYNAMICLIBRARY_H
#include <string>
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index d6e54be..8e6b91e 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -271,6 +271,7 @@ enum {
EM_SLE9X = 179, // Infineon Technologies SLE9X core
EM_L10M = 180, // Intel L10M
EM_K10M = 181, // Intel K10M
+ EM_AARCH64 = 183, // ARM AArch64
EM_AVR32 = 185, // Atmel Corporation 32-bit microprocessor family
EM_STM8 = 186, // STMicroeletronics STM8 8-bit microcontroller
EM_TILE64 = 187, // Tilera TILE64 multicore architecture family
@@ -366,7 +367,8 @@ enum {
R_X86_64_SIZE64 = 33,
R_X86_64_GOTPC32_TLSDESC = 34,
R_X86_64_TLSDESC_CALL = 35,
- R_X86_64_TLSDESC = 36
+ R_X86_64_TLSDESC = 36,
+ R_X86_64_IRELATIVE = 37
};
// i386 relocations.
@@ -469,6 +471,7 @@ enum {
R_PPC64_ADDR16_HI = 5,
R_PPC64_ADDR14 = 7,
R_PPC64_REL24 = 10,
+ R_PPC64_REL32 = 26,
R_PPC64_ADDR64 = 38,
R_PPC64_ADDR16_HIGHER = 39,
R_PPC64_ADDR16_HIGHEST = 41,
@@ -480,6 +483,7 @@ enum {
R_PPC64_TOC16_DS = 63,
R_PPC64_TOC16_LO_DS = 64,
R_PPC64_TLS = 67,
+ R_PPC64_TPREL16_LO = 70,
R_PPC64_DTPREL16_LO = 75,
R_PPC64_DTPREL16_HA = 77,
R_PPC64_GOT_TLSGD16_LO = 80,
@@ -492,8 +496,106 @@ enum {
R_PPC64_TLSLD = 108
};
+// ELF Relocation types for AArch64
+
+enum {
+ R_AARCH64_NONE = 0x100,
+
+ R_AARCH64_ABS64 = 0x101,
+ R_AARCH64_ABS32 = 0x102,
+ R_AARCH64_ABS16 = 0x103,
+ R_AARCH64_PREL64 = 0x104,
+ R_AARCH64_PREL32 = 0x105,
+ R_AARCH64_PREL16 = 0x106,
+
+ R_AARCH64_MOVW_UABS_G0 = 0x107,
+ R_AARCH64_MOVW_UABS_G0_NC = 0x108,
+ R_AARCH64_MOVW_UABS_G1 = 0x109,
+ R_AARCH64_MOVW_UABS_G1_NC = 0x10a,
+ R_AARCH64_MOVW_UABS_G2 = 0x10b,
+ R_AARCH64_MOVW_UABS_G2_NC = 0x10c,
+ R_AARCH64_MOVW_UABS_G3 = 0x10d,
+ R_AARCH64_MOVW_SABS_G0 = 0x10e,
+ R_AARCH64_MOVW_SABS_G1 = 0x10f,
+ R_AARCH64_MOVW_SABS_G2 = 0x110,
+
+ R_AARCH64_LD_PREL_LO19 = 0x111,
+ R_AARCH64_ADR_PREL_LO21 = 0x112,
+ R_AARCH64_ADR_PREL_PG_HI21 = 0x113,
+ R_AARCH64_ADD_ABS_LO12_NC = 0x115,
+ R_AARCH64_LDST8_ABS_LO12_NC = 0x116,
+
+ R_AARCH64_TSTBR14 = 0x117,
+ R_AARCH64_CONDBR19 = 0x118,
+ R_AARCH64_JUMP26 = 0x11a,
+ R_AARCH64_CALL26 = 0x11b,
+
+ R_AARCH64_LDST16_ABS_LO12_NC = 0x11c,
+ R_AARCH64_LDST32_ABS_LO12_NC = 0x11d,
+ R_AARCH64_LDST64_ABS_LO12_NC = 0x11e,
+
+ R_AARCH64_LDST128_ABS_LO12_NC = 0x12b,
+
+ R_AARCH64_ADR_GOT_PAGE = 0x137,
+ R_AARCH64_LD64_GOT_LO12_NC = 0x138,
+
+ R_AARCH64_TLSLD_MOVW_DTPREL_G2 = 0x20b,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G1 = 0x20c,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC = 0x20d,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G0 = 0x20e,
+ R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC = 0x20f,
+ R_AARCH64_TLSLD_ADD_DTPREL_HI12 = 0x210,
+ R_AARCH64_TLSLD_ADD_DTPREL_LO12 = 0x211,
+ R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC = 0x212,
+ R_AARCH64_TLSLD_LDST8_DTPREL_LO12 = 0x213,
+ R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC = 0x214,
+ R_AARCH64_TLSLD_LDST16_DTPREL_LO12 = 0x215,
+ R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC = 0x216,
+ R_AARCH64_TLSLD_LDST32_DTPREL_LO12 = 0x217,
+ R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC = 0x218,
+ R_AARCH64_TLSLD_LDST64_DTPREL_LO12 = 0x219,
+ R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC = 0x21a,
+
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 = 0x21b,
+ R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC = 0x21c,
+ R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 = 0x21d,
+ R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC = 0x21e,
+ R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 = 0x21f,
+
+ R_AARCH64_TLSLE_MOVW_TPREL_G2 = 0x220,
+ R_AARCH64_TLSLE_MOVW_TPREL_G1 = 0x221,
+ R_AARCH64_TLSLE_MOVW_TPREL_G1_NC = 0x222,
+ R_AARCH64_TLSLE_MOVW_TPREL_G0 = 0x223,
+ R_AARCH64_TLSLE_MOVW_TPREL_G0_NC = 0x224,
+ R_AARCH64_TLSLE_ADD_TPREL_HI12 = 0x225,
+ R_AARCH64_TLSLE_ADD_TPREL_LO12 = 0x226,
+ R_AARCH64_TLSLE_ADD_TPREL_LO12_NC = 0x227,
+ R_AARCH64_TLSLE_LDST8_TPREL_LO12 = 0x228,
+ R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC = 0x229,
+ R_AARCH64_TLSLE_LDST16_TPREL_LO12 = 0x22a,
+ R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC = 0x22b,
+ R_AARCH64_TLSLE_LDST32_TPREL_LO12 = 0x22c,
+ R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC = 0x22d,
+ R_AARCH64_TLSLE_LDST64_TPREL_LO12 = 0x22e,
+ R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC = 0x22f,
+
+ R_AARCH64_TLSDESC_ADR_PAGE = 0x232,
+ R_AARCH64_TLSDESC_LD64_LO12_NC = 0x233,
+ R_AARCH64_TLSDESC_ADD_LO12_NC = 0x234,
+
+ R_AARCH64_TLSDESC_CALL = 0x239
+};
+
// ARM Specific e_flags
-enum { EF_ARM_EABIMASK = 0xFF000000U };
+enum {
+ EF_ARM_EABI_UNKNOWN = 0x00000000U,
+ EF_ARM_EABI_VER1 = 0x01000000U,
+ EF_ARM_EABI_VER2 = 0x02000000U,
+ EF_ARM_EABI_VER3 = 0x03000000U,
+ EF_ARM_EABI_VER4 = 0x04000000U,
+ EF_ARM_EABI_VER5 = 0x05000000U,
+ EF_ARM_EABIMASK = 0xFF000000U
+};
// ELF Relocation types for ARM
// Meets 2.08 ABI Specs.
@@ -637,6 +739,13 @@ enum {
EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
EF_MIPS_PIC = 0x00000002, // Position independent code
EF_MIPS_CPIC = 0x00000004, // Call object with Position independent code
+ EF_MIPS_ABI_O32 = 0x00001000, // This file follows the first MIPS 32 bit ABI
+
+ //ARCH_ASE
+ EF_MIPS_MICROMIPS = 0x02000000, // microMIPS
+ EF_MIPS_ARCH_ASE_M16 =
+ 0x04000000, // Has Mips-16 ISA extensions
+ //ARCH
EF_MIPS_ARCH_1 = 0x00000000, // MIPS1 instruction set
EF_MIPS_ARCH_2 = 0x10000000, // MIPS2 instruction set
EF_MIPS_ARCH_3 = 0x20000000, // MIPS3 instruction set
@@ -707,6 +816,11 @@ enum {
R_MIPS_NUM = 218
};
+// Special values for the st_other field in the symbol table entry for MIPS.
+enum {
+ STO_MIPS_MICROMIPS = 0x80 // MIPS Specific ISA for MicroMips
+};
+
// Hexagon Specific e_flags
// Release 5 ABI
enum {
@@ -726,14 +840,14 @@ enum {
};
// Hexagon specific Section indexes for common small data
-// Release 5 ABI
+// Release 5 ABI
enum {
SHN_HEXAGON_SCOMMON = 0xff00, // Other access sizes
SHN_HEXAGON_SCOMMON_1 = 0xff01, // Byte-sized access
SHN_HEXAGON_SCOMMON_2 = 0xff02, // Half-word-sized access
SHN_HEXAGON_SCOMMON_4 = 0xff03, // Word-sized access
SHN_HEXAGON_SCOMMON_8 = 0xff04 // Double-word-size access
-};
+};
// ELF Relocation types for Hexagon
// Release 5 ABI
@@ -894,8 +1008,7 @@ enum {
SHT_GNU_verneed = 0x6ffffffe, // GNU version references.
SHT_GNU_versym = 0x6fffffff, // GNU symbol versions table.
SHT_HIOS = 0x6fffffff, // Highest operating system-specific type.
- SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
-
+ SHT_LOPROC = 0x70000000, // Lowest processor arch-specific type.
// Fixme: All this is duplicated in MCSectionELF. Why??
// Exception Index table
SHT_ARM_EXIDX = 0x70000001U,
@@ -905,10 +1018,14 @@ enum {
SHT_ARM_ATTRIBUTES = 0x70000003U,
SHT_ARM_DEBUGOVERLAY = 0x70000004U,
SHT_ARM_OVERLAYSECTION = 0x70000005U,
-
+ SHT_HEX_ORDERED = 0x70000000, // Link editor is to sort the entries in
+ // this section based on their sizes
SHT_X86_64_UNWIND = 0x70000001, // Unwind information
- SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_MIPS_REGINFO = 0x70000006, // Register usage information
+ SHT_MIPS_OPTIONS = 0x7000000d, // General options
+
+ SHT_HIPROC = 0x7fffffff, // Highest processor arch-specific type.
SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
};
@@ -970,7 +1087,14 @@ enum {
// sets this flag besides being able to refer to data in a section that does
// not set it; likewise, a small code model object can refer only to code in a
// section that does not set this flag.
- SHF_X86_64_LARGE = 0x10000000
+ SHF_X86_64_LARGE = 0x10000000,
+
+ // All sections with the GPREL flag are grouped into a global data area
+ // for faster accesses
+ SHF_HEX_GPREL = 0x10000000,
+
+ // Do not strip this section. FIXME: We need target specific SHF_ enums.
+ SHF_MIPS_NOSTRIP = 0x8000000
};
// Section Group Flags
@@ -1005,7 +1129,7 @@ struct Elf64_Sym {
Elf64_Word st_name; // Symbol name (index into string table)
unsigned char st_info; // Symbol's type and binding attributes
unsigned char st_other; // Must be zero; reserved
- Elf64_Half st_shndx; // Which section (header table index) it's defined in
+ Elf64_Half st_shndx; // Which section (header tbl index) it's defined in
Elf64_Addr st_value; // Value or address associated with the symbol
Elf64_Xword st_size; // Size of the symbol
@@ -1060,6 +1184,11 @@ enum {
STV_PROTECTED = 3 // Visible in other components but not preemptable
};
+// Symbol number.
+enum {
+ STN_UNDEF = 0
+};
+
// Relocation entry, without explicit addend.
struct Elf32_Rel {
Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
@@ -1100,14 +1229,14 @@ struct Elf64_Rel {
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
- Elf64_Xword getSymbol() const { return (r_info >> 32); }
- unsigned char getType() const {
- return (unsigned char) (r_info & 0xffffffffL);
+ Elf64_Word getSymbol() const { return (r_info >> 32); }
+ Elf64_Word getType() const {
+ return (Elf64_Word) (r_info & 0xffffffffL);
}
- void setSymbol(Elf32_Word s) { setSymbolAndType(s, getType()); }
- void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
- void setSymbolAndType(Elf64_Xword s, unsigned char t) {
- r_info = (s << 32) + (t&0xffffffffL);
+ void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+ void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+ r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
}
};
@@ -1119,14 +1248,14 @@ struct Elf64_Rela {
// These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE,
// and ELF64_R_INFO macros defined in the ELF specification:
- Elf64_Xword getSymbol() const { return (r_info >> 32); }
- unsigned char getType() const {
- return (unsigned char) (r_info & 0xffffffffL);
+ Elf64_Word getSymbol() const { return (r_info >> 32); }
+ Elf64_Word getType() const {
+ return (Elf64_Word) (r_info & 0xffffffffL);
}
- void setSymbol(Elf64_Xword s) { setSymbolAndType(s, getType()); }
- void setType(unsigned char t) { setSymbolAndType(getSymbol(), t); }
- void setSymbolAndType(Elf64_Xword s, unsigned char t) {
- r_info = (s << 32) + (t&0xffffffffL);
+ void setSymbol(Elf64_Word s) { setSymbolAndType(s, getType()); }
+ void setType(Elf64_Word t) { setSymbolAndType(getSymbol(), t); }
+ void setSymbolAndType(Elf64_Word s, Elf64_Word t) {
+ r_info = ((Elf64_Xword)s << 32) + (t&0xffffffffL);
}
};
@@ -1148,7 +1277,7 @@ struct Elf64_Phdr {
Elf64_Word p_flags; // Segment flags
Elf64_Off p_offset; // File offset where segment is located, in bytes
Elf64_Addr p_vaddr; // Virtual address of beginning of segment
- Elf64_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf64_Addr p_paddr; // Physical addr of beginning of segment (OS-specific)
Elf64_Xword p_filesz; // Num. of bytes in file image of segment (may be zero)
Elf64_Xword p_memsz; // Num. of bytes in mem image of segment (may be zero)
Elf64_Xword p_align; // Segment alignment constraint
@@ -1179,7 +1308,7 @@ enum {
PT_GNU_RELRO = 0x6474e552, // Read-only after relocation.
// ARM program header types.
- PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility information
+ PT_ARM_ARCHEXT = 0x70000000, // Platform architecture compatibility info
// These all contain stack unwind tables.
PT_ARM_EXIDX = 0x70000001,
PT_ARM_UNWIND = 0x70000001
diff --git a/include/llvm/Support/Errno.h b/include/llvm/Support/Errno.h
index 150bdb7..8e145c7 100644
--- a/include/llvm/Support/Errno.h
+++ b/include/llvm/Support/Errno.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_ERRNO_H
-#define LLVM_SYSTEM_ERRNO_H
+#ifndef LLVM_SUPPORT_ERRNO_H
+#define LLVM_SUPPORT_ERRNO_H
#include <string>
diff --git a/include/llvm/Support/ErrorOr.h b/include/llvm/Support/ErrorOr.h
new file mode 100644
index 0000000..ceec33d
--- /dev/null
+++ b/include/llvm/Support/ErrorOr.h
@@ -0,0 +1,488 @@
+//===- llvm/Support/ErrorOr.h - Error Smart Pointer -----------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+///
+/// Provides ErrorOr<T> smart pointer.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ERROR_OR_H
+#define LLVM_SUPPORT_ERROR_OR_H
+
+#include "llvm/ADT/PointerIntPair.h"
+#include "llvm/Support/AlignOf.h"
+#include "llvm/Support/system_error.h"
+#include "llvm/Support/type_traits.h"
+
+#include <cassert>
+#if LLVM_HAS_CXX11_TYPETRAITS
+#include <type_traits>
+#endif
+
+namespace llvm {
+struct ErrorHolderBase {
+ error_code Error;
+ uint16_t RefCount;
+ bool HasUserData;
+
+ ErrorHolderBase() : RefCount(1) {}
+
+ void aquire() {
+ ++RefCount;
+ }
+
+ void release() {
+ if (--RefCount == 0)
+ delete this;
+ }
+
+protected:
+ virtual ~ErrorHolderBase() {}
+};
+
+template<class T>
+struct ErrorHolder : ErrorHolderBase {
+#if LLVM_HAS_RVALUE_REFERENCES
+ ErrorHolder(T &&UD) : UserData(llvm_move(UD)) {}
+#else
+ ErrorHolder(T &UD) : UserData(UD) {}
+#endif
+ T UserData;
+};
+
+template<class Tp> struct ErrorOrUserDataTraits : llvm::false_type {};
+
+#if LLVM_HAS_CXX11_TYPETRAITS && LLVM_HAS_RVALUE_REFERENCES
+template<class T, class V>
+typename std::enable_if< std::is_constructible<T, V>::value
+ , typename std::remove_reference<V>::type>::type &&
+ moveIfMoveConstructible(V &Val) {
+ return std::move(Val);
+}
+
+template<class T, class V>
+typename std::enable_if< !std::is_constructible<T, V>::value
+ , typename std::remove_reference<V>::type>::type &
+moveIfMoveConstructible(V &Val) {
+ return Val;
+}
+#else
+template<class T, class V>
+V &moveIfMoveConstructible(V &Val) {
+ return Val;
+}
+#endif
+
+/// \brief Stores a reference that can be changed.
+template <typename T>
+class ReferenceStorage {
+ T *Storage;
+
+public:
+ ReferenceStorage(T &Ref) : Storage(&Ref) {}
+
+ operator T &() const { return *Storage; }
+ T &get() const { return *Storage; }
+};
+
+/// \brief Represents either an error or a value T.
+///
+/// ErrorOr<T> is a pointer-like class that represents the result of an
+/// operation. The result is either an error, or a value of type T. This is
+/// designed to emulate the usage of returning a pointer where nullptr indicates
+/// failure. However instead of just knowing that the operation failed, we also
+/// have an error_code and optional user data that describes why it failed.
+///
+/// It is used like the following.
+/// \code
+/// ErrorOr<Buffer> getBuffer();
+/// void handleError(error_code ec);
+///
+/// auto buffer = getBuffer();
+/// if (!buffer)
+/// handleError(buffer);
+/// buffer->write("adena");
+/// \endcode
+///
+/// ErrorOr<T> also supports user defined data for specific error_codes. To use
+/// this feature you must first add a template specialization of
+/// ErrorOrUserDataTraits derived from std::true_type for your type in the lld
+/// namespace. This specialization must have a static error_code error()
+/// function that returns the error_code this data is used with.
+///
+/// getError<UserData>() may be called to get either the stored user data, or
+/// a default constructed UserData if none was stored.
+///
+/// Example:
+/// \code
+/// struct InvalidArgError {
+/// InvalidArgError() {}
+/// InvalidArgError(std::string S) : ArgName(S) {}
+/// std::string ArgName;
+/// };
+///
+/// namespace llvm {
+/// template<>
+/// struct ErrorOrUserDataTraits<InvalidArgError> : std::true_type {
+/// static error_code error() {
+/// return make_error_code(errc::invalid_argument);
+/// }
+/// };
+/// } // end namespace llvm
+///
+/// using namespace llvm;
+///
+/// ErrorOr<int> foo() {
+/// return InvalidArgError("adena");
+/// }
+///
+/// int main() {
+/// auto a = foo();
+/// if (!a && error_code(a) == errc::invalid_argument)
+/// llvm::errs() << a.getError<InvalidArgError>().ArgName << "\n";
+/// }
+/// \endcode
+///
+/// An implicit conversion to bool provides a way to check if there was an
+/// error. The unary * and -> operators provide pointer like access to the
+/// value. Accessing the value when there is an error has undefined behavior.
+///
+/// When T is a reference type the behaivor is slightly different. The reference
+/// is held in a std::reference_wrapper<std::remove_reference<T>::type>, and
+/// there is special handling to make operator -> work as if T was not a
+/// reference.
+///
+/// T cannot be a rvalue reference.
+template<class T>
+class ErrorOr {
+ template <class OtherT> friend class ErrorOr;
+ static const bool isRef = is_reference<T>::value;
+ typedef ReferenceStorage<typename remove_reference<T>::type> wrap;
+
+public:
+ typedef typename
+ conditional< isRef
+ , wrap
+ , T
+ >::type storage_type;
+
+private:
+ typedef typename remove_reference<T>::type &reference;
+ typedef typename remove_reference<T>::type *pointer;
+
+public:
+ ErrorOr() : IsValid(false) {}
+
+ ErrorOr(llvm::error_code EC) : HasError(true), IsValid(true) {
+ Error = new ErrorHolderBase;
+ Error->Error = EC;
+ Error->HasUserData = false;
+ }
+
+ template<class UserDataT>
+ ErrorOr(UserDataT UD, typename
+ enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
+ : HasError(true), IsValid(true) {
+ Error = new ErrorHolder<UserDataT>(llvm_move(UD));
+ Error->Error = ErrorOrUserDataTraits<UserDataT>::error();
+ Error->HasUserData = true;
+ }
+
+ ErrorOr(T Val) : HasError(false), IsValid(true) {
+ new (get()) storage_type(moveIfMoveConstructible<storage_type>(Val));
+ }
+
+ ErrorOr(const ErrorOr &Other) : IsValid(false) {
+ copyConstruct(Other);
+ }
+
+ template <class OtherT>
+ ErrorOr(const ErrorOr<OtherT> &Other) : IsValid(false) {
+ copyConstruct(Other);
+ }
+
+ ErrorOr &operator =(const ErrorOr &Other) {
+ copyAssign(Other);
+ return *this;
+ }
+
+ template <class OtherT>
+ ErrorOr &operator =(const ErrorOr<OtherT> &Other) {
+ copyAssign(Other);
+ return *this;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCES
+ ErrorOr(ErrorOr &&Other) : IsValid(false) {
+ moveConstruct(std::move(Other));
+ }
+
+ template <class OtherT>
+ ErrorOr(ErrorOr<OtherT> &&Other) : IsValid(false) {
+ moveConstruct(std::move(Other));
+ }
+
+ ErrorOr &operator =(ErrorOr &&Other) {
+ moveAssign(std::move(Other));
+ return *this;
+ }
+
+ template <class OtherT>
+ ErrorOr &operator =(ErrorOr<OtherT> &&Other) {
+ moveAssign(std::move(Other));
+ return *this;
+ }
+#endif
+
+ ~ErrorOr() {
+ if (!IsValid)
+ return;
+ if (HasError)
+ Error->release();
+ else
+ get()->~storage_type();
+ }
+
+ template<class ET>
+ ET getError() const {
+ assert(IsValid && "Cannot get the error of a default constructed ErrorOr!");
+ assert(HasError && "Cannot get an error if none exists!");
+ assert(ErrorOrUserDataTraits<ET>::error() == Error->Error &&
+ "Incorrect user error data type for error!");
+ if (!Error->HasUserData)
+ return ET();
+ return reinterpret_cast<const ErrorHolder<ET>*>(Error)->UserData;
+ }
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ /// \brief Return false if there is an error.
+ operator unspecified_bool_type() const {
+ assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
+ return HasError ? 0 : unspecified_bool_true;
+ }
+
+ operator llvm::error_code() const {
+ assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
+ return HasError ? Error->Error : llvm::error_code::success();
+ }
+
+ pointer operator ->() {
+ return toPointer(get());
+ }
+
+ reference operator *() {
+ return *get();
+ }
+
+private:
+ template <class OtherT>
+ void copyConstruct(const ErrorOr<OtherT> &Other) {
+ // Construct an invalid ErrorOr if other is invalid.
+ if (!Other.IsValid)
+ return;
+ IsValid = true;
+ if (!Other.HasError) {
+ // Get the other value.
+ HasError = false;
+ new (get()) storage_type(*Other.get());
+ } else {
+ // Get other's error.
+ Error = Other.Error;
+ HasError = true;
+ Error->aquire();
+ }
+ }
+
+ template <class T1>
+ static bool compareThisIfSameType(const T1 &a, const T1 &b) {
+ return &a == &b;
+ }
+
+ template <class T1, class T2>
+ static bool compareThisIfSameType(const T1 &a, const T2 &b) {
+ return false;
+ }
+
+ template <class OtherT>
+ void copyAssign(const ErrorOr<OtherT> &Other) {
+ if (compareThisIfSameType(*this, Other))
+ return;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(Other);
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCES
+ template <class OtherT>
+ void moveConstruct(ErrorOr<OtherT> &&Other) {
+ // Construct an invalid ErrorOr if other is invalid.
+ if (!Other.IsValid)
+ return;
+ IsValid = true;
+ if (!Other.HasError) {
+ // Get the other value.
+ HasError = false;
+ new (get()) storage_type(std::move(*Other.get()));
+ // Tell other not to do any destruction.
+ Other.IsValid = false;
+ } else {
+ // Get other's error.
+ Error = Other.Error;
+ HasError = true;
+ // Tell other not to do any destruction.
+ Other.IsValid = false;
+ }
+ }
+
+ template <class OtherT>
+ void moveAssign(ErrorOr<OtherT> &&Other) {
+ if (compareThisIfSameType(*this, Other))
+ return;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(std::move(Other));
+ }
+#endif
+
+ pointer toPointer(pointer Val) {
+ return Val;
+ }
+
+ pointer toPointer(wrap *Val) {
+ return &Val->get();
+ }
+
+ storage_type *get() {
+ assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
+ assert(!HasError && "Cannot get value when an error exists!");
+ return reinterpret_cast<storage_type*>(TStorage.buffer);
+ }
+
+ const storage_type *get() const {
+ assert(IsValid && "Can't do anything on a default constructed ErrorOr!");
+ assert(!HasError && "Cannot get value when an error exists!");
+ return reinterpret_cast<const storage_type*>(TStorage.buffer);
+ }
+
+ union {
+ AlignedCharArrayUnion<storage_type> TStorage;
+ ErrorHolderBase *Error;
+ };
+ bool HasError : 1;
+ bool IsValid : 1;
+};
+
+// ErrorOr specialization for void.
+template <>
+class ErrorOr<void> {
+public:
+ ErrorOr() : Error(0, 0) {}
+
+ ErrorOr(llvm::error_code EC) : Error(0, 0) {
+ if (EC == errc::success) {
+ Error.setInt(1);
+ return;
+ }
+ ErrorHolderBase *E = new ErrorHolderBase;
+ E->Error = EC;
+ E->HasUserData = false;
+ Error.setPointer(E);
+ }
+
+ template<class UserDataT>
+ ErrorOr(UserDataT UD, typename
+ enable_if_c<ErrorOrUserDataTraits<UserDataT>::value>::type* = 0)
+ : Error(0, 0) {
+ ErrorHolderBase *E = new ErrorHolder<UserDataT>(llvm_move(UD));
+ E->Error = ErrorOrUserDataTraits<UserDataT>::error();
+ E->HasUserData = true;
+ Error.setPointer(E);
+ }
+
+ ErrorOr(const ErrorOr &Other) : Error(0, 0) {
+ Error = Other.Error;
+ if (Other.Error.getPointer()->Error) {
+ Error.getPointer()->aquire();
+ }
+ }
+
+ ErrorOr &operator =(const ErrorOr &Other) {
+ if (this == &Other)
+ return *this;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(Other);
+
+ return *this;
+ }
+
+#if LLVM_HAS_RVALUE_REFERENCES
+ ErrorOr(ErrorOr &&Other) : Error(0) {
+ // Get other's error.
+ Error = Other.Error;
+ // Tell other not to do any destruction.
+ Other.Error.setPointer(0);
+ }
+
+ ErrorOr &operator =(ErrorOr &&Other) {
+ if (this == &Other)
+ return *this;
+
+ this->~ErrorOr();
+ new (this) ErrorOr(std::move(Other));
+
+ return *this;
+ }
+#endif
+
+ ~ErrorOr() {
+ if (Error.getPointer())
+ Error.getPointer()->release();
+ }
+
+ template<class ET>
+ ET getError() const {
+ assert(ErrorOrUserDataTraits<ET>::error() == *this &&
+ "Incorrect user error data type for error!");
+ if (!Error.getPointer()->HasUserData)
+ return ET();
+ return reinterpret_cast<const ErrorHolder<ET> *>(
+ Error.getPointer())->UserData;
+ }
+
+ typedef void (*unspecified_bool_type)();
+ static void unspecified_bool_true() {}
+
+ /// \brief Return false if there is an error.
+ operator unspecified_bool_type() const {
+ return Error.getInt() ? unspecified_bool_true : 0;
+ }
+
+ operator llvm::error_code() const {
+ return Error.getInt() ? make_error_code(errc::success)
+ : Error.getPointer()->Error;
+ }
+
+private:
+ // If the bit is 1, the error is success.
+ llvm::PointerIntPair<ErrorHolderBase *, 1> Error;
+};
+
+template<class T, class E>
+typename enable_if_c<is_error_code_enum<E>::value ||
+ is_error_condition_enum<E>::value, bool>::type
+operator ==(ErrorOr<T> &Err, E Code) {
+ return error_code(Err) == Code;
+}
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FEnv.h b/include/llvm/Support/FEnv.h
index f6f4333..d9cf724 100644
--- a/include/llvm/Support/FEnv.h
+++ b/include/llvm/Support/FEnv.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_FENV_H
-#define LLVM_SYSTEM_FENV_H
+#ifndef LLVM_SUPPORT_FENV_H
+#define LLVM_SUPPORT_FENV_H
#include "llvm/Config/config.h"
#include <cerrno>
diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h
index f1cbe97..bae3a5a 100644
--- a/include/llvm/Support/FileSystem.h
+++ b/include/llvm/Support/FileSystem.h
@@ -24,8 +24,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_FILE_SYSTEM_H
-#define LLVM_SUPPORT_FILE_SYSTEM_H
+#ifndef LLVM_SUPPORT_FILESYSTEM_H
+#define LLVM_SUPPORT_FILESYSTEM_H
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/OwningPtr.h"
diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h
index e552315..f1040f5 100644
--- a/include/llvm/Support/GCOV.h
+++ b/include/llvm/Support/GCOV.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_GCOV_H
-#define LLVM_GCOV_H
+#ifndef LLVM_SUPPORT_GCOV_H
+#define LLVM_SUPPORT_GCOV_H
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
index 52b06ad..5a90553 100644
--- a/include/llvm/Support/GetElementPtrTypeIterator.h
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
-#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPEITERATOR_H
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/User.h"
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 30cfe61..22181d4 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -34,6 +34,10 @@ namespace llvm {
namespace DOT { // Private functions...
std::string EscapeString(const std::string &Label);
+
+ /// \brief Get a color string for this node number. Simply round-robin selects
+ /// from a reasonable number of colors.
+ StringRef getColorString(unsigned NodeNumber);
}
namespace GraphProgram {
@@ -173,6 +177,10 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
O << "|" << static_cast<const void*>(Node);
+
+ std::string NodeDesc = DTraits.getNodeDescription(Node, G);
+ if (!NodeDesc.empty())
+ O << "|" << DOT::EscapeString(NodeDesc);
}
std::string edgeSourceLabels;
@@ -193,6 +201,10 @@ public:
// If we should include the address of the node in the label, do so now.
if (DTraits.hasNodeAddressLabel(Node, G))
O << "|" << static_cast<const void*>(Node);
+
+ std::string NodeDesc = DTraits.getNodeDescription(Node, G);
+ if (!NodeDesc.empty())
+ O << "|" << DOT::EscapeString(NodeDesc);
}
if (DTraits.hasEdgeDestLabels()) {
diff --git a/include/llvm/Support/Host.h b/include/llvm/Support/Host.h
index b331016..3a44405 100644
--- a/include/llvm/Support/Host.h
+++ b/include/llvm/Support/Host.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_HOST_H
-#define LLVM_SYSTEM_HOST_H
+#ifndef LLVM_SUPPORT_HOST_H
+#define LLVM_SUPPORT_HOST_H
#include "llvm/ADT/StringMap.h"
#include <string>
@@ -42,6 +42,10 @@ namespace sys {
/// CPU_TYPE-VENDOR-KERNEL-OPERATING_SYSTEM
std::string getDefaultTargetTriple();
+ /// getProcessTriple() - Return an appropriate target triple for generating
+ /// code to be loaded into the current process, e.g. when using the JIT.
+ std::string getProcessTriple();
+
/// getHostCPUName - Get the LLVM name for the host CPU. The particular format
/// of the name is target dependent, and suitable for passing as -mcpu to the
/// target which matches the host.
diff --git a/include/llvm/Support/IncludeFile.h b/include/llvm/Support/IncludeFile.h
index a931972..2067e34 100644
--- a/include/llvm/Support/IncludeFile.h
+++ b/include/llvm/Support/IncludeFile.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_INCLUDEFILE_H
-#define LLVM_SYSTEM_INCLUDEFILE_H
+#ifndef LLVM_SUPPORT_INCLUDEFILE_H
+#define LLVM_SUPPORT_INCLUDEFILE_H
/// This macro is the public interface that IncludeFile.h exports. This gives
/// us the option to implement the "link the definition" capability in any
diff --git a/include/llvm/Support/IntegersSubset.h b/include/llvm/Support/IntegersSubset.h
index 9e5361c..ce34d78 100644
--- a/include/llvm/Support/IntegersSubset.h
+++ b/include/llvm/Support/IntegersSubset.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CONSTANTRANGESSET_H_
-#define CONSTANTRANGESSET_H_
+#ifndef LLVM_SUPPORT_INTEGERSSUBSET_H
+#define LLVM_SUPPORT_INTEGERSSUBSET_H
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
@@ -537,4 +537,4 @@ public:
}
-#endif /* CONSTANTRANGESSET_H_ */
+#endif /* CLLVM_SUPPORT_INTEGERSSUBSET_H */
diff --git a/include/llvm/Support/IntegersSubsetMapping.h b/include/llvm/Support/IntegersSubsetMapping.h
index 7635d5e..641ce78 100644
--- a/include/llvm/Support/IntegersSubsetMapping.h
+++ b/include/llvm/Support/IntegersSubsetMapping.h
@@ -17,8 +17,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef CRSBUILDER_H_
-#define CRSBUILDER_H_
+#ifndef LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
+#define LLVM_SUPPORT_INTEGERSSUBSETMAPPING_H
#include "llvm/Support/IntegersSubset.h"
#include <list>
@@ -585,4 +585,4 @@ typedef IntegersSubsetMapping<BasicBlock> IntegersSubsetToBB;
}
-#endif /* CRSBUILDER_H_ */
+#endif /* LLVM_SUPPORT_INTEGERSSUBSETMAPPING_CRSBUILDER_H */
diff --git a/include/llvm/Support/LEB128.h b/include/llvm/Support/LEB128.h
index b52e5bc..802b4f3 100644
--- a/include/llvm/Support/LEB128.h
+++ b/include/llvm/Support/LEB128.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_LEB128_H
-#define LLVM_SYSTEM_LEB128_H
+#ifndef LLVM_SUPPORT_LEB128_H
+#define LLVM_SUPPORT_LEB128_H
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Support/Locale.h b/include/llvm/Support/Locale.h
index b0f1295..b384d58 100644
--- a/include/llvm/Support/Locale.h
+++ b/include/llvm/Support/Locale.h
@@ -1,5 +1,5 @@
-#ifndef LLVM_SUPPORT_LOCALE
-#define LLVM_SUPPORT_LOCALE
+#ifndef LLVM_SUPPORT_LOCALE_H
+#define LLVM_SUPPORT_LOCALE_H
#include "llvm/ADT/StringRef.h"
@@ -14,4 +14,4 @@ bool isPrint(int c);
}
}
-#endif // LLVM_SUPPORT_LOCALE
+#endif // LLVM_SUPPORT_LOCALE_H
diff --git a/include/llvm/Support/LockFileManager.h b/include/llvm/Support/LockFileManager.h
index 8c4a760..9df8675 100644
--- a/include/llvm/Support/LockFileManager.h
+++ b/include/llvm/Support/LockFileManager.h
@@ -41,6 +41,7 @@ public:
};
private:
+ SmallString<128> FileName;
SmallString<128> LockFileName;
SmallString<128> UniqueLockFileName;
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index 11f9e63..214bb6c 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -16,6 +16,10 @@
#include "llvm/Support/SwapByteOrder.h"
+#ifdef _MSC_VER
+# include <intrin.h>
+#endif
+
namespace llvm {
// NOTE: The following support functions use the _32/_64 extensions instead of
@@ -61,7 +65,7 @@ inline bool isShiftedInt(int64_t x) {
/// isUInt - Checks if an unsigned integer fits into the given bit width.
template<unsigned N>
inline bool isUInt(uint64_t x) {
- return N >= 64 || x < (UINT64_C(1)<<N);
+ return N >= 64 || x < (UINT64_C(1)<<(N));
}
// Template specializations to get better code for common cases.
template<>
diff --git a/include/llvm/Support/Memory.h b/include/llvm/Support/Memory.h
index 025eee7..a08c796 100644
--- a/include/llvm/Support/Memory.h
+++ b/include/llvm/Support/Memory.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_MEMORY_H
-#define LLVM_SYSTEM_MEMORY_H
+#ifndef LLVM_SUPPORT_MEMORY_H
+#define LLVM_SUPPORT_MEMORY_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/system_error.h"
diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h
index b778b08..732b0f0 100644
--- a/include/llvm/Support/MemoryObject.h
+++ b/include/llvm/Support/MemoryObject.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef MEMORYOBJECT_H
-#define MEMORYOBJECT_H
+#ifndef LLVM_SUPPORT_MEMORYOBJECT_H
+#define LLVM_SUPPORT_MEMORYOBJECT_H
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/Mutex.h b/include/llvm/Support/Mutex.h
index 6abc533..496a438 100644
--- a/include/llvm/Support/Mutex.h
+++ b/include/llvm/Support/Mutex.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_MUTEX_H
-#define LLVM_SYSTEM_MUTEX_H
+#ifndef LLVM_SUPPORT_MUTEX_H
+#define LLVM_SUPPORT_MUTEX_H
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Threading.h"
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
index bdfab39..317416c 100644
--- a/include/llvm/Support/PassNameParser.h
+++ b/include/llvm/Support/PassNameParser.h
@@ -20,8 +20,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
-#define LLVM_SUPPORT_PASS_NAME_PARSER_H
+#ifndef LLVM_SUPPORT_PASSNAMEPARSER_H
+#define LLVM_SUPPORT_PASSNAMEPARSER_H
#include "llvm/ADT/STLExtras.h"
#include "llvm/Pass.h"
diff --git a/include/llvm/Support/PathV1.h b/include/llvm/Support/PathV1.h
index 643ee8c..86328f0 100644
--- a/include/llvm/Support/PathV1.h
+++ b/include/llvm/Support/PathV1.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_PATH_H
-#define LLVM_SYSTEM_PATH_H
+#ifndef LLVM_SUPPORT_PATHV1_H
+#define LLVM_SUPPORT_PATHV1_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/Process.h b/include/llvm/Support/Process.h
index ea8da6d..4256d4a 100644
--- a/include/llvm/Support/Process.h
+++ b/include/llvm/Support/Process.h
@@ -22,8 +22,8 @@
///
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_PROCESS_H
-#define LLVM_SYSTEM_PROCESS_H
+#ifndef LLVM_SUPPORT_PROCESS_H
+#define LLVM_SUPPORT_PROCESS_H
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 028565d..a0cc27c 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_PROGRAM_H
-#define LLVM_SYSTEM_PROGRAM_H
+#ifndef LLVM_SUPPORT_PROGRAM_H
+#define LLVM_SUPPORT_PROGRAM_H
#include "llvm/Support/Path.h"
diff --git a/include/llvm/Support/RegistryParser.h b/include/llvm/Support/RegistryParser.h
index 2cc5783..a6997b6 100644
--- a/include/llvm/Support/RegistryParser.h
+++ b/include/llvm/Support/RegistryParser.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_REGISTRY_PARSER_H
-#define LLVM_SUPPORT_REGISTRY_PARSER_H
+#ifndef LLVM_SUPPORT_REGISTRYPARSER_H
+#define LLVM_SUPPORT_REGISTRYPARSER_H
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Registry.h"
@@ -52,4 +52,4 @@ namespace llvm {
}
-#endif // LLVM_SUPPORT_REGISTRY_PARSER_H
+#endif // LLVM_SUPPORT_REGISTRYPARSER_H
diff --git a/include/llvm/Support/SMLoc.h b/include/llvm/Support/SMLoc.h
index 2b0e9df..0906471 100644
--- a/include/llvm/Support/SMLoc.h
+++ b/include/llvm/Support/SMLoc.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUPPORT_SMLOC_H
-#define SUPPORT_SMLOC_H
+#ifndef LLVM_SUPPORT_SMLOC_H
+#define LLVM_SUPPORT_SMLOC_H
#include <cassert>
diff --git a/include/llvm/Support/SaveAndRestore.h b/include/llvm/Support/SaveAndRestore.h
index ffa99b9..6330bec 100644
--- a/include/llvm/Support/SaveAndRestore.h
+++ b/include/llvm/Support/SaveAndRestore.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_ADT_SAVERESTORE
-#define LLVM_ADT_SAVERESTORE
+#ifndef LLVM_SUPPORT_SAVEANDRESTORE_H
+#define LLVM_SUPPORT_SAVEANDRESTORE_H
namespace llvm {
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 634f4cf..465656b 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -12,10 +12,11 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SIGNALS_H
-#define LLVM_SYSTEM_SIGNALS_H
+#ifndef LLVM_SUPPORT_SIGNALS_H
+#define LLVM_SUPPORT_SIGNALS_H
#include "llvm/Support/Path.h"
+#include <cstdio>
namespace llvm {
namespace sys {
@@ -38,6 +39,9 @@ namespace sys {
/// @brief Print a stack trace if a fatal signal occurs.
void PrintStackTraceOnErrorSignal();
+ /// \brief Print the stack trace using the given \c FILE object.
+ void PrintStackTrace(FILE *);
+
/// AddSignalHandler - Add a function to be called when an abort/kill signal
/// is delivered to the process. The handler can have a cookie passed to it
/// to identify what instance of the handler it is.
diff --git a/include/llvm/Support/Solaris.h b/include/llvm/Support/Solaris.h
index 57eee2c..6228c4b 100644
--- a/include/llvm/Support/Solaris.h
+++ b/include/llvm/Support/Solaris.h
@@ -11,8 +11,8 @@
*
*===----------------------------------------------------------------------===*/
-#ifndef LLVM_SYSTEM_SOLARIS_H
-#define LLVM_SYSTEM_SOLARIS_H
+#ifndef LLVM_SUPPORT_SOLARIS_H
+#define LLVM_SUPPORT_SOLARIS_H
#include <sys/types.h>
#include <sys/regset.h>
diff --git a/include/llvm/Support/SourceMgr.h b/include/llvm/Support/SourceMgr.h
index aaee344..02abf92 100644
--- a/include/llvm/Support/SourceMgr.h
+++ b/include/llvm/Support/SourceMgr.h
@@ -13,10 +13,12 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SUPPORT_SOURCEMGR_H
-#define SUPPORT_SOURCEMGR_H
+#ifndef LLVM_SUPPORT_SOURCEMGR_H
+#define LLVM_SUPPORT_SOURCEMGR_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/SMLoc.h"
#include <string>
@@ -24,6 +26,7 @@ namespace llvm {
class MemoryBuffer;
class SourceMgr;
class SMDiagnostic;
+ class SMFixIt;
class Twine;
class raw_ostream;
@@ -143,6 +146,7 @@ public:
/// the default error handler is used.
void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
+ ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>(),
bool ShowColors = true) const;
@@ -152,7 +156,8 @@ public:
/// @param Msg If non-null, the kind of message (e.g., "error") which is
/// prefixed to the message.
SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
- ArrayRef<SMRange> Ranges = ArrayRef<SMRange>()) const;
+ ArrayRef<SMRange> Ranges = ArrayRef<SMRange>(),
+ ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>()) const;
/// PrintIncludeStack - Prints the names of included files and the line of the
/// file they were included from. A diagnostic handler can use this before
@@ -164,6 +169,38 @@ public:
};
+/// Represents a single fixit, a replacement of one range of text with another.
+class SMFixIt {
+ SMRange Range;
+
+ std::string Text;
+
+public:
+ // FIXME: Twine.str() is not very efficient.
+ SMFixIt(SMLoc Loc, const Twine &Insertion)
+ : Range(Loc, Loc), Text(Insertion.str()) {
+ assert(Loc.isValid());
+ }
+
+ // FIXME: Twine.str() is not very efficient.
+ SMFixIt(SMRange R, const Twine &Replacement)
+ : Range(R), Text(Replacement.str()) {
+ assert(R.isValid());
+ }
+
+ StringRef getText() const { return Text; }
+ SMRange getRange() const { return Range; }
+
+ bool operator<(const SMFixIt &Other) const {
+ if (Range.Start.getPointer() != Other.Range.Start.getPointer())
+ return Range.Start.getPointer() < Other.Range.Start.getPointer();
+ if (Range.End.getPointer() != Other.Range.End.getPointer())
+ return Range.End.getPointer() < Other.Range.End.getPointer();
+ return Text < Other.Text;
+ }
+};
+
+
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
/// allowing printing to a raw_ostream as a caret diagnostic.
class SMDiagnostic {
@@ -174,35 +211,46 @@ class SMDiagnostic {
SourceMgr::DiagKind Kind;
std::string Message, LineContents;
std::vector<std::pair<unsigned, unsigned> > Ranges;
+ SmallVector<SMFixIt, 4> FixIts;
public:
// Null diagnostic.
SMDiagnostic()
: SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error) {}
// Diagnostic with no location (e.g. file not found, command line arg error).
- SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Knd,
- const std::string &Msg)
+ SMDiagnostic(StringRef filename, SourceMgr::DiagKind Knd, StringRef Msg)
: SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Knd),
Message(Msg) {}
// Diagnostic with a location.
- SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
+ SMDiagnostic(const SourceMgr &sm, SMLoc L, StringRef FN,
int Line, int Col, SourceMgr::DiagKind Kind,
- const std::string &Msg, const std::string &LineStr,
- ArrayRef<std::pair<unsigned,unsigned> > Ranges);
+ StringRef Msg, StringRef LineStr,
+ ArrayRef<std::pair<unsigned,unsigned> > Ranges,
+ ArrayRef<SMFixIt> FixIts = ArrayRef<SMFixIt>());
const SourceMgr *getSourceMgr() const { return SM; }
SMLoc getLoc() const { return Loc; }
- const std::string &getFilename() const { return Filename; }
+ StringRef getFilename() const { return Filename; }
int getLineNo() const { return LineNo; }
int getColumnNo() const { return ColumnNo; }
SourceMgr::DiagKind getKind() const { return Kind; }
- const std::string &getMessage() const { return Message; }
- const std::string &getLineContents() const { return LineContents; }
- const std::vector<std::pair<unsigned, unsigned> > &getRanges() const {
+ StringRef getMessage() const { return Message; }
+ StringRef getLineContents() const { return LineContents; }
+ ArrayRef<std::pair<unsigned, unsigned> > getRanges() const {
return Ranges;
}
- void print(const char *ProgName, raw_ostream &S, bool ShowColors = true) const;
+
+ void addFixIt(const SMFixIt &Hint) {
+ FixIts.push_back(Hint);
+ }
+
+ ArrayRef<SMFixIt> getFixIts() const {
+ return FixIts;
+ }
+
+ void print(const char *ProgName, raw_ostream &S,
+ bool ShowColors = true) const;
};
} // end llvm namespace
diff --git a/include/llvm/Support/StreamableMemoryObject.h b/include/llvm/Support/StreamableMemoryObject.h
index 2e1163f..3855485 100644
--- a/include/llvm/Support/StreamableMemoryObject.h
+++ b/include/llvm/Support/StreamableMemoryObject.h
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
-#ifndef STREAMABLEMEMORYOBJECT_H_
-#define STREAMABLEMEMORYOBJECT_H_
+#ifndef LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
+#define LLVM_SUPPORT_STREAMABLEMEMORYOBJECT_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/SwapByteOrder.h b/include/llvm/Support/SwapByteOrder.h
index 6c0592c..e65f9cc 100644
--- a/include/llvm/Support/SwapByteOrder.h
+++ b/include/llvm/Support/SwapByteOrder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SWAP_BYTE_ORDER_H
-#define LLVM_SYSTEM_SWAP_BYTE_ORDER_H
+#ifndef LLVM_SUPPORT_SWAPBYTEORDER_H
+#define LLVM_SUPPORT_SWAPBYTEORDER_H
#include "llvm/Support/DataTypes.h"
#include <cstddef>
diff --git a/include/llvm/Support/ThreadLocal.h b/include/llvm/Support/ThreadLocal.h
index 01f735c..7518626 100644
--- a/include/llvm/Support/ThreadLocal.h
+++ b/include/llvm/Support/ThreadLocal.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
-#define LLVM_SYSTEM_THREAD_LOCAL_H
+#ifndef LLVM_SUPPORT_THREADLOCAL_H
+#define LLVM_SUPPORT_THREADLOCAL_H
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Threading.h"
diff --git a/include/llvm/Support/Threading.h b/include/llvm/Support/Threading.h
index 9017afb..a7e8774 100644
--- a/include/llvm/Support/Threading.h
+++ b/include/llvm/Support/Threading.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_THREADING_H
-#define LLVM_SYSTEM_THREADING_H
+#ifndef LLVM_SUPPORT_THREADING_H
+#define LLVM_SUPPORT_THREADING_H
namespace llvm {
/// llvm_start_multithreaded - Allocate and initialize structures needed to
diff --git a/include/llvm/Support/TimeValue.h b/include/llvm/Support/TimeValue.h
index ab7401a..4b48b84 100644
--- a/include/llvm/Support/TimeValue.h
+++ b/include/llvm/Support/TimeValue.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_TIMEVALUE_H
-#define LLVM_SYSTEM_TIMEVALUE_H
+#ifndef LLVM_SUPPORT_TIMEVALUE_H
+#define LLVM_SUPPORT_TIMEVALUE_H
#include "llvm/Support/DataTypes.h"
#include <string>
@@ -240,7 +240,7 @@ namespace sys {
/// Posix, correcting for the difference in Posix zero time.
/// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
uint64_t toPosixTime() const {
- uint64_t result = seconds_ - PosixZeroTime.seconds_;
+ uint64_t result = seconds_ - PosixZeroTimeSeconds;
result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
return result;
}
@@ -248,14 +248,14 @@ namespace sys {
/// Converts the TimeValue into the corresponding number of seconds
/// since the epoch (00:00:00 Jan 1,1970).
uint64_t toEpochTime() const {
- return seconds_ - PosixZeroTime.seconds_;
+ return seconds_ - PosixZeroTimeSeconds;
}
/// Converts the TimeValue into the corresponding number of "ticks" for
/// Win32 platforms, correcting for the difference in Win32 zero time.
/// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
uint64_t toWin32Time() const {
- uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+ uint64_t result = seconds_ - Win32ZeroTimeSeconds;
result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
return result;
}
@@ -264,7 +264,7 @@ namespace sys {
/// correction for the Posix zero time.
/// @brief Convert to timespec time (ala POSIX.1b)
void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
- seconds = seconds_ - PosixZeroTime.seconds_;
+ seconds = seconds_ - PosixZeroTimeSeconds;
nanos = nanos_;
}
@@ -331,7 +331,7 @@ namespace sys {
/// TimeValue and assigns that value to \p this.
/// @brief Convert seconds form PosixTime to TimeValue
void fromEpochTime( SecondsType seconds ) {
- seconds_ = seconds + PosixZeroTime.seconds_;
+ seconds_ = seconds + PosixZeroTimeSeconds;
nanos_ = 0;
this->normalize();
}
@@ -340,7 +340,7 @@ namespace sys {
/// corresponding TimeValue and assigns that value to \p this.
/// @brief Convert seconds form Windows FILETIME to TimeValue
void fromWin32Time( uint64_t win32Time ) {
- this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTimeSeconds;
this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
}
@@ -360,6 +360,9 @@ namespace sys {
/// Store the values as a <timeval>.
SecondsType seconds_;///< Stores the seconds part of the TimeVal
NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
+
+ static const SecondsType PosixZeroTimeSeconds;
+ static const SecondsType Win32ZeroTimeSeconds;
/// @}
};
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 789c05f..d009d7f 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -6,11 +6,6 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
-// This file defines three classes: Timer, TimeRegion, and TimerGroup,
-// documented below.
-//
-//===----------------------------------------------------------------------===//
#ifndef LLVM_SUPPORT_TIMER_H
#define LLVM_SUPPORT_TIMER_H
@@ -78,7 +73,7 @@ public:
/// invocations of its startTimer()/stopTimer() methods. Given appropriate OS
/// support it can also keep track of the RSS of the program at various points.
/// By default, the Timer will print the amount of time it has captured to
-/// standard error when the laster timer is destroyed, otherwise it is printed
+/// standard error when the last timer is destroyed, otherwise it is printed
/// when its TimerGroup is destroyed. Timers do not print their information
/// if they are never started.
///
@@ -126,7 +121,7 @@ private:
/// The TimeRegion class is used as a helper class to call the startTimer() and
/// stopTimer() methods of the Timer class. When the object is constructed, it
-/// starts the timer specified as it's argument. When it is destroyed, it stops
+/// starts the timer specified as its argument. When it is destroyed, it stops
/// the relevant timer. This makes it easy to time a region of code.
///
class TimeRegion {
diff --git a/include/llvm/Support/ToolOutputFile.h b/include/llvm/Support/ToolOutputFile.h
index 65b182a..b3b7c57 100644
--- a/include/llvm/Support/ToolOutputFile.h
+++ b/include/llvm/Support/ToolOutputFile.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
-#define LLVM_SUPPORT_TOOL_OUTPUT_FILE_H
+#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
+#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
#include "llvm/Support/raw_ostream.h"
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index 5b728bc..6e4f57f 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -35,8 +35,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_YAML_PARSER_H
-#define LLVM_SUPPORT_YAML_PARSER_H
+#ifndef LLVM_SUPPORT_YAMLPARSER_H
+#define LLVM_SUPPORT_YAMLPARSER_H
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h
index 1862286..801868f 100644
--- a/include/llvm/Support/YAMLTraits.h
+++ b/include/llvm/Support/YAMLTraits.h
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_YAML_TRAITS_H_
-#define LLVM_YAML_TRAITS_H_
+#ifndef LLVM_SUPPORT_YAMLTRAITS_H
+#define LLVM_SUPPORT_YAMLTRAITS_H
#include "llvm/ADT/DenseMap.h"
@@ -195,7 +195,7 @@ public:
template <class T>
struct has_ScalarTraits
{
- typedef llvm::StringRef (*Signature_input)(llvm::StringRef, void*, T&);
+ typedef StringRef (*Signature_input)(StringRef, void*, T&);
typedef void (*Signature_output)(const T&, void*, llvm::raw_ostream&);
template <typename U>
@@ -528,73 +528,73 @@ yamlize(IO &io, T &Seq, bool) {
template<>
struct ScalarTraits<bool> {
static void output(const bool &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, bool &);
+ static StringRef input(StringRef, void*, bool &);
};
template<>
struct ScalarTraits<StringRef> {
static void output(const StringRef &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, StringRef &);
+ static StringRef input(StringRef, void*, StringRef &);
};
template<>
struct ScalarTraits<uint8_t> {
static void output(const uint8_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, uint8_t &);
+ static StringRef input(StringRef, void*, uint8_t &);
};
template<>
struct ScalarTraits<uint16_t> {
static void output(const uint16_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, uint16_t &);
+ static StringRef input(StringRef, void*, uint16_t &);
};
template<>
struct ScalarTraits<uint32_t> {
static void output(const uint32_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, uint32_t &);
+ static StringRef input(StringRef, void*, uint32_t &);
};
template<>
struct ScalarTraits<uint64_t> {
static void output(const uint64_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, uint64_t &);
+ static StringRef input(StringRef, void*, uint64_t &);
};
template<>
struct ScalarTraits<int8_t> {
static void output(const int8_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, int8_t &);
+ static StringRef input(StringRef, void*, int8_t &);
};
template<>
struct ScalarTraits<int16_t> {
static void output(const int16_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, int16_t &);
+ static StringRef input(StringRef, void*, int16_t &);
};
template<>
struct ScalarTraits<int32_t> {
static void output(const int32_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, int32_t &);
+ static StringRef input(StringRef, void*, int32_t &);
};
template<>
struct ScalarTraits<int64_t> {
static void output(const int64_t &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, int64_t &);
+ static StringRef input(StringRef, void*, int64_t &);
};
template<>
struct ScalarTraits<float> {
static void output(const float &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, float &);
+ static StringRef input(StringRef, void*, float &);
};
template<>
struct ScalarTraits<double> {
static void output(const double &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, double &);
+ static StringRef input(StringRef, void*, double &);
};
@@ -913,25 +913,25 @@ LLVM_YAML_STRONG_TYPEDEF(uint64_t, Hex64)
template<>
struct ScalarTraits<Hex8> {
static void output(const Hex8 &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, Hex8 &);
+ static StringRef input(StringRef, void*, Hex8 &);
};
template<>
struct ScalarTraits<Hex16> {
static void output(const Hex16 &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, Hex16 &);
+ static StringRef input(StringRef, void*, Hex16 &);
};
template<>
struct ScalarTraits<Hex32> {
static void output(const Hex32 &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, Hex32 &);
+ static StringRef input(StringRef, void*, Hex32 &);
};
template<>
struct ScalarTraits<Hex64> {
static void output(const Hex64 &, void*, llvm::raw_ostream &);
- static llvm::StringRef input(llvm::StringRef , void*, Hex64 &);
+ static StringRef input(StringRef, void*, Hex64 &);
};
@@ -1101,4 +1101,4 @@ operator<<(Output &yout, T &seq) {
-#endif // LLVM_YAML_TRAITS_H_
+#endif // LLVM_SUPPORT_YAMLTRAITS_H
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index eab0f2d..d2b4a2a 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -29,7 +29,6 @@ namespace llvm {
/// a chunk at a time.
class raw_ostream {
private:
- // Do not implement. raw_ostream is noncopyable.
void operator=(const raw_ostream &) LLVM_DELETED_FUNCTION;
raw_ostream(const raw_ostream &) LLVM_DELETED_FUNCTION;
diff --git a/include/llvm/Support/system_error.h b/include/llvm/Support/system_error.h
index 0d164f6..43dace6 100644
--- a/include/llvm/Support/system_error.h
+++ b/include/llvm/Support/system_error.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SYSTEM_SYSTEM_ERROR_H
-#define LLVM_SYSTEM_SYSTEM_ERROR_H
+#ifndef LLVM_SUPPORT_SYSTEM_ERROR_H
+#define LLVM_SUPPORT_SYSTEM_ERROR_H
#include "llvm/Support/Compiler.h"
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
index f930639..db43ccf 100644
--- a/include/llvm/Support/type_traits.h
+++ b/include/llvm/Support/type_traits.h
@@ -145,6 +145,10 @@ template <typename T> struct is_pointer<T* const> : true_type {};
template <typename T> struct is_pointer<T* volatile> : true_type {};
template <typename T> struct is_pointer<T* const volatile> : true_type {};
+/// \brief Metafunction that determines wheather the given type is a reference.
+template <typename T> struct is_reference : false_type {};
+template <typename T> struct is_reference<T&> : true_type {};
+
/// \brief Metafunction that determines whether the given type is either an
/// integral type or an enumeration type.
///
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index 8968534..3cf4f1f 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -175,8 +175,7 @@ public:
};
-// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
-/// BitsRecTy - 'bits&lt;n&gt;' - Represent a fixed number of bits
+/// BitsRecTy - 'bits<n>' - Represent a fixed number of bits
///
class BitsRecTy : public RecTy {
unsigned Size;
@@ -288,10 +287,8 @@ public:
}
};
-// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
-// the specified type.
-/// ListRecTy - 'list&lt;Ty&gt;' - Represent a list of values, all of which must
-/// be of the specified type.
+/// ListRecTy - 'list<Ty>' - Represent a list of values, all of which must be of
+/// the specified type.
///
class ListRecTy : public RecTy {
RecTy *Ty;
@@ -930,7 +927,7 @@ public:
///
class BinOpInit : public OpInit {
public:
- enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
+ enum BinaryOp { ADD, SHL, SRA, SRL, STRCONCAT, CONCAT, EQ };
private:
BinaryOp Opc;
Init *LHS, *RHS;
@@ -1387,12 +1384,14 @@ class Record {
SmallVector<SMLoc, 4> Locs;
std::vector<Init *> TemplateArgs;
std::vector<RecordVal> Values;
- std::vector<Record*> SuperClasses;
+ std::vector<Record *> SuperClasses;
+ std::vector<SMRange> SuperClassRanges;
// Tracks Record instances. Not owned by Record.
RecordKeeper &TrackedRecords;
DefInit *TheInit;
+ bool IsAnonymous;
void init();
void checkName();
@@ -1401,14 +1400,15 @@ public:
// Constructs a record.
explicit Record(const std::string &N, ArrayRef<SMLoc> locs,
- RecordKeeper &records) :
+ RecordKeeper &records, bool Anonymous = false) :
ID(LastID++), Name(StringInit::get(N)), Locs(locs.begin(), locs.end()),
- TrackedRecords(records), TheInit(0) {
+ TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
init();
}
- explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records) :
+ explicit Record(Init *N, ArrayRef<SMLoc> locs, RecordKeeper &records,
+ bool Anonymous = false) :
ID(LastID++), Name(N), Locs(locs.begin(), locs.end()),
- TrackedRecords(records), TheInit(0) {
+ TrackedRecords(records), TheInit(0), IsAnonymous(Anonymous) {
init();
}
@@ -1417,7 +1417,8 @@ public:
Record(const Record &O) :
ID(LastID++), Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs),
Values(O.Values), SuperClasses(O.SuperClasses),
- TrackedRecords(O.TrackedRecords), TheInit(O.TheInit) { }
+ SuperClassRanges(O.SuperClassRanges), TrackedRecords(O.TrackedRecords),
+ TheInit(O.TheInit), IsAnonymous(O.IsAnonymous) { }
~Record() {}
@@ -1448,6 +1449,7 @@ public:
}
const std::vector<RecordVal> &getValues() const { return Values; }
const std::vector<Record*> &getSuperClasses() const { return SuperClasses; }
+ ArrayRef<SMRange> getSuperClassRanges() const { return SuperClassRanges; }
bool isTemplateArg(Init *Name) const {
for (unsigned i = 0, e = TemplateArgs.size(); i != e; ++i)
@@ -1522,9 +1524,10 @@ public:
return false;
}
- void addSuperClass(Record *R) {
+ void addSuperClass(Record *R, SMRange Range) {
assert(!isSubClassOf(R) && "Already subclassing record!");
SuperClasses.push_back(R);
+ SuperClassRanges.push_back(Range);
}
/// resolveReferences - If there are any field references that refer to fields
@@ -1541,6 +1544,10 @@ public:
return TrackedRecords;
}
+ bool isAnonymous() const {
+ return IsAnonymous;
+ }
+
void dump() const;
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/TableGen/StringMatcher.h b/include/llvm/TableGen/StringMatcher.h
index 1b0572f..99cbcad 100644
--- a/include/llvm/TableGen/StringMatcher.h
+++ b/include/llvm/TableGen/StringMatcher.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef STRINGMATCHER_H
-#define STRINGMATCHER_H
+#ifndef LLVM_TABLEGEN_STRINGMATCHER_H
+#define LLVM_TABLEGEN_STRINGMATCHER_H
#include "llvm/ADT/StringRef.h"
#include <string>
diff --git a/include/llvm/Target/CostTable.h b/include/llvm/Target/CostTable.h
new file mode 100644
index 0000000..a974b56
--- /dev/null
+++ b/include/llvm/Target/CostTable.h
@@ -0,0 +1,64 @@
+//===-- CostTable.h - Instruction Cost Table handling -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Cost tables and simple lookup functions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_COSTTABLE_H_
+#define LLVM_TARGET_COSTTABLE_H_
+
+namespace llvm {
+
+/// Cost Table Entry
+template <class TypeTy>
+struct CostTblEntry {
+ int ISD;
+ TypeTy Type;
+ unsigned Cost;
+};
+
+/// Find in cost table, TypeTy must be comparable by ==
+template <class TypeTy>
+int CostTableLookup(const CostTblEntry<TypeTy> *Tbl,
+ unsigned len, int ISD, TypeTy Ty) {
+ for (unsigned int i = 0; i < len; ++i)
+ if (Tbl[i].ISD == ISD && Tbl[i].Type == Ty)
+ return i;
+
+ // Could not find an entry.
+ return -1;
+}
+
+/// Type Conversion Cost Table
+template <class TypeTy>
+struct TypeConversionCostTblEntry {
+ int ISD;
+ TypeTy Dst;
+ TypeTy Src;
+ unsigned Cost;
+};
+
+/// Find in type conversion cost table, TypeTy must be comparable by ==
+template <class TypeTy>
+int ConvertCostTableLookup(const TypeConversionCostTblEntry<TypeTy> *Tbl,
+ unsigned len, int ISD, TypeTy Dst, TypeTy Src) {
+ for (unsigned int i = 0; i < len; ++i)
+ if (Tbl[i].ISD == ISD && Tbl[i].Src == Src && Tbl[i].Dst == Dst)
+ return i;
+
+ // Could not find an entry.
+ return -1;
+}
+
+} // namespace llvm
+
+
+#endif /* LLVM_TARGET_COSTTABLE_H_ */
diff --git a/include/llvm/Target/Mangler.h b/include/llvm/Target/Mangler.h
index a50f54a..9500f1c 100644
--- a/include/llvm/Target/Mangler.h
+++ b/include/llvm/Target/Mangler.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_MANGLER_H
-#define LLVM_SUPPORT_MANGLER_H
+#ifndef LLVM_TARGET_MANGLER_H
+#define LLVM_TARGET_MANGLER_H
#include "llvm/ADT/DenseMap.h"
@@ -69,4 +69,4 @@ public:
} // End llvm namespace
-#endif // LLVM_SUPPORT_MANGLER_H
+#endif // LLVM_TARGET_MANGLER_H
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 1781e47..876479b 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -367,8 +367,9 @@ class Instruction {
// hasSideEffects - The instruction has side effects that are not
// captured by any operands of the instruction or other flags.
//
- // neverHasSideEffects - Set on an instruction with no pattern if it has no
- // side effects.
+ // neverHasSideEffects (deprecated) - Set on an instruction with no pattern
+ // if it has no side effects. This is now equivalent to setting
+ // "hasSideEffects = 0".
bit hasSideEffects = ?;
bit neverHasSideEffects = 0;
diff --git a/include/llvm/Target/TargetFrameLowering.h b/include/llvm/Target/TargetFrameLowering.h
index 1958f90..58bfcec 100644
--- a/include/llvm/Target/TargetFrameLowering.h
+++ b/include/llvm/Target/TargetFrameLowering.h
@@ -120,6 +120,10 @@ public:
/// by adding a check even before the "normal" function prologue.
virtual void adjustForSegmentedStacks(MachineFunction &MF) const { }
+ /// Adjust the prologue to add Erlang Run-Time System (ERTS) specific code in
+ /// the assembly prologue to explicitly handle the stack.
+ virtual void adjustForHiPEPrologue(MachineFunction &MF) const { }
+
/// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee
/// saved registers and returns true if it isn't possible / profitable to do
/// so by issuing a series of store instructions via
@@ -192,6 +196,21 @@ public:
///
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}
+
+ /// 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
+ /// for eliminating these instructions, replacing them with concrete
+ /// instructions. This method need only be implemented if using call frame
+ /// setup/destroy pseudo instructions.
+ ///
+ virtual void
+ eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
+ "target!");
+ }
};
} // End llvm namespace
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index eee25c9..a28d63a 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -68,17 +68,12 @@ namespace llvm {
};
}
-//===----------------------------------------------------------------------===//
-/// TargetLowering - This class defines information used to lower LLVM code to
-/// legal SelectionDAG operators that the target instruction selector can accept
-/// natively.
-///
-/// This class also defines callbacks that targets must implement to lower
-/// target-specific constructs to SelectionDAG operators.
-///
-class TargetLowering {
- TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
- void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
+/// TargetLoweringBase - This base class for TargetLowering contains the
+/// SelectionDAG-independent parts that can be used from the rest of CodeGen.
+class TargetLoweringBase {
+ TargetLoweringBase(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLoweringBase&) LLVM_DELETED_FUNCTION;
+
public:
/// LegalizeAction - This enum indicates whether operations are valid for a
/// target, and if not, what action should be used to make them valid.
@@ -136,9 +131,9 @@ public:
}
/// NOTE: The constructor takes ownership of TLOF.
- explicit TargetLowering(const TargetMachine &TM,
- const TargetLoweringObjectFile *TLOF);
- virtual ~TargetLowering();
+ explicit TargetLoweringBase(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
+ virtual ~TargetLoweringBase();
const TargetMachine &getTargetMachine() const { return TM; }
const DataLayout *getDataLayout() const { return TD; }
@@ -188,7 +183,7 @@ public:
/// isPredictableSelectExpensive - Return true if selects are only cheaper
/// than branches if the branch is unlikely to be predicted right.
bool isPredictableSelectExpensive() const {
- return predictableSelectIsExpensive;
+ return PredictableSelectIsExpensive;
}
/// getSetCCResultType - Return the ValueType of the result of SETCC
@@ -664,7 +659,7 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memset
unsigned getMaxStoresPerMemset(bool OptSize) const {
- return OptSize ? maxStoresPerMemsetOptSize : maxStoresPerMemset;
+ return OptSize ? MaxStoresPerMemsetOptSize : MaxStoresPerMemset;
}
/// This function returns the maximum number of store operations permitted
@@ -673,7 +668,7 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memcpy
unsigned getMaxStoresPerMemcpy(bool OptSize) const {
- return OptSize ? maxStoresPerMemcpyOptSize : maxStoresPerMemcpy;
+ return OptSize ? MaxStoresPerMemcpyOptSize : MaxStoresPerMemcpy;
}
/// This function returns the maximum number of store operations permitted
@@ -682,7 +677,7 @@ public:
/// return the limit for functions that have OptSize attribute.
/// @brief Get maximum # of store operations permitted for llvm.memmove
unsigned getMaxStoresPerMemmove(bool OptSize) const {
- return OptSize ? maxStoresPerMemmoveOptSize : maxStoresPerMemmove;
+ return OptSize ? MaxStoresPerMemmoveOptSize : MaxStoresPerMemmove;
}
/// This function returns true if the target allows unaligned memory accesses.
@@ -701,7 +696,7 @@ public:
/// optimization.
/// @brief Determine if the target should perform code placement optimization.
bool shouldOptimizeCodePlacement() const {
- return benefitFromCodePlacementOpt;
+ return BenefitFromCodePlacementOpt;
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
@@ -829,55 +824,6 @@ public:
return InsertFencesForAtomic;
}
- /// getPreIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if the node's address
- /// can be legally represented as pre-indexed load / store address.
- virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
- SDValue &/*Offset*/,
- ISD::MemIndexedMode &/*AM*/,
- SelectionDAG &/*DAG*/) const {
- return false;
- }
-
- /// getPostIndexedAddressParts - returns true by value, base pointer and
- /// offset pointer and addressing mode by reference if this node can be
- /// combined with a load / store to form a post-indexed load / store.
- virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
- SDValue &/*Base*/, SDValue &/*Offset*/,
- ISD::MemIndexedMode &/*AM*/,
- SelectionDAG &/*DAG*/) const {
- return false;
- }
-
- /// getJumpTableEncoding - Return the entry encoding for a jump table in the
- /// current function. The returned value is a member of the
- /// MachineJumpTableInfo::JTEntryKind enum.
- virtual unsigned getJumpTableEncoding() const;
-
- virtual const MCExpr *
- LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
- const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
- MCContext &/*Ctx*/) const {
- llvm_unreachable("Need to implement this hook if target has custom JTIs");
- }
-
- /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
- /// jumptable.
- virtual SDValue getPICJumpTableRelocBase(SDValue Table,
- SelectionDAG &DAG) const;
-
- /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
- /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
- /// MCExpr.
- virtual const MCExpr *
- getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
- unsigned JTI, MCContext &Ctx) const;
-
- /// isOffsetFoldingLegal - Return true if folding a constant offset
- /// with the given GlobalAddress is legal. It is frequently not legal in
- /// PIC relocation models.
- virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
-
/// getStackCookieLocation - Return true if the target stores stack
/// protector cookies at a fixed offset in some non-standard address
/// space, and populates the address space and offset as
@@ -906,152 +852,6 @@ public:
/// @}
//===--------------------------------------------------------------------===//
- // TargetLowering Optimization Methods
- //
-
- /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
- /// SDValues for returning information from TargetLowering to its clients
- /// that want to combine
- struct TargetLoweringOpt {
- SelectionDAG &DAG;
- bool LegalTys;
- bool LegalOps;
- SDValue Old;
- SDValue New;
-
- explicit TargetLoweringOpt(SelectionDAG &InDAG,
- bool LT, bool LO) :
- DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
-
- bool LegalTypes() const { return LegalTys; }
- bool LegalOperations() const { return LegalOps; }
-
- bool CombineTo(SDValue O, SDValue N) {
- Old = O;
- New = N;
- return true;
- }
-
- /// ShrinkDemandedConstant - Check to see if the specified operand of the
- /// specified instruction is a constant integer. If so, check to see if
- /// there are any bits set in the constant that are not demanded. If so,
- /// shrink the constant and return true.
- bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
-
- /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
- /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
- /// cast, but it could be generalized for targets with other types of
- /// implicit widening casts.
- bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
- DebugLoc dl);
- };
-
- /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
- /// DemandedMask bits of the result of Op are ever used downstream. If we can
- /// use this information to simplify Op, create a new simplified DAG node and
- /// return true, returning the original and new nodes in Old and New.
- /// Otherwise, analyze the expression and return a mask of KnownOne and
- /// KnownZero bits for the expression (used to simplify the caller).
- /// The KnownZero/One bits may only be accurate for those bits in the
- /// DemandedMask.
- bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
- APInt &KnownZero, APInt &KnownOne,
- TargetLoweringOpt &TLO, unsigned Depth = 0) const;
-
- /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
- /// Mask are known to be either zero or one and return them in the
- /// KnownZero/KnownOne bitsets.
- virtual void computeMaskedBitsForTargetNode(const SDValue Op,
- APInt &KnownZero,
- APInt &KnownOne,
- const SelectionDAG &DAG,
- unsigned Depth = 0) const;
-
- /// ComputeNumSignBitsForTargetNode - This method can be implemented by
- /// targets that want to expose additional information about sign bits to the
- /// DAG Combiner.
- virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
- unsigned Depth = 0) const;
-
- struct DAGCombinerInfo {
- void *DC; // The DAG Combiner object.
- CombineLevel Level;
- bool CalledByLegalizer;
- public:
- SelectionDAG &DAG;
-
- DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc)
- : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
-
- bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
- bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
- bool isAfterLegalizeVectorOps() const {
- return Level == AfterLegalizeDAG;
- }
- CombineLevel getDAGCombineLevel() { return Level; }
- bool isCalledByLegalizer() const { return CalledByLegalizer; }
-
- void AddToWorklist(SDNode *N);
- void RemoveFromWorklist(SDNode *N);
- SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
- bool AddTo = true);
- SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
- SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
-
- void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
- };
-
- /// SimplifySetCC - Try to simplify a setcc built with the specified operands
- /// and cc. If it is unable to simplify it, return a null SDValue.
- SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
- ISD::CondCode Cond, bool foldBooleans,
- DAGCombinerInfo &DCI, DebugLoc dl) const;
-
- /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
- /// node is a GlobalAddress + offset.
- virtual bool
- isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
-
- /// PerformDAGCombine - This method will be invoked for all target nodes and
- /// for any target-independent nodes that the target has registered with
- /// invoke it for.
- ///
- /// The semantics are as follows:
- /// Return Value:
- /// SDValue.Val == 0 - No change was made
- /// SDValue.Val == N - N was replaced, is dead, and is already handled.
- /// otherwise - N should be replaced by the returned Operand.
- ///
- /// In addition, methods provided by DAGCombinerInfo may be used to perform
- /// more complex transformations.
- ///
- virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
-
- /// isTypeDesirableForOp - Return true if the target has native support for
- /// the specified value type and it is 'desirable' to use the type for the
- /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
- /// instruction encodings are longer and some i16 instructions are slow.
- virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
- // By default, assume all legal types are desirable.
- return isTypeLegal(VT);
- }
-
- /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
- /// to transform a floating point op of specified opcode to a equivalent op of
- /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
- virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/,
- EVT /*VT*/) const {
- return false;
- }
-
- /// IsDesirableToPromoteOp - This method query the target whether it is
- /// beneficial for dag combiner to promote the specified node. If true, it
- /// should return the desired promotion type by reference.
- virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
- return false;
- }
-
- //===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
//
@@ -1302,387 +1102,6 @@ protected:
public:
//===--------------------------------------------------------------------===//
- // Lowering methods - These methods must be implemented by targets so that
- // the SelectionDAGBuilder code knows how to lower these.
- //
-
- /// LowerFormalArguments - This hook must be implemented to lower the
- /// incoming (formal) arguments, described by the Ins array, into the
- /// specified DAG. The implementation should fill in the InVals array
- /// with legal-type argument values, and return the resulting token
- /// chain value.
- ///
- virtual SDValue
- LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
- bool /*isVarArg*/,
- const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
- DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
- SmallVectorImpl<SDValue> &/*InVals*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- struct ArgListEntry {
- SDValue Node;
- Type* Ty;
- bool isSExt : 1;
- bool isZExt : 1;
- bool isInReg : 1;
- bool isSRet : 1;
- bool isNest : 1;
- bool isByVal : 1;
- uint16_t Alignment;
-
- ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
- isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
- };
- typedef std::vector<ArgListEntry> ArgListTy;
-
- /// CallLoweringInfo - This structure contains all information that is
- /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
- /// SelectionDAG builder needs to lower a call, and targets will see this
- /// struct in their LowerCall implementation.
- struct CallLoweringInfo {
- SDValue Chain;
- Type *RetTy;
- bool RetSExt : 1;
- bool RetZExt : 1;
- bool IsVarArg : 1;
- bool IsInReg : 1;
- bool DoesNotReturn : 1;
- bool IsReturnValueUsed : 1;
-
- // IsTailCall should be modified by implementations of
- // TargetLowering::LowerCall that perform tail call conversions.
- bool IsTailCall;
-
- unsigned NumFixedArgs;
- CallingConv::ID CallConv;
- SDValue Callee;
- ArgListTy &Args;
- SelectionDAG &DAG;
- DebugLoc DL;
- ImmutableCallSite *CS;
- SmallVector<ISD::OutputArg, 32> Outs;
- SmallVector<SDValue, 32> OutVals;
- SmallVector<ISD::InputArg, 32> Ins;
-
-
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// ImmutableCallSite \p cs.
- CallLoweringInfo(SDValue chain, Type *retTy,
- FunctionType *FTy, bool isTailCall, SDValue callee,
- ArgListTy &args, SelectionDAG &dag, DebugLoc dl,
- ImmutableCallSite &cs)
- : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)),
- RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()),
- IsInReg(cs.paramHasAttr(0, Attribute::InReg)),
- DoesNotReturn(cs.doesNotReturn()),
- IsReturnValueUsed(!cs.getInstruction()->use_empty()),
- IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()),
- CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag),
- DL(dl), CS(&cs) {}
-
- /// CallLoweringInfo - Constructs a call lowering context based on the
- /// provided call information.
- CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt,
- bool isVarArg, bool isInReg, unsigned numFixedArgs,
- CallingConv::ID callConv, bool isTailCall,
- bool doesNotReturn, bool isReturnValueUsed, SDValue callee,
- ArgListTy &args, SelectionDAG &dag, DebugLoc dl)
- : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt),
- IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn),
- IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall),
- NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee),
- Args(args), DAG(dag), DL(dl), CS(NULL) {}
- };
-
- /// LowerCallTo - This function lowers an abstract call to a function into an
- /// actual call. This returns a pair of operands. The first element is the
- /// return value for the function (if RetTy is not VoidTy). The second
- /// element is the outgoing token chain. It calls LowerCall to do the actual
- /// lowering.
- std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
-
- /// LowerCall - This hook must be implemented to lower calls into the
- /// the specified DAG. The outgoing arguments to the call are described
- /// by the Outs array, and the values to be returned by the call are
- /// described by the Ins array. The implementation should fill in the
- /// InVals array with legal-type return values from the call, and return
- /// the resulting token chain value.
- virtual SDValue
- LowerCall(CallLoweringInfo &/*CLI*/,
- SmallVectorImpl<SDValue> &/*InVals*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
- virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
-
- /// CanLowerReturn - This hook should be implemented to check whether the
- /// return values described by the Outs array can fit into the return
- /// registers. If false is returned, an sret-demotion is performed.
- ///
- virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
- MachineFunction &/*MF*/, bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- LLVMContext &/*Context*/) const
- {
- // Return true by default to get preexisting behavior.
- return true;
- }
-
- /// LowerReturn - This hook must be implemented to lower outgoing
- /// return values, described by the Outs array, into the specified
- /// DAG. The implementation should return the resulting token chain
- /// value.
- ///
- virtual SDValue
- LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
- bool /*isVarArg*/,
- const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
- const SmallVectorImpl<SDValue> &/*OutVals*/,
- DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
- llvm_unreachable("Not Implemented");
- }
-
- /// isUsedByReturnOnly - Return true if result of the specified node is used
- /// by a return node only. It also compute and return the input chain for the
- /// tail call.
- /// This is used to determine whether it is possible
- /// to codegen a libcall as tail call at legalization time.
- virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const {
- return false;
- }
-
- /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
- /// call instruction as a tail call. This is used by optimization passes to
- /// determine if it's profitable to duplicate return instructions to enable
- /// tailcall optimization.
- virtual bool mayBeEmittedAsTailCall(CallInst *) const {
- return false;
- }
-
- /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
- /// sign extend a zeroext/signext integer argument or return value.
- /// FIXME: Most C calling convention requires the return type to be promoted,
- /// but this is not true all the time, e.g. i1 on x86-64. It is also not
- /// necessary for non-C calling conventions. The frontend should handle this
- /// and include all of the necessary information.
- virtual MVT getTypeForExtArgOrReturn(MVT VT,
- ISD::NodeType /*ExtendKind*/) const {
- MVT MinVT = getRegisterType(MVT::i32);
- return VT.bitsLT(MinVT) ? MinVT : VT;
- }
-
- /// LowerOperationWrapper - This callback is invoked by the type legalizer
- /// to legalize nodes with an illegal operand type but legal result types.
- /// It replaces the LowerOperation callback in the type Legalizer.
- /// The reason we can not do away with LowerOperation entirely is that
- /// LegalizeDAG isn't yet ready to use this callback.
- /// TODO: Consider merging with ReplaceNodeResults.
-
- /// The target places new result values for the node in Results (their number
- /// and types must exactly match those of the original return values of
- /// the node), or leaves Results empty, which indicates that the node is not
- /// to be custom lowered after all.
- /// The default implementation calls LowerOperation.
- virtual void LowerOperationWrapper(SDNode *N,
- SmallVectorImpl<SDValue> &Results,
- SelectionDAG &DAG) const;
-
- /// LowerOperation - This callback is invoked for operations that are
- /// unsupported by the target, which are registered to use 'custom' lowering,
- /// and whose defined values are all legal.
- /// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation of this aborts.
- virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
-
- /// ReplaceNodeResults - This callback is invoked when a node result type is
- /// illegal for the target, and the operation was registered to use 'custom'
- /// lowering for that result type. The target places new result values for
- /// the node in Results (their number and types must exactly match those of
- /// the original return values of the node), or leaves Results empty, which
- /// indicates that the node is not to be custom lowered after all.
- ///
- /// If the target has no operations that require custom lowering, it need not
- /// implement this. The default implementation aborts.
- virtual void ReplaceNodeResults(SDNode * /*N*/,
- SmallVectorImpl<SDValue> &/*Results*/,
- SelectionDAG &/*DAG*/) const {
- llvm_unreachable("ReplaceNodeResults not implemented for this target!");
- }
-
- /// getTargetNodeName() - This method returns the name of a target specific
- /// DAG node.
- virtual const char *getTargetNodeName(unsigned Opcode) const;
-
- /// createFastISel - This method returns a target specific FastISel object,
- /// or null if the target does not support "fast" ISel.
- virtual FastISel *createFastISel(FunctionLoweringInfo &,
- const TargetLibraryInfo *) const {
- return 0;
- }
-
- //===--------------------------------------------------------------------===//
- // Inline Asm Support hooks
- //
-
- /// ExpandInlineAsm - This hook allows the target to expand an inline asm
- /// call to be explicit llvm code if it wants to. This is useful for
- /// turning simple inline asms into LLVM intrinsics, which gives the
- /// compiler more information about the behavior of the code.
- virtual bool ExpandInlineAsm(CallInst *) const {
- return false;
- }
-
- enum ConstraintType {
- C_Register, // Constraint represents specific register(s).
- C_RegisterClass, // Constraint represents any of register(s) in class.
- C_Memory, // Memory constraint.
- C_Other, // Something else.
- C_Unknown // Unsupported constraint.
- };
-
- enum ConstraintWeight {
- // Generic weights.
- CW_Invalid = -1, // No match.
- CW_Okay = 0, // Acceptable.
- CW_Good = 1, // Good weight.
- CW_Better = 2, // Better weight.
- CW_Best = 3, // Best weight.
-
- // Well-known weights.
- CW_SpecificReg = CW_Okay, // Specific register operands.
- CW_Register = CW_Good, // Register operands.
- CW_Memory = CW_Better, // Memory operands.
- CW_Constant = CW_Best, // Constant operand.
- CW_Default = CW_Okay // Default or don't know type.
- };
-
- /// AsmOperandInfo - This contains information for each constraint that we are
- /// lowering.
- struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
- /// ConstraintCode - This contains the actual string for the code, like "m".
- /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
- /// most closely matches the operand.
- std::string ConstraintCode;
-
- /// ConstraintType - Information about the constraint code, e.g. Register,
- /// RegisterClass, Memory, Other, Unknown.
- TargetLowering::ConstraintType ConstraintType;
-
- /// CallOperandval - If this is the result output operand or a
- /// clobber, this is null, otherwise it is the incoming operand to the
- /// CallInst. This gets modified as the asm is processed.
- Value *CallOperandVal;
-
- /// ConstraintVT - The ValueType for the operand value.
- MVT ConstraintVT;
-
- /// isMatchingInputConstraint - Return true of this is an input operand that
- /// is a matching constraint like "4".
- bool isMatchingInputConstraint() const;
-
- /// getMatchedOperand - If this is an input matching constraint, this method
- /// returns the output operand it matches.
- unsigned getMatchedOperand() const;
-
- /// Copy constructor for copying from an AsmOperandInfo.
- AsmOperandInfo(const AsmOperandInfo &info)
- : InlineAsm::ConstraintInfo(info),
- ConstraintCode(info.ConstraintCode),
- ConstraintType(info.ConstraintType),
- CallOperandVal(info.CallOperandVal),
- ConstraintVT(info.ConstraintVT) {
- }
-
- /// Copy constructor for copying from a ConstraintInfo.
- AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
- : InlineAsm::ConstraintInfo(info),
- ConstraintType(TargetLowering::C_Unknown),
- CallOperandVal(0), ConstraintVT(MVT::Other) {
- }
- };
-
- typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
-
- /// ParseConstraints - Split up the constraint string from the inline
- /// assembly value into the specific constraints and their prefixes,
- /// and also tie in the associated operand values.
- /// If this returns an empty vector, and if the constraint string itself
- /// isn't empty, there was an error parsing.
- virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
-
- /// Examine constraint type and operand type and determine a weight value.
- /// The operand object must already have been set up with the operand type.
- virtual ConstraintWeight getMultipleConstraintMatchWeight(
- AsmOperandInfo &info, int maIndex) const;
-
- /// Examine constraint string and operand type and determine a weight value.
- /// The operand object must already have been set up with the operand type.
- virtual ConstraintWeight getSingleConstraintMatchWeight(
- AsmOperandInfo &info, const char *constraint) const;
-
- /// ComputeConstraintToUse - Determines the constraint code and constraint
- /// type to use for the specific AsmOperandInfo, setting
- /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
- /// being passed in is available, it can be passed in as Op, otherwise an
- /// empty SDValue can be passed.
- virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
- SDValue Op,
- SelectionDAG *DAG = 0) const;
-
- /// getConstraintType - Given a constraint, return the type of constraint it
- /// is for this target.
- virtual ConstraintType getConstraintType(const std::string &Constraint) const;
-
- /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
- /// {edx}), return the register number and the register class for the
- /// register.
- ///
- /// Given a register class constraint, like 'r', if this corresponds directly
- /// to an LLVM register class, return a register of 0 and the register class
- /// pointer.
- ///
- /// This should only be used for C_Register constraints. On error,
- /// this returns a register number of 0 and a null register class pointer..
- virtual std::pair<unsigned, const TargetRegisterClass*>
- getRegForInlineAsmConstraint(const std::string &Constraint,
- EVT VT) const;
-
- /// LowerXConstraint - try to replace an X constraint, which matches anything,
- /// with another that has more specific requirements based on the type of the
- /// corresponding operand. This returns null if there is no replacement to
- /// make.
- virtual const char *LowerXConstraint(EVT ConstraintVT) const;
-
- /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
- /// vector. If it is invalid, don't add anything to Ops.
- virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
- std::vector<SDValue> &Ops,
- SelectionDAG &DAG) const;
-
- //===--------------------------------------------------------------------===//
- // Instruction Emitting Hooks
- //
-
- // EmitInstrWithCustomInserter - This method should be implemented by targets
- // that mark instructions with the 'usesCustomInserter' flag. These
- // instructions are special in various ways, which require special support to
- // insert. The specified MachineInstr is created but not inserted into any
- // basic blocks, and this method is called to expand it into a sequence of
- // instructions, potentially also creating new basic blocks and control flow.
- virtual MachineBasicBlock *
- EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
-
- /// AdjustInstrPostInstrSelection - This method should be implemented by
- /// targets that mark instructions with the 'hasPostISelHook' flag. These
- /// instructions must be adjusted after instruction selection by target hooks.
- /// e.g. To fill in optional defs for ARM 's' setting instructions.
- virtual void
- AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
-
- //===--------------------------------------------------------------------===//
// Addressing mode description hooks (used by LSR etc).
//
@@ -1798,17 +1217,6 @@ public:
}
//===--------------------------------------------------------------------===//
- // Div utility functions
- //
- SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
- SelectionDAG &DAG) const;
- SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*> *Created) const;
- SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
- std::vector<SDNode*> *Created) const;
-
-
- //===--------------------------------------------------------------------===//
// Runtime Library hooks
//
@@ -2190,11 +1598,11 @@ protected:
/// with 16-bit alignment would result in four 2-byte stores and one 1-byte
/// store. This only applies to setting a constant array of a constant size.
/// @brief Specify maximum number of store instructions per memset call.
- unsigned maxStoresPerMemset;
+ unsigned MaxStoresPerMemset;
/// Maximum number of stores operations that may be substituted for the call
/// to memset, used for functions with OptSize attribute.
- unsigned maxStoresPerMemsetOptSize;
+ unsigned MaxStoresPerMemsetOptSize;
/// When lowering \@llvm.memcpy this field specifies the maximum number of
/// store operations that may be substituted for a call to memcpy. Targets
@@ -2206,11 +1614,11 @@ protected:
/// and one 1-byte store. This only applies to copying a constant array of
/// constant size.
/// @brief Specify maximum bytes of store instructions per memcpy call.
- unsigned maxStoresPerMemcpy;
+ unsigned MaxStoresPerMemcpy;
/// Maximum number of store operations that may be substituted for a call
/// to memcpy, used for functions with OptSize attribute.
- unsigned maxStoresPerMemcpyOptSize;
+ unsigned MaxStoresPerMemcpyOptSize;
/// When lowering \@llvm.memmove this field specifies the maximum number of
/// store instructions that may be substituted for a call to memmove. Targets
@@ -2221,26 +1629,641 @@ protected:
/// with 8-bit alignment would result in nine 1-byte stores. This only
/// applies to copying a constant array of constant size.
/// @brief Specify maximum bytes of store instructions per memmove call.
- unsigned maxStoresPerMemmove;
+ unsigned MaxStoresPerMemmove;
/// Maximum number of store instructions that may be substituted for a call
/// to memmove, used for functions with OpSize attribute.
- unsigned maxStoresPerMemmoveOptSize;
+ unsigned MaxStoresPerMemmoveOptSize;
/// This field specifies whether the target can benefit from code placement
/// optimization.
- bool benefitFromCodePlacementOpt;
+ bool BenefitFromCodePlacementOpt;
- /// predictableSelectIsExpensive - Tells the code generator that select is
+ /// PredictableSelectIsExpensive - Tells the code generator that select is
/// more expensive than a branch if the branch is usually predicted right.
- bool predictableSelectIsExpensive;
+ bool PredictableSelectIsExpensive;
-private:
+protected:
/// isLegalRC - Return true if the value types that can be represented by the
/// specified register class are all legal.
bool isLegalRC(const TargetRegisterClass *RC) const;
};
+//===----------------------------------------------------------------------===//
+/// TargetLowering - This class defines information used to lower LLVM code to
+/// legal SelectionDAG operators that the target instruction selector can accept
+/// natively.
+///
+/// This class also defines callbacks that targets must implement to lower
+/// target-specific constructs to SelectionDAG operators.
+///
+class TargetLowering : public TargetLoweringBase {
+ TargetLowering(const TargetLowering&) LLVM_DELETED_FUNCTION;
+ void operator=(const TargetLowering&) LLVM_DELETED_FUNCTION;
+
+public:
+ /// NOTE: The constructor takes ownership of TLOF.
+ explicit TargetLowering(const TargetMachine &TM,
+ const TargetLoweringObjectFile *TLOF);
+
+ /// getPreIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if the node's address
+ /// can be legally represented as pre-indexed load / store address.
+ virtual bool getPreIndexedAddressParts(SDNode * /*N*/, SDValue &/*Base*/,
+ SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getPostIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if this node can be
+ /// combined with a load / store to form a post-indexed load / store.
+ virtual bool getPostIndexedAddressParts(SDNode * /*N*/, SDNode * /*Op*/,
+ SDValue &/*Base*/, SDValue &/*Offset*/,
+ ISD::MemIndexedMode &/*AM*/,
+ SelectionDAG &/*DAG*/) const {
+ return false;
+ }
+
+ /// getJumpTableEncoding - Return the entry encoding for a jump table in the
+ /// current function. The returned value is a member of the
+ /// MachineJumpTableInfo::JTEntryKind enum.
+ virtual unsigned getJumpTableEncoding() const;
+
+ virtual const MCExpr *
+ LowerCustomJumpTableEntry(const MachineJumpTableInfo * /*MJTI*/,
+ const MachineBasicBlock * /*MBB*/, unsigned /*uid*/,
+ MCContext &/*Ctx*/) const {
+ llvm_unreachable("Need to implement this hook if target has custom JTIs");
+ }
+
+ /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
+ /// jumptable.
+ virtual SDValue getPICJumpTableRelocBase(SDValue Table,
+ SelectionDAG &DAG) const;
+
+ /// getPICJumpTableRelocBaseExpr - This returns the relocation base for the
+ /// given PIC jumptable, the same as getPICJumpTableRelocBase, but as an
+ /// MCExpr.
+ virtual const MCExpr *
+ getPICJumpTableRelocBaseExpr(const MachineFunction *MF,
+ unsigned JTI, MCContext &Ctx) const;
+
+ /// isOffsetFoldingLegal - Return true if folding a constant offset
+ /// with the given GlobalAddress is legal. It is frequently not legal in
+ /// PIC relocation models.
+ virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
+
+ bool isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
+ SDValue &Chain) const;
+
+ void softenSetCCOperands(SelectionDAG &DAG, EVT VT,
+ SDValue &NewLHS, SDValue &NewRHS,
+ ISD::CondCode &CCCode, DebugLoc DL) const;
+
+ SDValue makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC, EVT RetVT,
+ const SDValue *Ops, unsigned NumOps,
+ bool isSigned, DebugLoc dl) const;
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Optimization Methods
+ //
+
+ /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
+ /// SDValues for returning information from TargetLowering to its clients
+ /// that want to combine
+ struct TargetLoweringOpt {
+ SelectionDAG &DAG;
+ bool LegalTys;
+ bool LegalOps;
+ SDValue Old;
+ SDValue New;
+
+ explicit TargetLoweringOpt(SelectionDAG &InDAG,
+ bool LT, bool LO) :
+ DAG(InDAG), LegalTys(LT), LegalOps(LO) {}
+
+ bool LegalTypes() const { return LegalTys; }
+ bool LegalOperations() const { return LegalOps; }
+
+ bool CombineTo(SDValue O, SDValue N) {
+ Old = O;
+ New = N;
+ return true;
+ }
+
+ /// ShrinkDemandedConstant - Check to see if the specified operand of the
+ /// specified instruction is a constant integer. If so, check to see if
+ /// there are any bits set in the constant that are not demanded. If so,
+ /// shrink the constant and return true.
+ bool ShrinkDemandedConstant(SDValue Op, const APInt &Demanded);
+
+ /// ShrinkDemandedOp - Convert x+y to (VT)((SmallVT)x+(SmallVT)y) if the
+ /// casts are free. This uses isZExtFree and ZERO_EXTEND for the widening
+ /// cast, but it could be generalized for targets with other types of
+ /// implicit widening casts.
+ bool ShrinkDemandedOp(SDValue Op, unsigned BitWidth, const APInt &Demanded,
+ DebugLoc dl);
+ };
+
+ /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
+ /// DemandedMask bits of the result of Op are ever used downstream. If we can
+ /// use this information to simplify Op, create a new simplified DAG node and
+ /// return true, returning the original and new nodes in Old and New.
+ /// Otherwise, analyze the expression and return a mask of KnownOne and
+ /// KnownZero bits for the expression (used to simplify the caller).
+ /// The KnownZero/One bits may only be accurate for those bits in the
+ /// DemandedMask.
+ bool SimplifyDemandedBits(SDValue Op, const APInt &DemandedMask,
+ APInt &KnownZero, APInt &KnownOne,
+ TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+
+ /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
+ /// Mask are known to be either zero or one and return them in the
+ /// KnownZero/KnownOne bitsets.
+ virtual void computeMaskedBitsForTargetNode(const SDValue Op,
+ APInt &KnownZero,
+ APInt &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
+ /// ComputeNumSignBitsForTargetNode - This method can be implemented by
+ /// targets that want to expose additional information about sign bits to the
+ /// DAG Combiner.
+ virtual unsigned ComputeNumSignBitsForTargetNode(SDValue Op,
+ unsigned Depth = 0) const;
+
+ struct DAGCombinerInfo {
+ void *DC; // The DAG Combiner object.
+ CombineLevel Level;
+ bool CalledByLegalizer;
+ public:
+ SelectionDAG &DAG;
+
+ DAGCombinerInfo(SelectionDAG &dag, CombineLevel level, bool cl, void *dc)
+ : DC(dc), Level(level), CalledByLegalizer(cl), DAG(dag) {}
+
+ bool isBeforeLegalize() const { return Level == BeforeLegalizeTypes; }
+ bool isBeforeLegalizeOps() const { return Level < AfterLegalizeVectorOps; }
+ bool isAfterLegalizeVectorOps() const {
+ return Level == AfterLegalizeDAG;
+ }
+ CombineLevel getDAGCombineLevel() { return Level; }
+ bool isCalledByLegalizer() const { return CalledByLegalizer; }
+
+ void AddToWorklist(SDNode *N);
+ void RemoveFromWorklist(SDNode *N);
+ SDValue CombineTo(SDNode *N, const std::vector<SDValue> &To,
+ bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res, bool AddTo = true);
+ SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1, bool AddTo = true);
+
+ void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
+ };
+
+ /// SimplifySetCC - Try to simplify a setcc built with the specified operands
+ /// and cc. If it is unable to simplify it, return a null SDValue.
+ SDValue SimplifySetCC(EVT VT, SDValue N0, SDValue N1,
+ ISD::CondCode Cond, bool foldBooleans,
+ DAGCombinerInfo &DCI, DebugLoc dl) const;
+
+ /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
+ /// node is a GlobalAddress + offset.
+ virtual bool
+ isGAPlusOffset(SDNode *N, const GlobalValue* &GA, int64_t &Offset) const;
+
+ /// PerformDAGCombine - This method will be invoked for all target nodes and
+ /// for any target-independent nodes that the target has registered with
+ /// invoke it for.
+ ///
+ /// The semantics are as follows:
+ /// Return Value:
+ /// SDValue.Val == 0 - No change was made
+ /// SDValue.Val == N - N was replaced, is dead, and is already handled.
+ /// otherwise - N should be replaced by the returned Operand.
+ ///
+ /// In addition, methods provided by DAGCombinerInfo may be used to perform
+ /// more complex transformations.
+ ///
+ virtual SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+
+ /// isTypeDesirableForOp - Return true if the target has native support for
+ /// the specified value type and it is 'desirable' to use the type for the
+ /// given node type. e.g. On x86 i16 is legal, but undesirable since i16
+ /// instruction encodings are longer and some i16 instructions are slow.
+ virtual bool isTypeDesirableForOp(unsigned /*Opc*/, EVT VT) const {
+ // By default, assume all legal types are desirable.
+ return isTypeLegal(VT);
+ }
+
+ /// isDesirableToPromoteOp - Return true if it is profitable for dag combiner
+ /// to transform a floating point op of specified opcode to a equivalent op of
+ /// an integer type. e.g. f32 load -> i32 load can be profitable on ARM.
+ virtual bool isDesirableToTransformToIntegerOp(unsigned /*Opc*/,
+ EVT /*VT*/) const {
+ return false;
+ }
+
+ /// IsDesirableToPromoteOp - This method query the target whether it is
+ /// beneficial for dag combiner to promote the specified node. If true, it
+ /// should return the desired promotion type by reference.
+ virtual bool IsDesirableToPromoteOp(SDValue /*Op*/, EVT &/*PVT*/) const {
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Lowering methods - These methods must be implemented by targets so that
+ // the SelectionDAGBuilder code knows how to lower these.
+ //
+
+ /// LowerFormalArguments - This hook must be implemented to lower the
+ /// incoming (formal) arguments, described by the Ins array, into the
+ /// specified DAG. The implementation should fill in the InVals array
+ /// with legal-type argument values, and return the resulting token
+ /// chain value.
+ ///
+ virtual SDValue
+ LowerFormalArguments(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::InputArg> &/*Ins*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ struct ArgListEntry {
+ SDValue Node;
+ Type* Ty;
+ bool isSExt : 1;
+ bool isZExt : 1;
+ bool isInReg : 1;
+ bool isSRet : 1;
+ bool isNest : 1;
+ bool isByVal : 1;
+ uint16_t Alignment;
+
+ ArgListEntry() : isSExt(false), isZExt(false), isInReg(false),
+ isSRet(false), isNest(false), isByVal(false), Alignment(0) { }
+ };
+ typedef std::vector<ArgListEntry> ArgListTy;
+
+ /// CallLoweringInfo - This structure contains all information that is
+ /// necessary for lowering calls. It is passed to TLI::LowerCallTo when the
+ /// SelectionDAG builder needs to lower a call, and targets will see this
+ /// struct in their LowerCall implementation.
+ struct CallLoweringInfo {
+ SDValue Chain;
+ Type *RetTy;
+ bool RetSExt : 1;
+ bool RetZExt : 1;
+ bool IsVarArg : 1;
+ bool IsInReg : 1;
+ bool DoesNotReturn : 1;
+ bool IsReturnValueUsed : 1;
+
+ // IsTailCall should be modified by implementations of
+ // TargetLowering::LowerCall that perform tail call conversions.
+ bool IsTailCall;
+
+ unsigned NumFixedArgs;
+ CallingConv::ID CallConv;
+ SDValue Callee;
+ ArgListTy &Args;
+ SelectionDAG &DAG;
+ DebugLoc DL;
+ ImmutableCallSite *CS;
+ SmallVector<ISD::OutputArg, 32> Outs;
+ SmallVector<SDValue, 32> OutVals;
+ SmallVector<ISD::InputArg, 32> Ins;
+
+
+ /// CallLoweringInfo - Constructs a call lowering context based on the
+ /// ImmutableCallSite \p cs.
+ CallLoweringInfo(SDValue chain, Type *retTy,
+ FunctionType *FTy, bool isTailCall, SDValue callee,
+ ArgListTy &args, SelectionDAG &dag, DebugLoc dl,
+ ImmutableCallSite &cs)
+ : Chain(chain), RetTy(retTy), RetSExt(cs.paramHasAttr(0, Attribute::SExt)),
+ RetZExt(cs.paramHasAttr(0, Attribute::ZExt)), IsVarArg(FTy->isVarArg()),
+ IsInReg(cs.paramHasAttr(0, Attribute::InReg)),
+ DoesNotReturn(cs.doesNotReturn()),
+ IsReturnValueUsed(!cs.getInstruction()->use_empty()),
+ IsTailCall(isTailCall), NumFixedArgs(FTy->getNumParams()),
+ CallConv(cs.getCallingConv()), Callee(callee), Args(args), DAG(dag),
+ DL(dl), CS(&cs) {}
+
+ /// CallLoweringInfo - Constructs a call lowering context based on the
+ /// provided call information.
+ CallLoweringInfo(SDValue chain, Type *retTy, bool retSExt, bool retZExt,
+ bool isVarArg, bool isInReg, unsigned numFixedArgs,
+ CallingConv::ID callConv, bool isTailCall,
+ bool doesNotReturn, bool isReturnValueUsed, SDValue callee,
+ ArgListTy &args, SelectionDAG &dag, DebugLoc dl)
+ : Chain(chain), RetTy(retTy), RetSExt(retSExt), RetZExt(retZExt),
+ IsVarArg(isVarArg), IsInReg(isInReg), DoesNotReturn(doesNotReturn),
+ IsReturnValueUsed(isReturnValueUsed), IsTailCall(isTailCall),
+ NumFixedArgs(numFixedArgs), CallConv(callConv), Callee(callee),
+ Args(args), DAG(dag), DL(dl), CS(NULL) {}
+ };
+
+ /// LowerCallTo - This function lowers an abstract call to a function into an
+ /// actual call. This returns a pair of operands. The first element is the
+ /// return value for the function (if RetTy is not VoidTy). The second
+ /// element is the outgoing token chain. It calls LowerCall to do the actual
+ /// lowering.
+ std::pair<SDValue, SDValue> LowerCallTo(CallLoweringInfo &CLI) const;
+
+ /// LowerCall - This hook must be implemented to lower calls into the
+ /// the specified DAG. The outgoing arguments to the call are described
+ /// by the Outs array, and the values to be returned by the call are
+ /// described by the Ins array. The implementation should fill in the
+ /// InVals array with legal-type return values from the call, and return
+ /// the resulting token chain value.
+ virtual SDValue
+ LowerCall(CallLoweringInfo &/*CLI*/,
+ SmallVectorImpl<SDValue> &/*InVals*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// HandleByVal - Target-specific cleanup for formal ByVal parameters.
+ virtual void HandleByVal(CCState *, unsigned &, unsigned) const {}
+
+ /// CanLowerReturn - This hook should be implemented to check whether the
+ /// return values described by the Outs array can fit into the return
+ /// registers. If false is returned, an sret-demotion is performed.
+ ///
+ virtual bool CanLowerReturn(CallingConv::ID /*CallConv*/,
+ MachineFunction &/*MF*/, bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ LLVMContext &/*Context*/) const
+ {
+ // Return true by default to get preexisting behavior.
+ return true;
+ }
+
+ /// LowerReturn - This hook must be implemented to lower outgoing
+ /// return values, described by the Outs array, into the specified
+ /// DAG. The implementation should return the resulting token chain
+ /// value.
+ ///
+ virtual SDValue
+ LowerReturn(SDValue /*Chain*/, CallingConv::ID /*CallConv*/,
+ bool /*isVarArg*/,
+ const SmallVectorImpl<ISD::OutputArg> &/*Outs*/,
+ const SmallVectorImpl<SDValue> &/*OutVals*/,
+ DebugLoc /*dl*/, SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("Not Implemented");
+ }
+
+ /// isUsedByReturnOnly - Return true if result of the specified node is used
+ /// by a return node only. It also compute and return the input chain for the
+ /// tail call.
+ /// This is used to determine whether it is possible
+ /// to codegen a libcall as tail call at legalization time.
+ virtual bool isUsedByReturnOnly(SDNode *, SDValue &Chain) const {
+ return false;
+ }
+
+ /// mayBeEmittedAsTailCall - Return true if the target may be able emit the
+ /// call instruction as a tail call. This is used by optimization passes to
+ /// determine if it's profitable to duplicate return instructions to enable
+ /// tailcall optimization.
+ virtual bool mayBeEmittedAsTailCall(CallInst *) const {
+ return false;
+ }
+
+ /// getTypeForExtArgOrReturn - Return the type that should be used to zero or
+ /// sign extend a zeroext/signext integer argument or return value.
+ /// FIXME: Most C calling convention requires the return type to be promoted,
+ /// but this is not true all the time, e.g. i1 on x86-64. It is also not
+ /// necessary for non-C calling conventions. The frontend should handle this
+ /// and include all of the necessary information.
+ virtual MVT getTypeForExtArgOrReturn(MVT VT,
+ ISD::NodeType /*ExtendKind*/) const {
+ MVT MinVT = getRegisterType(MVT::i32);
+ return VT.bitsLT(MinVT) ? MinVT : VT;
+ }
+
+ /// LowerOperationWrapper - This callback is invoked by the type legalizer
+ /// to legalize nodes with an illegal operand type but legal result types.
+ /// It replaces the LowerOperation callback in the type Legalizer.
+ /// The reason we can not do away with LowerOperation entirely is that
+ /// LegalizeDAG isn't yet ready to use this callback.
+ /// TODO: Consider merging with ReplaceNodeResults.
+
+ /// The target places new result values for the node in Results (their number
+ /// and types must exactly match those of the original return values of
+ /// the node), or leaves Results empty, which indicates that the node is not
+ /// to be custom lowered after all.
+ /// The default implementation calls LowerOperation.
+ virtual void LowerOperationWrapper(SDNode *N,
+ SmallVectorImpl<SDValue> &Results,
+ SelectionDAG &DAG) const;
+
+ /// LowerOperation - This callback is invoked for operations that are
+ /// unsupported by the target, which are registered to use 'custom' lowering,
+ /// and whose defined values are all legal.
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation of this aborts.
+ virtual SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const;
+
+ /// ReplaceNodeResults - This callback is invoked when a node result type is
+ /// illegal for the target, and the operation was registered to use 'custom'
+ /// lowering for that result type. The target places new result values for
+ /// the node in Results (their number and types must exactly match those of
+ /// the original return values of the node), or leaves Results empty, which
+ /// indicates that the node is not to be custom lowered after all.
+ ///
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation aborts.
+ virtual void ReplaceNodeResults(SDNode * /*N*/,
+ SmallVectorImpl<SDValue> &/*Results*/,
+ SelectionDAG &/*DAG*/) const {
+ llvm_unreachable("ReplaceNodeResults not implemented for this target!");
+ }
+
+ /// getTargetNodeName() - This method returns the name of a target specific
+ /// DAG node.
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ /// createFastISel - This method returns a target specific FastISel object,
+ /// or null if the target does not support "fast" ISel.
+ virtual FastISel *createFastISel(FunctionLoweringInfo &,
+ const TargetLibraryInfo *) const {
+ return 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inline Asm Support hooks
+ //
+
+ /// ExpandInlineAsm - This hook allows the target to expand an inline asm
+ /// call to be explicit llvm code if it wants to. This is useful for
+ /// turning simple inline asms into LLVM intrinsics, which gives the
+ /// compiler more information about the behavior of the code.
+ virtual bool ExpandInlineAsm(CallInst *) const {
+ return false;
+ }
+
+ enum ConstraintType {
+ C_Register, // Constraint represents specific register(s).
+ C_RegisterClass, // Constraint represents any of register(s) in class.
+ C_Memory, // Memory constraint.
+ C_Other, // Something else.
+ C_Unknown // Unsupported constraint.
+ };
+
+ enum ConstraintWeight {
+ // Generic weights.
+ CW_Invalid = -1, // No match.
+ CW_Okay = 0, // Acceptable.
+ CW_Good = 1, // Good weight.
+ CW_Better = 2, // Better weight.
+ CW_Best = 3, // Best weight.
+
+ // Well-known weights.
+ CW_SpecificReg = CW_Okay, // Specific register operands.
+ CW_Register = CW_Good, // Register operands.
+ CW_Memory = CW_Better, // Memory operands.
+ CW_Constant = CW_Best, // Constant operand.
+ CW_Default = CW_Okay // Default or don't know type.
+ };
+
+ /// AsmOperandInfo - This contains information for each constraint that we are
+ /// lowering.
+ struct AsmOperandInfo : public InlineAsm::ConstraintInfo {
+ /// ConstraintCode - This contains the actual string for the code, like "m".
+ /// TargetLowering picks the 'best' code from ConstraintInfo::Codes that
+ /// most closely matches the operand.
+ std::string ConstraintCode;
+
+ /// ConstraintType - Information about the constraint code, e.g. Register,
+ /// RegisterClass, Memory, Other, Unknown.
+ TargetLowering::ConstraintType ConstraintType;
+
+ /// CallOperandval - If this is the result output operand or a
+ /// clobber, this is null, otherwise it is the incoming operand to the
+ /// CallInst. This gets modified as the asm is processed.
+ Value *CallOperandVal;
+
+ /// ConstraintVT - The ValueType for the operand value.
+ MVT ConstraintVT;
+
+ /// isMatchingInputConstraint - Return true of this is an input operand that
+ /// is a matching constraint like "4".
+ bool isMatchingInputConstraint() const;
+
+ /// getMatchedOperand - If this is an input matching constraint, this method
+ /// returns the output operand it matches.
+ unsigned getMatchedOperand() const;
+
+ /// Copy constructor for copying from an AsmOperandInfo.
+ AsmOperandInfo(const AsmOperandInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintCode(info.ConstraintCode),
+ ConstraintType(info.ConstraintType),
+ CallOperandVal(info.CallOperandVal),
+ ConstraintVT(info.ConstraintVT) {
+ }
+
+ /// Copy constructor for copying from a ConstraintInfo.
+ AsmOperandInfo(const InlineAsm::ConstraintInfo &info)
+ : InlineAsm::ConstraintInfo(info),
+ ConstraintType(TargetLowering::C_Unknown),
+ CallOperandVal(0), ConstraintVT(MVT::Other) {
+ }
+ };
+
+ typedef std::vector<AsmOperandInfo> AsmOperandInfoVector;
+
+ /// ParseConstraints - Split up the constraint string from the inline
+ /// assembly value into the specific constraints and their prefixes,
+ /// and also tie in the associated operand values.
+ /// If this returns an empty vector, and if the constraint string itself
+ /// isn't empty, there was an error parsing.
+ virtual AsmOperandInfoVector ParseConstraints(ImmutableCallSite CS) const;
+
+ /// Examine constraint type and operand type and determine a weight value.
+ /// The operand object must already have been set up with the operand type.
+ virtual ConstraintWeight getMultipleConstraintMatchWeight(
+ AsmOperandInfo &info, int maIndex) const;
+
+ /// Examine constraint string and operand type and determine a weight value.
+ /// The operand object must already have been set up with the operand type.
+ virtual ConstraintWeight getSingleConstraintMatchWeight(
+ AsmOperandInfo &info, const char *constraint) const;
+
+ /// ComputeConstraintToUse - Determines the constraint code and constraint
+ /// type to use for the specific AsmOperandInfo, setting
+ /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand
+ /// being passed in is available, it can be passed in as Op, otherwise an
+ /// empty SDValue can be passed.
+ virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo,
+ SDValue Op,
+ SelectionDAG *DAG = 0) const;
+
+ /// getConstraintType - Given a constraint, return the type of constraint it
+ /// is for this target.
+ virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+
+ /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
+ /// {edx}), return the register number and the register class for the
+ /// register.
+ ///
+ /// Given a register class constraint, like 'r', if this corresponds directly
+ /// to an LLVM register class, return a register of 0 and the register class
+ /// pointer.
+ ///
+ /// This should only be used for C_Register constraints. On error,
+ /// this returns a register number of 0 and a null register class pointer..
+ virtual std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint,
+ EVT VT) const;
+
+ /// LowerXConstraint - try to replace an X constraint, which matches anything,
+ /// with another that has more specific requirements based on the type of the
+ /// corresponding operand. This returns null if there is no replacement to
+ /// make.
+ virtual const char *LowerXConstraint(EVT ConstraintVT) const;
+
+ /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
+ /// vector. If it is invalid, don't add anything to Ops.
+ virtual void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
+ std::vector<SDValue> &Ops,
+ SelectionDAG &DAG) const;
+
+ //===--------------------------------------------------------------------===//
+ // Div utility functions
+ //
+ SDValue BuildExactSDIV(SDValue Op1, SDValue Op2, DebugLoc dl,
+ SelectionDAG &DAG) const;
+ SDValue BuildSDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*> *Created) const;
+ SDValue BuildUDIV(SDNode *N, SelectionDAG &DAG, bool IsAfterLegalization,
+ std::vector<SDNode*> *Created) const;
+
+ //===--------------------------------------------------------------------===//
+ // Instruction Emitting Hooks
+ //
+
+ // EmitInstrWithCustomInserter - This method should be implemented by targets
+ // that mark instructions with the 'usesCustomInserter' flag. These
+ // instructions are special in various ways, which require special support to
+ // insert. The specified MachineInstr is created but not inserted into any
+ // basic blocks, and this method is called to expand it into a sequence of
+ // instructions, potentially also creating new basic blocks and control flow.
+ virtual MachineBasicBlock *
+ EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
+
+ /// AdjustInstrPostInstrSelection - This method should be implemented by
+ /// targets that mark instructions with the 'hasPostISelHook' flag. These
+ /// instructions must be adjusted after instruction selection by target hooks.
+ /// e.g. To fill in optional defs for ARM 's' setting instructions.
+ virtual void
+ AdjustInstrPostInstrSelection(MachineInstr *MI, SDNode *Node) const;
+};
+
/// GetReturnInfo - Given an LLVM IR type and return type attributes,
/// compute the return value EVTs and flags, and optionally also
/// the offsets, if the return value is being lowered to memory.
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index aa049f0..35cf20a 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -59,10 +59,6 @@ protected: // Can only create subclasses.
TargetMachine(const Target &T, StringRef TargetTriple,
StringRef CPU, StringRef FS, const TargetOptions &Options);
- /// getSubtargetImpl - virtual method implemented by subclasses that returns
- /// a reference to that target's TargetSubtargetInfo-derived member variable.
- virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; }
-
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
@@ -95,6 +91,10 @@ public:
const StringRef getTargetCPU() const { return TargetCPU; }
const StringRef getTargetFeatureString() const { return TargetFS; }
+ /// getSubtargetImpl - virtual method implemented by subclasses that returns
+ /// a reference to that target's TargetSubtargetInfo-derived member variable.
+ virtual const TargetSubtargetInfo *getSubtargetImpl() const { return 0; }
+
TargetOptions Options;
// Interfaces to the major aspects of target machine information:
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
index 8fc566e..c31db24 100644
--- a/include/llvm/Target/TargetOptions.h
+++ b/include/llvm/Target/TargetOptions.h
@@ -48,10 +48,10 @@ namespace llvm {
UseSoftFloat(false), NoZerosInBSS(false), JITExceptionHandling(false),
JITEmitDebugInfo(false), JITEmitDebugInfoToDisk(false),
GuaranteedTailCallOpt(false), DisableTailCalls(false),
- StackAlignmentOverride(0), RealignStack(true), EnableFastISel(false),
- PositionIndependentExecutable(false), EnableSegmentedStacks(false),
- UseInitArray(false), TrapFuncName(""),FloatABIType(FloatABI::Default),
- AllowFPOpFusion(FPOpFusion::Standard)
+ StackAlignmentOverride(0), RealignStack(true), SSPBufferSize(0),
+ EnableFastISel(false), PositionIndependentExecutable(false),
+ EnableSegmentedStacks(false), UseInitArray(false), TrapFuncName(""),
+ FloatABIType(FloatABI::Default), AllowFPOpFusion(FPOpFusion::Standard)
{}
/// PrintMachineCode - This flag is enabled when the -print-machineinstrs
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index 2a8ef98..6b1e70b 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -733,21 +733,6 @@ public:
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
- /// 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
- /// for eliminating these instructions, replacing them with concrete
- /// instructions. This method need only be implemented if using call frame
- /// setup/destroy pseudo instructions.
- ///
- virtual void
- eliminateCallFramePseudoInstr(MachineFunction &MF,
- MachineBasicBlock &MBB,
- MachineBasicBlock::iterator MI) const {
- llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
- "target!");
- }
-
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false
@@ -767,10 +752,11 @@ public:
/// referenced by the iterator contains an MO_FrameIndex operand which must be
/// eliminated by this method. This method may modify or replace the
/// specified instruction, as long as it keeps the iterator pointing at the
- /// finished product. SPAdj is the SP adjustment due to call frame setup
- /// instruction.
+ /// finished product. SPAdj is the SP adjustment due to call frame setup
+ /// instruction. FIOperandNum is the FI operand number.
virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
- int SPAdj, RegScavenger *RS=NULL) const = 0;
+ int SPAdj, unsigned FIOperandNum,
+ RegScavenger *RS = NULL) const = 0;
//===--------------------------------------------------------------------===//
/// Debug information queries.
diff --git a/include/llvm/Target/TargetSchedule.td b/include/llvm/Target/TargetSchedule.td
index 0da82fd..b7920ba 100644
--- a/include/llvm/Target/TargetSchedule.td
+++ b/include/llvm/Target/TargetSchedule.td
@@ -76,6 +76,7 @@ class SchedMachineModel {
int IssueWidth = -1; // Max micro-ops that may be scheduled per cycle.
int MinLatency = -1; // Determines which instrucions are allowed in a group.
// (-1) inorder (0) ooo, (1): inorder +var latencies.
+ int ILPWindow = -1; // Cycles of latency likely hidden by hardware buffers.
int LoadLatency = -1; // Cycles for loads to access the cache.
int HighLatency = -1; // Approximation of cycles for "high latency" ops.
int MispredictPenalty = -1; // Extra cycles for a mispredicted branch.
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 3f22f47..b2d405d 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -19,6 +19,7 @@
namespace llvm {
+class MachineFunction;
class MachineInstr;
class SDep;
class SUnit;
@@ -73,6 +74,9 @@ public:
// the latency of a schedule dependency.
virtual void adjustSchedDependency(SUnit *def, SUnit *use,
SDep& dep) const { }
+
+ /// \brief Reset the features for the subtarget.
+ virtual void resetSubtargetFeatures(const MachineFunction *MF) { }
};
} // End llvm namespace
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 3ea0a42..209f68d 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_SUPPORT_PASSMANAGERBUILDER_H
-#define LLVM_SUPPORT_PASSMANAGERBUILDER_H
+#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
+#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
#include <vector>
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 5504dc9..fed92c8 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -39,9 +39,11 @@ ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
// Insert AddressSanitizer (address sanity checking) instrumentation
FunctionPass *createAddressSanitizerFunctionPass(
bool CheckInitOrder = false, bool CheckUseAfterReturn = false,
- bool CheckLifetime = false, StringRef BlacklistFile = StringRef());
+ bool CheckLifetime = false, StringRef BlacklistFile = StringRef(),
+ bool ZeroBaseShadow = false);
ModulePass *createAddressSanitizerModulePass(
- bool CheckInitOrder = false, StringRef BlacklistFile = StringRef());
+ bool CheckInitOrder = false, StringRef BlacklistFile = StringRef(),
+ bool ZeroBaseShadow = false);
// Insert MemorySanitizer instrumentation (detection of uninitialized reads)
FunctionPass *createMemorySanitizerPass(bool TrackOrigins = false,
diff --git a/include/llvm/Transforms/ObjCARC.h b/include/llvm/Transforms/ObjCARC.h
new file mode 100644
index 0000000..b3c19c0
--- /dev/null
+++ b/include/llvm/Transforms/ObjCARC.h
@@ -0,0 +1,49 @@
+//===-- ObjCARC.h - ObjCARC Scalar Transformations --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the ObjCARC Scalar Transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_OBJCARC_H
+#define LLVM_TRANSFORMS_OBJCARC_H
+
+namespace llvm {
+
+class Pass;
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCAPElim - ObjC ARC autorelease pool elimination.
+//
+Pass *createObjCARCAPElimPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCExpand - ObjC ARC preliminary simplifications.
+//
+Pass *createObjCARCExpandPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCContract - Late ObjC ARC cleanups.
+//
+Pass *createObjCARCContractPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ObjCARCOpt - ObjC ARC optimization.
+//
+Pass *createObjCARCOptPass();
+
+} // End llvm namespace
+
+#endif
+
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index d465127..e89759a 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -334,30 +334,6 @@ Pass *createCorrelatedValuePropagationPass();
//===----------------------------------------------------------------------===//
//
-// ObjCARCAPElim - ObjC ARC autorelease pool elimination.
-//
-Pass *createObjCARCAPElimPass();
-
-//===----------------------------------------------------------------------===//
-//
-// ObjCARCExpand - ObjC ARC preliminary simplifications.
-//
-Pass *createObjCARCExpandPass();
-
-//===----------------------------------------------------------------------===//
-//
-// ObjCARCContract - Late ObjC ARC cleanups.
-//
-Pass *createObjCARCContractPass();
-
-//===----------------------------------------------------------------------===//
-//
-// ObjCARCOpt - ObjC ARC optimization.
-//
-Pass *createObjCARCOptPass();
-
-//===----------------------------------------------------------------------===//
-//
// InstructionSimplifier - Remove redundant instructions.
//
FunctionPass *createInstructionSimplifierPass();
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
index d08f75e..8f1a6e2 100644
--- a/include/llvm/Transforms/Utils/BasicBlockUtils.h
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -12,14 +12,13 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
-#define LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
+#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
+#define LLVM_TRANSFORMS_UTILS_BASICBLOCKUTILS_H
// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
#include "llvm/IR/BasicBlock.h"
#include "llvm/Support/CFG.h"
-#include "llvm/Support/DebugLoc.h"
namespace llvm {
diff --git a/include/llvm/Transforms/Utils/BlackList.h b/include/llvm/Transforms/Utils/BlackList.h
new file mode 100644
index 0000000..f19470e
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BlackList.h
@@ -0,0 +1,58 @@
+//===-- BlackList.h - blacklist for sanitizers ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//===----------------------------------------------------------------------===//
+//
+// This is a utility class for instrumentation passes (like AddressSanitizer
+// or ThreadSanitizer) to avoid instrumenting some functions or global
+// variables based on a user-supplied blacklist.
+//
+// The blacklist disables instrumentation of various functions and global
+// variables. Each line contains a prefix, followed by a wild card expression.
+// Empty lines and lines starting with "#" are ignored.
+// ---
+// # Blacklisted items:
+// fun:*_ZN4base6subtle*
+// global:*global_with_bad_access_or_initialization*
+// global-init:*global_with_initialization_issues*
+// global-init-type:*Namespace::ClassName*
+// src:file_with_tricky_code.cc
+// ---
+// Note that the wild card is in fact an llvm::Regex, but * is automatically
+// replaced with .*
+// This is similar to the "ignore" feature of ThreadSanitizer.
+// http://code.google.com/p/data-race-test/wiki/ThreadSanitizerIgnores
+//
+//===----------------------------------------------------------------------===//
+//
+
+#include "llvm/ADT/StringMap.h"
+
+namespace llvm {
+class Function;
+class GlobalVariable;
+class Module;
+class Regex;
+class StringRef;
+
+class BlackList {
+ public:
+ BlackList(const StringRef Path);
+ // Returns whether either this function or it's source file are blacklisted.
+ bool isIn(const Function &F) const;
+ // Returns whether either this global or it's source file are blacklisted.
+ bool isIn(const GlobalVariable &G) const;
+ // Returns whether this module is blacklisted by filename.
+ bool isIn(const Module &M) const;
+ // Returns whether a global should be excluded from initialization checking.
+ bool isInInit(const GlobalVariable &G) const;
+ private:
+ StringMap<Regex*> Entries;
+
+ bool inSection(const StringRef Section, const StringRef Query) const;
+};
+
+} // namespace llvm
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index ca2d8f6..181ed07 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TRANSFORMS_UTILS_BUILDLIBCALLS_H
-#define TRANSFORMS_UTILS_BUILDLIBCALLS_H
+#ifndef LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
+#define LLVM_TRANSFORMS_UTILS_BUILDLIBCALLS_H
#include "llvm/IR/IRBuilder.h"
diff --git a/include/llvm/Transforms/Utils/BypassSlowDivision.h b/include/llvm/Transforms/Utils/BypassSlowDivision.h
index b11be05..0d081c0 100644
--- a/include/llvm/Transforms/Utils/BypassSlowDivision.h
+++ b/include/llvm/Transforms/Utils/BypassSlowDivision.h
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
-#define TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
+#ifndef LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
+#define LLVM_TRANSFORMS_UTILS_BYPASSSLOWDIVISION_H
#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/Function.h"
diff --git a/include/llvm/Transforms/Utils/IntegerDivision.h b/include/llvm/Transforms/Utils/IntegerDivision.h
index cecc807..27d3c58 100644
--- a/include/llvm/Transforms/Utils/IntegerDivision.h
+++ b/include/llvm/Transforms/Utils/IntegerDivision.h
@@ -14,8 +14,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TRANSFORMS_UTILS_INTEGERDIVISION_H
-#define TRANSFORMS_UTILS_INTEGERDIVISION_H
+#ifndef LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
+#define LLVM_TRANSFORMS_UTILS_INTEGERDIVISION_H
namespace llvm {
class BinaryOperator;
@@ -43,6 +43,20 @@ namespace llvm {
/// @brief Replace Div with generated code.
bool expandDivision(BinaryOperator* Div);
+ /// Generate code to calculate the remainder of two integers, replacing Rem
+ /// with the generated code. Uses the above 32bit routine, therefore adequate
+ /// for targets with little or no support for less than 32 bit arithmetic.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandRemainderUpTo32Bits(BinaryOperator *Rem);
+
+ /// Generate code to divide two integers, replacing Div with the generated
+ /// code. Uses the above 32bit routine, therefore adequate for targets with
+ /// little or no support for less than 32 bit arithmetic.
+ ///
+ /// @brief Replace Rem with generated code.
+ bool expandDivisionUpTo32Bits(BinaryOperator *Div);
+
} // End llvm namespace
#endif
diff --git a/include/llvm/Transforms/Utils/ModuleUtils.h b/include/llvm/Transforms/Utils/ModuleUtils.h
index 2c0ec9b..bb7fc06 100644
--- a/include/llvm/Transforms/Utils/ModuleUtils.h
+++ b/include/llvm/Transforms/Utils/ModuleUtils.h
@@ -11,8 +11,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
-#define LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
+#ifndef LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
+#define LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
namespace llvm {
@@ -30,4 +30,4 @@ void appendToGlobalDtors(Module &M, Function *F, int Priority);
} // End llvm namespace
-#endif // LLVM_TRANSFORMS_UTILS_MODULE_UTILS_H
+#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
index 0bb6ec6..52a6157 100644
--- a/include/llvm/Transforms/Utils/PromoteMemToReg.h
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -12,8 +12,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
-#define TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+#ifndef LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+#define LLVM_TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
#include <vector>
diff --git a/include/llvm/Transforms/Vectorize.h b/include/llvm/Transforms/Vectorize.h
index 1ba4d22..d205dbd 100644
--- a/include/llvm/Transforms/Vectorize.h
+++ b/include/llvm/Transforms/Vectorize.h
@@ -84,6 +84,9 @@ struct VectorizeConfig {
/// @brief The maximum number of pairable instructions per group.
unsigned MaxInsts;
+ /// @brief The maximum number of candidate instruction pairs per group.
+ unsigned MaxPairs;
+
/// @brief The maximum number of pairing iterations.
unsigned MaxIter;