aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2015-04-08 08:55:49 -0700
committerPirama Arumuga Nainar <pirama@google.com>2015-04-09 15:04:38 -0700
commit4c5e43da7792f75567b693105cc53e3f1992ad98 (patch)
tree1b2c9792582e12f5af0b1512e3094425f0dc0df9 /include
parentc75239e6119d0f9a74c57099d91cbc9bde56bf33 (diff)
downloadexternal_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.zip
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.gz
external_llvm-4c5e43da7792f75567b693105cc53e3f1992ad98.tar.bz2
Update aosp/master llvm for rebase to r233350
Change-Id: I07d935f8793ee8ec6b7da003f6483046594bca49
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/Linker.h14
-rw-r--r--include/llvm/ADT/APFloat.h6
-rw-r--r--include/llvm/ADT/APInt.h9
-rw-r--r--include/llvm/ADT/ArrayRef.h65
-rw-r--r--include/llvm/ADT/BitVector.h2
-rw-r--r--include/llvm/ADT/DeltaAlgorithm.h2
-rw-r--r--include/llvm/ADT/DenseMap.h73
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h38
-rw-r--r--include/llvm/ADT/EpochTracker.h99
-rw-r--r--include/llvm/ADT/FoldingSet.h14
-rw-r--r--include/llvm/ADT/ImmutableMap.h58
-rw-r--r--include/llvm/ADT/ImmutableSet.h170
-rw-r--r--include/llvm/ADT/IndexedMap.h7
-rw-r--r--include/llvm/ADT/IntervalMap.h18
-rw-r--r--include/llvm/ADT/IntrusiveRefCntPtr.h7
-rw-r--r--include/llvm/ADT/MapVector.h5
-rw-r--r--include/llvm/ADT/PostOrderIterator.h53
-rw-r--r--include/llvm/ADT/STLExtras.h78
-rw-r--r--include/llvm/ADT/SmallBitVector.h2
-rw-r--r--include/llvm/ADT/SmallVector.h22
-rw-r--r--include/llvm/ADT/StringRef.h9
-rw-r--r--include/llvm/ADT/Triple.h3
-rw-r--r--include/llvm/ADT/Twine.h102
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h7
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h5
-rw-r--r--include/llvm/Analysis/ConstantFolding.h30
-rw-r--r--include/llvm/Analysis/ConstantsScanner.h93
-rw-r--r--include/llvm/Analysis/DependenceAnalysis.h9
-rw-r--r--include/llvm/Analysis/DominanceFrontierImpl.h2
-rw-r--r--include/llvm/Analysis/IVUsers.h1
-rw-r--r--include/llvm/Analysis/InstructionSimplify.h69
-rw-r--r--include/llvm/Analysis/IntervalIterator.h33
-rw-r--r--include/llvm/Analysis/LazyValueInfo.h1
-rw-r--r--include/llvm/Analysis/LibCallAliasAnalysis.h8
-rw-r--r--include/llvm/Analysis/LibCallSemantics.h26
-rw-r--r--include/llvm/Analysis/Loads.h3
-rw-r--r--include/llvm/Analysis/LoopAccessAnalysis.h254
-rw-r--r--include/llvm/Analysis/LoopInfoImpl.h2
-rw-r--r--include/llvm/Analysis/MemoryBuiltins.h21
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h5
-rw-r--r--include/llvm/Analysis/PHITransAddr.h8
-rw-r--r--include/llvm/Analysis/Passes.h4
-rw-r--r--include/llvm/Analysis/RegionIterator.h20
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h59
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h10
-rw-r--r--include/llvm/Analysis/TargetFolder.h4
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.def1029
-rw-r--r--include/llvm/Analysis/TargetLibraryInfo.h746
-rw-r--r--include/llvm/Analysis/TargetTransformInfo.h18
-rw-r--r--include/llvm/Analysis/TargetTransformInfoImpl.h6
-rw-r--r--include/llvm/Analysis/ValueTracking.h53
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h3
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h6
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h68
-rw-r--r--include/llvm/CodeGen/BasicTTIImpl.h58
-rw-r--r--include/llvm/CodeGen/DIE.h53
-rw-r--r--include/llvm/CodeGen/ForwardControlFlowIntegrity.h122
-rw-r--r--include/llvm/CodeGen/ISDOpcodes.h2
-rw-r--r--include/llvm/CodeGen/JumpInstrTables.h105
-rw-r--r--include/llvm/CodeGen/LatencyPriorityQueue.h2
-rw-r--r--include/llvm/CodeGen/LiveInterval.h16
-rw-r--r--include/llvm/CodeGen/LivePhysRegs.h6
-rw-r--r--include/llvm/CodeGen/LiveStackAnalysis.h3
-rw-r--r--include/llvm/CodeGen/MachineDominators.h74
-rw-r--r--include/llvm/CodeGen/MachineInstr.h13
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h4
-rw-r--r--include/llvm/CodeGen/MachineMemOperand.h18
-rw-r--r--include/llvm/CodeGen/MachineOperand.h2
-rw-r--r--include/llvm/CodeGen/MachineRegisterInfo.h15
-rw-r--r--include/llvm/CodeGen/MachineValueType.h4
-rw-r--r--include/llvm/CodeGen/Passes.h23
-rw-r--r--include/llvm/CodeGen/RegAllocPBQP.h6
-rw-r--r--include/llvm/CodeGen/ResourcePriorityQueue.h8
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h4
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h6
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h4
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h379
-rw-r--r--include/llvm/CodeGen/StackMapLivenessAnalysis.h64
-rw-r--r--include/llvm/CodeGen/StackMaps.h6
-rw-r--r--include/llvm/CodeGen/TargetLoweringObjectFileImpl.h15
-rw-r--r--include/llvm/CodeGen/ValueTypes.h7
-rw-r--r--include/llvm/Config/config.h.cmake60
-rw-r--r--include/llvm/Config/config.h.in72
-rw-r--r--include/llvm/Config/llvm-config.h.cmake4
-rw-r--r--include/llvm/Config/llvm-config.h.in3
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h14
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h5
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFFormValue.h3
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h1
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h2
-rw-r--r--include/llvm/DebugInfo/PDB/DIA/DIASession.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDB.h4
-rw-r--r--include/llvm/DebugInfo/PDB/PDBExtras.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymDumper.h86
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbol.h3
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolBlock.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolCustom.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolData.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolExe.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFunc.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolLabel.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolThunk.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h5
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBTypes.h36
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h3
-rw-r--r--include/llvm/ExecutionEngine/JITSymbolFlags.h81
-rw-r--r--include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h17
-rw-r--r--include/llvm/ExecutionEngine/Orc/IndirectionUtils.h109
-rw-r--r--include/llvm/ExecutionEngine/Orc/JITSymbol.h19
-rw-r--r--include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h116
-rw-r--r--include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h50
-rw-r--r--include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h7
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyld.h27
-rw-r--r--include/llvm/ExecutionEngine/RuntimeDyldChecker.h6
-rw-r--r--include/llvm/IR/BasicBlock.h6
-rw-r--r--include/llvm/IR/CFG.h10
-rw-r--r--include/llvm/IR/CallSite.h2
-rw-r--r--include/llvm/IR/ConstantRange.h33
-rw-r--r--include/llvm/IR/DataLayout.h47
-rw-r--r--include/llvm/IR/DebugInfo.h714
-rw-r--r--include/llvm/IR/DebugInfoMetadata.h273
-rw-r--r--include/llvm/IR/DebugLoc.h1
-rw-r--r--include/llvm/IR/DiagnosticInfo.h1
-rw-r--r--include/llvm/IR/GVMaterializer.h2
-rw-r--r--include/llvm/IR/GlobalValue.h2
-rw-r--r--include/llvm/IR/IRBuilder.h44
-rw-r--r--include/llvm/IR/InlineAsm.h53
-rw-r--r--include/llvm/IR/InstIterator.h17
-rw-r--r--include/llvm/IR/InstrTypes.h13
-rw-r--r--include/llvm/IR/Instruction.h7
-rw-r--r--include/llvm/IR/Instructions.h95
-rw-r--r--include/llvm/IR/IntrinsicInst.h34
-rw-r--r--include/llvm/IR/Intrinsics.td19
-rw-r--r--include/llvm/IR/IntrinsicsHexagon.td144
-rw-r--r--include/llvm/IR/IntrinsicsPowerPC.td144
-rw-r--r--include/llvm/IR/IntrinsicsX86.td59
-rw-r--r--include/llvm/IR/Metadata.def3
-rw-r--r--include/llvm/IR/Metadata.h42
-rw-r--r--include/llvm/IR/Module.h24
-rw-r--r--include/llvm/IR/NoFolder.h4
-rw-r--r--include/llvm/IR/Operator.h5
-rw-r--r--include/llvm/IR/PassManager.h7
-rw-r--r--include/llvm/IR/PassManagerInternal.h1
-rw-r--r--include/llvm/IR/Value.h2
-rw-r--r--include/llvm/IR/Verifier.h13
-rw-r--r--include/llvm/InitializePasses.h4
-rw-r--r--include/llvm/LTO/LTOCodeGenerator.h7
-rw-r--r--include/llvm/LinkAllPasses.h3
-rw-r--r--include/llvm/Linker/Linker.h1
-rw-r--r--include/llvm/MC/MCAsmInfo.h9
-rw-r--r--include/llvm/MC/MCAsmLayout.h2
-rw-r--r--include/llvm/MC/MCAssembler.h48
-rw-r--r--include/llvm/MC/MCContext.h93
-rw-r--r--include/llvm/MC/MCELFObjectWriter.h2
-rw-r--r--include/llvm/MC/MCExpr.h26
-rw-r--r--include/llvm/MC/MCMachObjectWriter.h7
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h4
-rw-r--r--include/llvm/MC/MCObjectStreamer.h10
-rw-r--r--include/llvm/MC/MCObjectWriter.h18
-rw-r--r--include/llvm/MC/MCParser/MCAsmLexer.h8
-rw-r--r--include/llvm/MC/MCSection.h101
-rw-r--r--include/llvm/MC/MCSectionCOFF.h11
-rw-r--r--include/llvm/MC/MCSectionELF.h23
-rw-r--r--include/llvm/MC/MCSectionMachO.h12
-rw-r--r--include/llvm/MC/MCStreamer.h41
-rw-r--r--include/llvm/Object/Archive.h8
-rw-r--r--include/llvm/Object/ELF.h24
-rw-r--r--include/llvm/Object/ELFTypes.h8
-rw-r--r--include/llvm/Object/MachOUniversal.h10
-rw-r--r--include/llvm/Object/SymbolicFile.h4
-rw-r--r--include/llvm/Option/Arg.h4
-rw-r--r--include/llvm/Option/ArgList.h31
-rw-r--r--include/llvm/Option/OptSpecifier.h2
-rw-r--r--include/llvm/Option/OptTable.h5
-rw-r--r--include/llvm/Option/Option.h1
-rw-r--r--include/llvm/Passes/PassBuilder.h105
-rw-r--r--include/llvm/ProfileData/CoverageMapping.h5
-rw-r--r--include/llvm/ProfileData/CoverageMappingReader.h4
-rw-r--r--include/llvm/Support/ARMBuildAttributes.h7
-rw-r--r--include/llvm/Support/CommandLine.h62
-rw-r--r--include/llvm/Support/Compression.h4
-rw-r--r--include/llvm/Support/CrashRecoveryContext.h2
-rw-r--r--include/llvm/Support/DataExtractor.h1
-rw-r--r--include/llvm/Support/Debug.h3
-rw-r--r--include/llvm/Support/Dwarf.def1
-rw-r--r--include/llvm/Support/ELF.h1
-rw-r--r--include/llvm/Support/Endian.h23
-rw-r--r--include/llvm/Support/FileUtilities.h4
-rw-r--r--include/llvm/Support/Format.h3
-rw-r--r--include/llvm/Support/GraphWriter.h3
-rw-r--r--include/llvm/Support/MathExtras.h15
-rw-r--r--include/llvm/Support/MemoryBuffer.h2
-rw-r--r--include/llvm/Support/Program.h3
-rw-r--r--include/llvm/Support/Regex.h1
-rw-r--r--include/llvm/Support/Signals.h10
-rw-r--r--include/llvm/Support/StreamingMemoryObject.h1
-rw-r--r--include/llvm/Support/StringPool.h2
-rw-r--r--include/llvm/Support/SystemUtils.h2
-rw-r--r--include/llvm/Support/TargetRegistry.h201
-rw-r--r--include/llvm/Support/Timer.h1
-rw-r--r--include/llvm/Support/UnicodeCharRanges.h4
-rw-r--r--include/llvm/Support/YAMLParser.h5
-rw-r--r--include/llvm/Support/raw_ostream.h6
-rw-r--r--include/llvm/TableGen/Record.h6
-rw-r--r--include/llvm/Target/Target.td3
-rw-r--r--include/llvm/Target/TargetInstrInfo.h34
-rw-r--r--include/llvm/Target/TargetLowering.h101
-rw-r--r--include/llvm/Target/TargetLoweringObjectFile.h23
-rw-r--r--include/llvm/Target/TargetMachine.h40
-rw-r--r--include/llvm/Target/TargetRegisterInfo.h35
-rw-r--r--include/llvm/Target/TargetSelectionDAG.td24
-rw-r--r--include/llvm/Target/TargetSubtargetInfo.h16
-rw-r--r--include/llvm/Transforms/IPO/LowerBitSets.h71
-rw-r--r--include/llvm/Transforms/IPO/PassManagerBuilder.h2
-rw-r--r--include/llvm/Transforms/Instrumentation.h4
-rw-r--r--include/llvm/Transforms/Scalar.h8
-rw-r--r--include/llvm/Transforms/Utils/BuildLibCalls.h32
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h10
-rw-r--r--include/llvm/Transforms/Utils/Local.h32
-rw-r--r--include/llvm/Transforms/Utils/LoopUtils.h17
-rw-r--r--include/llvm/Transforms/Utils/SimplifyLibCalls.h9
-rw-r--r--include/llvm/module.modulemap5
246 files changed, 4982 insertions, 3598 deletions
diff --git a/include/llvm-c/Linker.h b/include/llvm-c/Linker.h
index cedde5e..9f98a33 100644
--- a/include/llvm-c/Linker.h
+++ b/include/llvm-c/Linker.h
@@ -20,13 +20,23 @@
extern "C" {
#endif
+/* This enum is provided for backwards-compatibility only. It has no effect. */
+typedef enum {
+ LLVMLinkerDestroySource = 0, /* This is the default behavior. */
+ LLVMLinkerPreserveSource_Removed = 1 /* This option has been deprecated and
+ should not be used. */
+} LLVMLinkerMode;
+
/* Links the source module into the destination module, taking ownership
* of the source module away from the caller. Optionally returns a
* human-readable description of any errors that occurred in linking.
* OutMessage must be disposed with LLVMDisposeMessage. The return value
- * is true if an error occurred, false otherwise. */
+ * is true if an error occurred, false otherwise.
+ *
+ * Note that the linker mode parameter \p Unused is no longer used, and has
+ * no effect. */
LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
- unsigned Unused, char **OutMessage);
+ LLVMLinkerMode Unused, char **OutMessage);
#ifdef __cplusplus
}
diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h
index bf814e0..53b53c5 100644
--- a/include/llvm/ADT/APFloat.h
+++ b/include/llvm/ADT/APFloat.h
@@ -282,12 +282,6 @@ public:
/// into FoldingSets.
void Profile(FoldingSetNodeID &NID) const;
- /// \brief Used by the Bitcode serializer to emit APInts to Bitcode.
- void Emit(Serializer &S) const;
-
- /// \brief Used by the Bitcode deserializer to deserialize APInts.
- static APFloat ReadVal(Deserializer &D);
-
/// \name Arithmetic
/// @{
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
index c2fe094..36d8159 100644
--- a/include/llvm/ADT/APInt.h
+++ b/include/llvm/ADT/APInt.h
@@ -25,9 +25,7 @@
#include <string>
namespace llvm {
-class Deserializer;
class FoldingSetNodeID;
-class Serializer;
class StringRef;
class hash_code;
class raw_ostream;
@@ -409,6 +407,13 @@ public:
: getZExtValue();
}
+ /// \brief Check if the APInt consists of a repeated bit pattern.
+ ///
+ /// e.g. 0x01010101 satisfies isSplat(8).
+ /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
+ /// width without remainder.
+ bool isSplat(unsigned SplatSizeInBits) const;
+
/// @}
/// \name Value Generators
/// @{
diff --git a/include/llvm/ADT/ArrayRef.h b/include/llvm/ADT/ArrayRef.h
index 5b7ed9c..f7b055e 100644
--- a/include/llvm/ADT/ArrayRef.h
+++ b/include/llvm/ADT/ArrayRef.h
@@ -11,7 +11,6 @@
#define LLVM_ADT_ARRAYREF_H
#include "llvm/ADT/None.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <vector>
@@ -44,19 +43,6 @@ namespace llvm {
/// The number of elements.
size_type Length;
- /// \brief A dummy "optional" type that is only created by implicit
- /// conversion from a reference to T.
- ///
- /// This type must *only* be used in a function argument or as a copy of
- /// a function argument, as otherwise it will hold a pointer to a temporary
- /// past that temporaries' lifetime.
- struct TRefOrNothing {
- const T *TPtr;
-
- TRefOrNothing() : TPtr(nullptr) {}
- TRefOrNothing(const T &TRef) : TPtr(&TRef) {}
- };
-
public:
/// @name Constructors
/// @{
@@ -151,13 +137,9 @@ namespace llvm {
bool equals(ArrayRef RHS) const {
if (Length != RHS.Length)
return false;
- // Don't use std::equal(), since it asserts in MSVC on nullptr iterators.
- for (auto L = begin(), LE = end(), R = RHS.begin(); L != LE; ++L, ++R)
- // Match std::equal() in using == (instead of !=) to minimize API
- // requirements of ArrayRef'ed types.
- if (!(*L == *R))
- return false;
- return true;
+ if (Length == 0)
+ return true;
+ return std::equal(begin(), end(), RHS.begin());
}
/// slice(n) - Chop off the first N elements of the array.
@@ -202,47 +184,6 @@ namespace llvm {
}
/// @}
- /// @{
- /// @name Convenience methods
-
- /// @brief Predicate for testing that the array equals the exact sequence of
- /// arguments.
- ///
- /// Will return false if the size is not equal to the exact number of
- /// arguments given or if the array elements don't equal the argument
- /// elements in order. Currently supports up to 16 arguments, but can
- /// easily be extended.
- bool equals(TRefOrNothing Arg0 = TRefOrNothing(),
- TRefOrNothing Arg1 = TRefOrNothing(),
- TRefOrNothing Arg2 = TRefOrNothing(),
- TRefOrNothing Arg3 = TRefOrNothing(),
- TRefOrNothing Arg4 = TRefOrNothing(),
- TRefOrNothing Arg5 = TRefOrNothing(),
- TRefOrNothing Arg6 = TRefOrNothing(),
- TRefOrNothing Arg7 = TRefOrNothing(),
- TRefOrNothing Arg8 = TRefOrNothing(),
- TRefOrNothing Arg9 = TRefOrNothing(),
- TRefOrNothing Arg10 = TRefOrNothing(),
- TRefOrNothing Arg11 = TRefOrNothing(),
- TRefOrNothing Arg12 = TRefOrNothing(),
- TRefOrNothing Arg13 = TRefOrNothing(),
- TRefOrNothing Arg14 = TRefOrNothing(),
- TRefOrNothing Arg15 = TRefOrNothing()) {
- TRefOrNothing Args[] = {Arg0, Arg1, Arg2, Arg3, Arg4, Arg5,
- Arg6, Arg7, Arg8, Arg9, Arg10, Arg11,
- Arg12, Arg13, Arg14, Arg15};
- if (size() > array_lengthof(Args))
- return false;
-
- for (unsigned i = 0, e = size(); i != e; ++i)
- if (Args[i].TPtr == nullptr || (*this)[i] != *Args[i].TPtr)
- return false;
-
- // Either the size is exactly as many args, or the next arg must be null.
- return size() == array_lengthof(Args) || Args[size()].TPtr == nullptr;
- }
-
- /// @}
};
/// MutableArrayRef - Represent a mutable reference to an array (0 or more
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
index 0dbe810..f58dd73 100644
--- a/include/llvm/ADT/BitVector.h
+++ b/include/llvm/ADT/BitVector.h
@@ -53,7 +53,7 @@ public:
BitPos = Idx % BITWORD_SIZE;
}
- ~reference() {}
+ reference(const reference&) = default;
reference &operator=(reference t) {
*this = bool(t);
diff --git a/include/llvm/ADT/DeltaAlgorithm.h b/include/llvm/ADT/DeltaAlgorithm.h
index 4d07e04..21bc1e8 100644
--- a/include/llvm/ADT/DeltaAlgorithm.h
+++ b/include/llvm/ADT/DeltaAlgorithm.h
@@ -77,6 +77,8 @@ protected:
/// ExecuteOneTest - Execute a single test predicate on the change set \p S.
virtual bool ExecuteOneTest(const changeset_ty &S) = 0;
+ DeltaAlgorithm& operator=(const DeltaAlgorithm&) = default;
+
public:
virtual ~DeltaAlgorithm();
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
index 1699ea3..8c65f70 100644
--- a/include/llvm/ADT/DenseMap.h
+++ b/include/llvm/ADT/DenseMap.h
@@ -15,6 +15,7 @@
#define LLVM_ADT_DENSEMAP_H
#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/EpochTracker.h"
#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MathExtras.h"
@@ -50,7 +51,7 @@ class DenseMapIterator;
template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
typename BucketT>
-class DenseMapBase {
+class DenseMapBase : public DebugEpochBase {
public:
typedef unsigned size_type;
typedef KeyT key_type;
@@ -62,16 +63,17 @@ public:
const_iterator;
inline iterator begin() {
// When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
- return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
+ return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
}
inline iterator end() {
- return iterator(getBucketsEnd(), getBucketsEnd(), true);
+ return iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
}
inline const_iterator begin() const {
- return empty() ? end() : const_iterator(getBuckets(), getBucketsEnd());
+ return empty() ? end()
+ : const_iterator(getBuckets(), getBucketsEnd(), *this);
}
inline const_iterator end() const {
- return const_iterator(getBucketsEnd(), getBucketsEnd(), true);
+ return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
}
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
@@ -81,11 +83,13 @@ public:
/// Grow the densemap so that it has at least Size buckets. Does not shrink
void resize(size_type Size) {
+ incrementEpoch();
if (Size > getNumBuckets())
grow(Size);
}
void clear() {
+ incrementEpoch();
if (getNumEntries() == 0 && getNumTombstones() == 0) return;
// If the capacity of the array is huge, and the # elements used is small,
@@ -118,13 +122,13 @@ public:
iterator find(const KeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return iterator(TheBucket, getBucketsEnd(), true);
+ return iterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
const_iterator find(const KeyT &Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return const_iterator(TheBucket, getBucketsEnd(), true);
+ return const_iterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
@@ -137,14 +141,14 @@ public:
iterator find_as(const LookupKeyT &Val) {
BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return iterator(TheBucket, getBucketsEnd(), true);
+ return iterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
template<class LookupKeyT>
const_iterator find_as(const LookupKeyT &Val) const {
const BucketT *TheBucket;
if (LookupBucketFor(Val, TheBucket))
- return const_iterator(TheBucket, getBucketsEnd(), true);
+ return const_iterator(TheBucket, getBucketsEnd(), *this, true);
return end();
}
@@ -163,12 +167,13 @@ public:
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
BucketT *TheBucket;
if (LookupBucketFor(KV.first, TheBucket))
- return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
false); // Already in map.
// Otherwise, insert the new element.
TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
- return std::make_pair(iterator(TheBucket, getBucketsEnd(), true), true);
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
+ true);
}
// Inserts key,value pair into the map if the key isn't already in the map.
@@ -177,14 +182,15 @@ public:
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),
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, 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);
+ return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
+ true);
}
/// insert - Range insertion of pairs.
@@ -431,6 +437,8 @@ private:
}
BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
+ incrementEpoch();
+
// If the load of the hash table is more than 3/4, or if fewer than 1/8 of
// the buckets are empty (meaning that many are filled with tombstones),
// grow the table.
@@ -987,9 +995,10 @@ private:
template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
bool IsConst>
-class DenseMapIterator {
+class DenseMapIterator : DebugEpochBase::HandleBase {
typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
+ friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
public:
typedef ptrdiff_t difference_type;
@@ -1003,38 +1012,54 @@ private:
public:
DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
- DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
- : Ptr(Pos), End(E) {
+ DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch,
+ bool NoAdvance = false)
+ : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
+ assert(isHandleInSync() && "invalid construction!");
if (!NoAdvance) AdvancePastEmptyBuckets();
}
- // If IsConst is true this is a converting constructor from iterator to
- // const_iterator and the default copy constructor is used.
- // Otherwise this is a copy constructor for iterator.
+ // Converting ctor from non-const iterators to const iterators. SFINAE'd out
+ // for const iterator destinations so it doesn't end up as a user defined copy
+ // constructor.
+ template <bool IsConstSrc,
+ typename = typename std::enable_if<!IsConstSrc && IsConst>::type>
DenseMapIterator(
- const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false> &I)
- : Ptr(I.Ptr), End(I.End) {}
+ const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
+ : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
reference operator*() const {
+ assert(isHandleInSync() && "invalid iterator access!");
return *Ptr;
}
pointer operator->() const {
+ assert(isHandleInSync() && "invalid iterator access!");
return Ptr;
}
bool operator==(const ConstIterator &RHS) const {
- return Ptr == RHS.operator->();
+ assert((!Ptr || isHandleInSync()) && "handle not in sync!");
+ assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
+ assert(getEpochAddress() == RHS.getEpochAddress() &&
+ "comparing incomparable iterators!");
+ return Ptr == RHS.Ptr;
}
bool operator!=(const ConstIterator &RHS) const {
- return Ptr != RHS.operator->();
+ assert((!Ptr || isHandleInSync()) && "handle not in sync!");
+ assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
+ assert(getEpochAddress() == RHS.getEpochAddress() &&
+ "comparing incomparable iterators!");
+ return Ptr != RHS.Ptr;
}
inline DenseMapIterator& operator++() { // Preincrement
+ assert(isHandleInSync() && "invalid iterator access!");
++Ptr;
AdvancePastEmptyBuckets();
return *this;
}
DenseMapIterator operator++(int) { // Postincrement
+ assert(isHandleInSync() && "invalid iterator access!");
DenseMapIterator tmp = *this; ++*this; return tmp;
}
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
index 6cd9e68..5186333 100644
--- a/include/llvm/ADT/DepthFirstIterator.h
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -113,9 +113,8 @@ private:
while (It != GT::child_end(Node)) {
NodeType *Next = *It++;
// Has our next sibling been visited?
- if (Next && !this->Visited.count(Next)) {
+ if (Next && this->Visited.insert(Next).second) {
// No, do it now.
- this->Visited.insert(Next);
VisitStack.push_back(std::make_pair(PointerIntTy(Next, 0),
GT::child_begin(Next)));
return;
@@ -129,58 +128,57 @@ private:
public:
typedef typename super::pointer pointer;
- typedef df_iterator<GraphT, SetType, ExtStorage, GT> _Self;
// Provide static begin and end methods as our public "constructors"
- static inline _Self begin(const GraphT& G) {
- return _Self(GT::getEntryNode(G));
+ static df_iterator begin(const GraphT &G) {
+ return df_iterator(GT::getEntryNode(G));
}
- static inline _Self end(const GraphT& G) { return _Self(); }
+ static df_iterator end(const GraphT &G) { return df_iterator(); }
// Static begin and end methods as our public ctors for external iterators
- static inline _Self begin(const GraphT& G, SetType &S) {
- return _Self(GT::getEntryNode(G), S);
+ static df_iterator begin(const GraphT &G, SetType &S) {
+ return df_iterator(GT::getEntryNode(G), S);
}
- static inline _Self end(const GraphT& G, SetType &S) { return _Self(S); }
+ static df_iterator end(const GraphT &G, SetType &S) { return df_iterator(S); }
- inline bool operator==(const _Self& x) const {
+ bool operator==(const df_iterator &x) const {
return VisitStack == x.VisitStack;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ bool operator!=(const df_iterator &x) const { return !(*this == x); }
- inline pointer operator*() const {
- return VisitStack.back().first.getPointer();
- }
+ pointer operator*() const { return VisitStack.back().first.getPointer(); }
// This is a nonstandard operator-> that dereferences the pointer an extra
// time... so that you can actually call methods ON the Node, because
// the contained type is a pointer. This allows BBIt->getTerminator() f.e.
//
- inline NodeType *operator->() const { return operator*(); }
+ NodeType *operator->() const { return **this; }
- inline _Self& operator++() { // Preincrement
+ df_iterator &operator++() { // Preincrement
toNext();
return *this;
}
// skips all children of the current node and traverses to next node
//
- inline _Self& skipChildren() {
+ df_iterator &skipChildren() {
VisitStack.pop_back();
if (!VisitStack.empty())
toNext();
return *this;
}
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
+ df_iterator operator++(int) { // Postincrement
+ df_iterator tmp = *this;
+ ++*this;
+ return tmp;
}
// nodeVisited - return true if this iterator has already visited the
// specified node. This is public, and will probably be used to iterate over
// nodes that a depth first iteration did not find: ie unreachable nodes.
//
- inline bool nodeVisited(NodeType *Node) const {
+ bool nodeVisited(NodeType *Node) const {
return this->Visited.count(Node) != 0;
}
diff --git a/include/llvm/ADT/EpochTracker.h b/include/llvm/ADT/EpochTracker.h
new file mode 100644
index 0000000..d593073
--- /dev/null
+++ b/include/llvm/ADT/EpochTracker.h
@@ -0,0 +1,99 @@
+//===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- 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 DebugEpochBase and DebugEpochBase::HandleBase classes.
+// These can be used to write iterators that are fail-fast when LLVM is built
+// with asserts enabled.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EPOCH_TRACKER_H
+#define LLVM_ADT_EPOCH_TRACKER_H
+
+#include "llvm/Config/llvm-config.h"
+
+#include <cstdint>
+
+namespace llvm {
+
+#ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
+
+class DebugEpochBase {
+public:
+ void incrementEpoch() {}
+
+ class HandleBase {
+ public:
+ HandleBase() {}
+ explicit HandleBase(const DebugEpochBase *) {}
+ bool isHandleInSync() const { return true; }
+ const void *getEpochAddress() const { return nullptr; }
+ };
+};
+
+#else
+
+/// \brief A base class for data structure classes wishing to make iterators
+/// ("handles") pointing into themselves fail-fast. When building without
+/// asserts, this class is empty and does nothing.
+///
+/// DebugEpochBase does not by itself track handles pointing into itself. The
+/// expectation is that routines touching the handles will poll on
+/// isHandleInSync at appropriate points to assert that the handle they're using
+/// is still valid.
+///
+class DebugEpochBase {
+ uint64_t Epoch;
+
+public:
+ DebugEpochBase() : Epoch(0) {}
+
+ /// \brief Calling incrementEpoch invalidates all handles pointing into the
+ /// calling instance.
+ void incrementEpoch() { ++Epoch; }
+
+ /// \brief The destructor calls incrementEpoch to make use-after-free bugs
+ /// more likely to crash deterministically.
+ ~DebugEpochBase() { incrementEpoch(); }
+
+ /// \brief A base class for iterator classes ("handles") that wish to poll for
+ /// iterator invalidating modifications in the underlying data structure.
+ /// When LLVM is built without asserts, this class is empty and does nothing.
+ ///
+ /// HandleBase does not track the parent data structure by itself. It expects
+ /// the routines modifying the data structure to call incrementEpoch when they
+ /// make an iterator-invalidating modification.
+ ///
+ class HandleBase {
+ const uint64_t *EpochAddress;
+ uint64_t EpochAtCreation;
+
+ public:
+ HandleBase() : EpochAddress(nullptr), EpochAtCreation(UINT64_MAX) {}
+
+ explicit HandleBase(const DebugEpochBase *Parent)
+ : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch) {}
+
+ /// \brief Returns true if the DebugEpochBase this Handle is linked to has
+ /// not called incrementEpoch on itself since the creation of this
+ /// HandleBase instance.
+ bool isHandleInSync() const { return *EpochAddress == EpochAtCreation; }
+
+ /// \brief Returns a pointer to the epoch word stored in the data structure
+ /// this handle points into. Can be used to check if two iterators point
+ /// into the same data structure.
+ const void *getEpochAddress() const { return EpochAddress; }
+ };
+};
+
+#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
+
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
index 7ade167..52d10c1 100644
--- a/include/llvm/ADT/FoldingSet.h
+++ b/include/llvm/ADT/FoldingSet.h
@@ -23,9 +23,6 @@
#include "llvm/Support/DataTypes.h"
namespace llvm {
- class APFloat;
- class APInt;
-
/// This folding set used for two purposes:
/// 1. Given information about a node we want to create, look up the unique
/// instance of the node in the set. If the node already exists, return
@@ -110,6 +107,8 @@ class FoldingSetNodeID;
/// back to the bucket to facilitate node removal.
///
class FoldingSetImpl {
+ virtual void anchor(); // Out of line virtual method.
+
protected:
/// Buckets - Array of bucket chains.
///
@@ -123,10 +122,11 @@ protected:
/// is greater than twice the number of buckets.
unsigned NumNodes;
-public:
+ ~FoldingSetImpl();
+
explicit FoldingSetImpl(unsigned Log2InitSize = 6);
- virtual ~FoldingSetImpl();
+public:
//===--------------------------------------------------------------------===//
/// Node - This class is used to maintain the singly linked bucket list in
/// a folding set.
@@ -393,7 +393,7 @@ DefaultContextualFoldingSetTrait<T, Ctx>::ComputeHash(T &X,
/// implementation of the folding set to the node class T. T must be a
/// subclass of FoldingSetNode and implement a Profile function.
///
-template<class T> class FoldingSet : public FoldingSetImpl {
+template <class T> class FoldingSet final : public FoldingSetImpl {
private:
/// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
/// way to convert nodes into a unique specifier.
@@ -463,7 +463,7 @@ public:
/// function with signature
/// void Profile(llvm::FoldingSetNodeID &, Ctx);
template <class T, class Ctx>
-class ContextualFoldingSet : public FoldingSetImpl {
+class ContextualFoldingSet final : public FoldingSetImpl {
// Unfortunately, this can't derive from FoldingSet<T> because the
// construction vtable for FoldingSet<T> requires
// FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
diff --git a/include/llvm/ADT/ImmutableMap.h b/include/llvm/ADT/ImmutableMap.h
index 75fee90..438dec2 100644
--- a/include/llvm/ADT/ImmutableMap.h
+++ b/include/llvm/ADT/ImmutableMap.h
@@ -203,33 +203,14 @@ public:
// Iterators.
//===--------------------------------------------------===//
- class iterator {
- typename TreeTy::iterator itr;
-
- iterator() {}
- iterator(TreeTy* t) : itr(t) {}
+ class iterator : public ImutAVLValueIterator<ImmutableMap> {
+ iterator() = default;
+ explicit iterator(TreeTy *Tree) : iterator::ImutAVLValueIterator(Tree) {}
friend class ImmutableMap;
public:
- typedef ptrdiff_t difference_type;
- 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; }
+ key_type_ref getKey() const { return (*this)->first; }
+ data_type_ref getData() const { return (*this)->second; }
};
iterator begin() const { return iterator(Root); }
@@ -376,30 +357,17 @@ public:
//===--------------------------------------------------===//
// Iterators.
//===--------------------------------------------------===//
-
- class iterator {
- typename TreeTy::iterator itr;
-
- iterator() {}
- iterator(TreeTy* t) : itr(t) {}
+
+ class iterator : public ImutAVLValueIterator<ImmutableMapRef> {
+ iterator() = default;
+ explicit iterator(TreeTy *Tree) : iterator::ImutAVLValueIterator(Tree) {}
friend class ImmutableMapRef;
-
+
public:
- value_type_ref operator*() const { return itr->getValue(); }
- value_type* 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; }
+ key_type_ref getKey() const { return (*this)->first; }
+ data_type_ref getData() const { return (*this)->second; }
};
-
+
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
diff --git a/include/llvm/ADT/ImmutableSet.h b/include/llvm/ADT/ImmutableSet.h
index 3c6f58c..87026f0 100644
--- a/include/llvm/ADT/ImmutableSet.h
+++ b/include/llvm/ADT/ImmutableSet.h
@@ -142,13 +142,13 @@ public:
iterator RItr = RHS.begin(), REnd = RHS.end();
while (LItr != LEnd && RItr != REnd) {
- if (*LItr == *RItr) {
+ if (&*LItr == &*RItr) {
LItr.skipSubTree();
RItr.skipSubTree();
continue;
}
- if (!LItr->isElementEqual(*RItr))
+ if (!LItr->isElementEqual(&*RItr))
return false;
++LItr;
@@ -293,8 +293,8 @@ private:
height = h;
}
- static inline
- uint32_t computeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+ static uint32_t computeDigest(ImutAVLTree *L, ImutAVLTree *R,
+ value_type_ref V) {
uint32_t digest = 0;
if (L)
@@ -311,7 +311,7 @@ private:
return digest;
}
- inline uint32_t computeDigest() {
+ uint32_t computeDigest() {
// Check the lowest bit to determine if digest has actually been
// pre-computed.
if (hasCachedDigest())
@@ -429,9 +429,7 @@ protected:
value_type_ref getValue(TreeTy* T) const { return T->value; }
// Make sure the index is not the Tombstone or Entry key of the DenseMap.
- static inline unsigned maskCacheIndex(unsigned I) {
- return (I & ~0x02);
- }
+ static unsigned maskCacheIndex(unsigned I) { return (I & ~0x02); }
unsigned incrementHeight(TreeTy* L, TreeTy* R) const {
unsigned hl = getHeight(L);
@@ -444,7 +442,7 @@ protected:
typename TreeTy::iterator& TE) {
typename TreeTy::iterator I = T->begin(), E = T->end();
for ( ; I!=E ; ++I, ++TI) {
- if (TI == TE || !I->isElementEqual(*TI))
+ if (TI == TE || !I->isElementEqual(&*TI))
return false;
}
return true;
@@ -647,24 +645,26 @@ public:
//===----------------------------------------------------------------------===//
template <typename ImutInfo>
-class ImutAVLTreeGenericIterator {
+class ImutAVLTreeGenericIterator
+ : public std::iterator<std::bidirectional_iterator_tag,
+ ImutAVLTree<ImutInfo>> {
SmallVector<uintptr_t,20> stack;
public:
enum VisitFlag { VisitedNone=0x0, VisitedLeft=0x1, VisitedRight=0x3,
Flags=0x3 };
typedef ImutAVLTree<ImutInfo> TreeTy;
- typedef ImutAVLTreeGenericIterator<ImutInfo> _Self;
- inline ImutAVLTreeGenericIterator() {}
- inline ImutAVLTreeGenericIterator(const TreeTy* Root) {
+ ImutAVLTreeGenericIterator() {}
+ ImutAVLTreeGenericIterator(const TreeTy *Root) {
if (Root) stack.push_back(reinterpret_cast<uintptr_t>(Root));
}
- TreeTy* operator*() const {
+ TreeTy &operator*() const {
assert(!stack.empty());
- return reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
+ return *reinterpret_cast<TreeTy *>(stack.back() & ~Flags);
}
+ TreeTy *operator->() const { return &*this; }
uintptr_t getVisitState() const {
assert(!stack.empty());
@@ -695,13 +695,15 @@ public:
}
}
- inline bool operator==(const _Self& x) const {
+ bool operator==(const ImutAVLTreeGenericIterator &x) const {
return stack == x.stack;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ bool operator!=(const ImutAVLTreeGenericIterator &x) const {
+ return !(*this == x);
+ }
- _Self& operator++() {
+ ImutAVLTreeGenericIterator &operator++() {
assert(!stack.empty());
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
assert(Current);
@@ -727,7 +729,7 @@ public:
return *this;
}
- _Self& operator--() {
+ ImutAVLTreeGenericIterator &operator--() {
assert(!stack.empty());
TreeTy* Current = reinterpret_cast<TreeTy*>(stack.back() & ~Flags);
assert(Current);
@@ -754,30 +756,34 @@ public:
};
template <typename ImutInfo>
-class ImutAVLTreeInOrderIterator {
+class ImutAVLTreeInOrderIterator
+ : public std::iterator<std::bidirectional_iterator_tag,
+ ImutAVLTree<ImutInfo>> {
typedef ImutAVLTreeGenericIterator<ImutInfo> InternalIteratorTy;
InternalIteratorTy InternalItr;
public:
typedef ImutAVLTree<ImutInfo> TreeTy;
- typedef ImutAVLTreeInOrderIterator<ImutInfo> _Self;
ImutAVLTreeInOrderIterator(const TreeTy* Root) : InternalItr(Root) {
- if (Root) operator++(); // Advance to first element.
+ if (Root)
+ ++*this; // Advance to first element.
}
ImutAVLTreeInOrderIterator() : InternalItr() {}
- inline bool operator==(const _Self& x) const {
+ bool operator==(const ImutAVLTreeInOrderIterator &x) const {
return InternalItr == x.InternalItr;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ bool operator!=(const ImutAVLTreeInOrderIterator &x) const {
+ return !(*this == x);
+ }
- inline TreeTy* operator*() const { return *InternalItr; }
- inline TreeTy* operator->() const { return *InternalItr; }
+ TreeTy &operator*() const { return *InternalItr; }
+ TreeTy *operator->() const { return &*InternalItr; }
- inline _Self& operator++() {
+ ImutAVLTreeInOrderIterator &operator++() {
do ++InternalItr;
while (!InternalItr.atEnd() &&
InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
@@ -785,7 +791,7 @@ public:
return *this;
}
- inline _Self& operator--() {
+ ImutAVLTreeInOrderIterator &operator--() {
do --InternalItr;
while (!InternalItr.atBeginning() &&
InternalItr.getVisitState() != InternalIteratorTy::VisitedLeft);
@@ -793,7 +799,7 @@ public:
return *this;
}
- inline void skipSubTree() {
+ void skipSubTree() {
InternalItr.skipToParent();
while (!InternalItr.atEnd() &&
@@ -802,6 +808,24 @@ public:
}
};
+/// Generic iterator that wraps a T::TreeTy::iterator and exposes
+/// iterator::getValue() on dereference.
+template <typename T>
+struct ImutAVLValueIterator
+ : iterator_adaptor_base<
+ ImutAVLValueIterator<T>, typename T::TreeTy::iterator,
+ typename std::iterator_traits<
+ typename T::TreeTy::iterator>::iterator_category,
+ const typename T::value_type> {
+ ImutAVLValueIterator() = default;
+ explicit ImutAVLValueIterator(typename T::TreeTy *Tree)
+ : ImutAVLValueIterator::iterator_adaptor_base(Tree) {}
+
+ typename ImutAVLValueIterator::reference operator*() const {
+ return this->I->getValue();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Trait classes for Profile information.
//===----------------------------------------------------------------------===//
@@ -814,7 +838,7 @@ struct ImutProfileInfo {
typedef const T value_type;
typedef const T& value_type_ref;
- static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
FoldingSetTrait<T>::Profile(X,ID);
}
};
@@ -825,7 +849,7 @@ struct ImutProfileInteger {
typedef const T value_type;
typedef const T& value_type_ref;
- static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddInteger(X);
}
};
@@ -852,7 +876,7 @@ struct ImutProfileInfo<bool> {
typedef const bool value_type;
typedef const bool& value_type_ref;
- static inline void Profile(FoldingSetNodeID& ID, value_type_ref X) {
+ static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddBoolean(X);
}
};
@@ -865,7 +889,7 @@ struct ImutProfileInfo<T*> {
typedef const T* value_type;
typedef value_type value_type_ref;
- static inline void Profile(FoldingSetNodeID &ID, value_type_ref X) {
+ static void Profile(FoldingSetNodeID &ID, value_type_ref X) {
ID.AddPointer(X);
}
};
@@ -890,18 +914,18 @@ struct ImutContainerInfo : public ImutProfileInfo<T> {
typedef bool data_type;
typedef bool data_type_ref;
- static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
- static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+ static key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static data_type_ref DataOfValue(value_type_ref) { return true; }
- static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
+ static bool isEqual(key_type_ref LHS, key_type_ref RHS) {
return std::equal_to<key_type>()(LHS,RHS);
}
- static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
+ static bool isLess(key_type_ref LHS, key_type_ref RHS) {
return std::less<key_type>()(LHS,RHS);
}
- static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+ static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
};
/// ImutContainerInfo - Specialization for pointer values to treat pointers
@@ -916,18 +940,14 @@ struct ImutContainerInfo<T*> : public ImutProfileInfo<T*> {
typedef bool data_type;
typedef bool data_type_ref;
- static inline key_type_ref KeyOfValue(value_type_ref D) { return D; }
- static inline data_type_ref DataOfValue(value_type_ref) { return true; }
+ static key_type_ref KeyOfValue(value_type_ref D) { return D; }
+ static data_type_ref DataOfValue(value_type_ref) { return true; }
- static inline bool isEqual(key_type_ref LHS, key_type_ref RHS) {
- return LHS == RHS;
- }
+ static bool isEqual(key_type_ref LHS, key_type_ref RHS) { return LHS == RHS; }
- static inline bool isLess(key_type_ref LHS, key_type_ref RHS) {
- return LHS < RHS;
- }
+ static bool isLess(key_type_ref LHS, key_type_ref RHS) { return LHS < RHS; }
- static inline bool isDataEqual(data_type_ref,data_type_ref) { return true; }
+ static bool isDataEqual(data_type_ref, data_type_ref) { return true; }
};
//===----------------------------------------------------------------------===//
@@ -1059,31 +1079,7 @@ public:
// Iterators.
//===--------------------------------------------------===//
- class iterator {
- typename TreeTy::iterator itr;
-
- iterator() {}
- iterator(TreeTy* t) : itr(t) {}
- friend class ImmutableSet<ValT,ValInfo>;
-
- public:
- typedef ptrdiff_t difference_type;
- 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; }
- };
+ typedef ImutAVLValueIterator<ImmutableSet> iterator;
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
@@ -1094,13 +1090,11 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
- static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) {
+ static void Profile(FoldingSetNodeID &ID, const ImmutableSet &S) {
ID.AddPointer(S.Root);
}
- inline void Profile(FoldingSetNodeID& ID) const {
- return Profile(ID,*this);
- }
+ void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
//===--------------------------------------------------===//
// For testing.
@@ -1150,7 +1144,7 @@ public:
if (Root) { Root->release(); }
}
- static inline ImmutableSetRef getEmptySet(FactoryTy *F) {
+ static ImmutableSetRef getEmptySet(FactoryTy *F) {
return ImmutableSetRef(0, F);
}
@@ -1195,21 +1189,7 @@ public:
// Iterators.
//===--------------------------------------------------===//
- class iterator {
- typename TreeTy::iterator itr;
- iterator(TreeTy* t) : itr(t) {}
- friend class ImmutableSetRef<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 ImutAVLValueIterator<ImmutableSetRef> iterator;
iterator begin() const { return iterator(Root); }
iterator end() const { return iterator(); }
@@ -1220,13 +1200,11 @@ public:
unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
- static inline void Profile(FoldingSetNodeID& ID, const ImmutableSetRef& S) {
+ static void Profile(FoldingSetNodeID &ID, const ImmutableSetRef &S) {
ID.AddPointer(S.Root);
}
- inline void Profile(FoldingSetNodeID& ID) const {
- return Profile(ID,*this);
- }
+ void Profile(FoldingSetNodeID &ID) const { return Profile(ID, *this); }
//===--------------------------------------------------===//
// For testing.
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
index 2ffb505..5ba85c0 100644
--- a/include/llvm/ADT/IndexedMap.h
+++ b/include/llvm/ADT/IndexedMap.h
@@ -21,16 +21,19 @@
#define LLVM_ADT_INDEXEDMAP_H
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include <cassert>
#include <functional>
-#include <vector>
namespace llvm {
template <typename T, typename ToIndexT = llvm::identity<unsigned> >
class IndexedMap {
typedef typename ToIndexT::argument_type IndexT;
- typedef std::vector<T> StorageT;
+ // Prefer SmallVector with zero inline storage over std::vector. IndexedMaps
+ // can grow very large and SmallVector grows more efficiently as long as T
+ // is trivially copyable.
+ typedef SmallVector<T, 0> StorageT;
StorageT storage_;
T nullVal_;
ToIndexT toIndex_;
diff --git a/include/llvm/ADT/IntervalMap.h b/include/llvm/ADT/IntervalMap.h
index 99be38f..f8843b2 100644
--- a/include/llvm/ADT/IntervalMap.h
+++ b/include/llvm/ADT/IntervalMap.h
@@ -101,6 +101,7 @@
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/AlignOf.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/RecyclingAllocator.h"
#include <iterator>
@@ -953,11 +954,6 @@ class IntervalMap {
RootBranch node;
};
- enum {
- RootDataSize = sizeof(RootBranchData) > sizeof(RootLeaf) ?
- sizeof(RootBranchData) : sizeof(RootLeaf)
- };
-
public:
typedef typename Sizer::Allocator Allocator;
typedef KeyT KeyType;
@@ -966,13 +962,7 @@ public:
private:
// The root data is either a RootLeaf or a RootBranchData instance.
- // We can't put them in a union since C++03 doesn't allow non-trivial
- // constructors in unions.
- // Instead, we use a char array with pointer alignment. The alignment is
- // ensured by the allocator member in the class, but still verified in the
- // constructor. We don't support keys or values that are more aligned than a
- // pointer.
- char data[RootDataSize];
+ AlignedCharArrayUnion<RootLeaf, RootBranchData> data;
// Tree height.
// 0: Leaves in root.
@@ -993,7 +983,7 @@ private:
const char *d;
T *t;
} u;
- u.d = data;
+ u.d = data.buffer;
return *u.t;
}
@@ -1051,7 +1041,7 @@ private:
public:
explicit IntervalMap(Allocator &a) : height(0), rootSize(0), allocator(a) {
- assert((uintptr_t(data) & (alignOf<RootLeaf>() - 1)) == 0 &&
+ assert((uintptr_t(data.buffer) & (alignOf<RootLeaf>() - 1)) == 0 &&
"Insufficient alignment");
new(&rootLeaf()) RootLeaf();
}
diff --git a/include/llvm/ADT/IntrusiveRefCntPtr.h b/include/llvm/ADT/IntrusiveRefCntPtr.h
index 9b12d04..65b2da7 100644
--- a/include/llvm/ADT/IntrusiveRefCntPtr.h
+++ b/include/llvm/ADT/IntrusiveRefCntPtr.h
@@ -21,10 +21,9 @@
#ifndef LLVM_ADT_INTRUSIVEREFCNTPTR_H
#define LLVM_ADT_INTRUSIVEREFCNTPTR_H
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
#include <atomic>
-#include <memory>
+#include <cassert>
+#include <cstddef>
namespace llvm {
@@ -268,6 +267,8 @@ public:
// LLVM-style downcasting support for IntrusiveRefCntPtr objects
//===----------------------------------------------------------------------===//
+ template <typename From> struct simplify_type;
+
template<class T> struct simplify_type<IntrusiveRefCntPtr<T> > {
typedef T* SimpleType;
static SimpleType getSimplifiedValue(IntrusiveRefCntPtr<T>& Val) {
diff --git a/include/llvm/ADT/MapVector.h b/include/llvm/ADT/MapVector.h
index 1331b15..f19a50b 100644
--- a/include/llvm/ADT/MapVector.h
+++ b/include/llvm/ADT/MapVector.h
@@ -67,6 +67,11 @@ public:
Vector.clear();
}
+ void swap(MapVector &RHS) {
+ std::swap(Map, RHS.Map);
+ std::swap(Vector, RHS.Vector);
+ }
+
ValueT &operator[](const KeyT &Key) {
std::pair<KeyT, unsigned> Pair = std::make_pair(Key, 0);
std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
index dfadc3b..fa337e9 100644
--- a/include/llvm/ADT/PostOrderIterator.h
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -111,53 +111,52 @@ class po_iterator : public std::iterator<std::forward_iterator_tag,
}
}
- inline po_iterator(NodeType *BB) {
+ po_iterator(NodeType *BB) {
this->insertEdge((NodeType*)nullptr, BB);
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
- inline po_iterator() {} // End is when stack is empty.
+ po_iterator() {} // End is when stack is empty.
- inline po_iterator(NodeType *BB, SetType &S) :
- po_iterator_storage<SetType, ExtStorage>(S) {
+ po_iterator(NodeType *BB, SetType &S)
+ : po_iterator_storage<SetType, ExtStorage>(S) {
if (this->insertEdge((NodeType*)nullptr, BB)) {
VisitStack.push_back(std::make_pair(BB, GT::child_begin(BB)));
traverseChild();
}
}
- inline po_iterator(SetType &S) :
- po_iterator_storage<SetType, ExtStorage>(S) {
+ po_iterator(SetType &S)
+ : po_iterator_storage<SetType, ExtStorage>(S) {
} // End is when stack is empty.
public:
typedef typename super::pointer pointer;
- typedef po_iterator<GraphT, SetType, ExtStorage, GT> _Self;
// Provide static "constructors"...
- static inline _Self begin(GraphT G) { return _Self(GT::getEntryNode(G)); }
- static inline _Self end (GraphT G) { return _Self(); }
+ static po_iterator begin(GraphT G) {
+ return po_iterator(GT::getEntryNode(G));
+ }
+ static po_iterator end(GraphT G) { return po_iterator(); }
- static inline _Self begin(GraphT G, SetType &S) {
- return _Self(GT::getEntryNode(G), S);
+ static po_iterator begin(GraphT G, SetType &S) {
+ return po_iterator(GT::getEntryNode(G), S);
}
- static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
+ static po_iterator end(GraphT G, SetType &S) { return po_iterator(S); }
- inline bool operator==(const _Self& x) const {
+ bool operator==(const po_iterator &x) const {
return VisitStack == x.VisitStack;
}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ bool operator!=(const po_iterator &x) const { return !(*this == x); }
- inline pointer operator*() const {
- return VisitStack.back().first;
- }
+ pointer operator*() const { return VisitStack.back().first; }
// This is a nonstandard operator-> that dereferences the pointer an extra
// time... so that you can actually call methods ON the BasicBlock, because
// the contained type is a pointer. This allows BBIt->getTerminator() f.e.
//
- inline NodeType *operator->() const { return operator*(); }
+ NodeType *operator->() const { return **this; }
- inline _Self& operator++() { // Preincrement
+ po_iterator &operator++() { // Preincrement
this->finishPostorder(VisitStack.back().first);
VisitStack.pop_back();
if (!VisitStack.empty())
@@ -165,8 +164,10 @@ public:
return *this;
}
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
+ po_iterator operator++(int) { // Postincrement
+ po_iterator tmp = *this;
+ ++*this;
+ return tmp;
}
};
@@ -260,19 +261,17 @@ template<class GraphT, class GT = GraphTraits<GraphT> >
class ReversePostOrderTraversal {
typedef typename GT::NodeType NodeType;
std::vector<NodeType*> Blocks; // Block list in normal PO order
- inline void Initialize(NodeType *BB) {
+ void Initialize(NodeType *BB) {
std::copy(po_begin(BB), po_end(BB), std::back_inserter(Blocks));
}
public:
typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
- inline ReversePostOrderTraversal(GraphT G) {
- Initialize(GT::getEntryNode(G));
- }
+ ReversePostOrderTraversal(GraphT G) { Initialize(GT::getEntryNode(G)); }
// Because we want a reverse post order, use reverse iterators from the vector
- inline rpo_iterator begin() { return Blocks.rbegin(); }
- inline rpo_iterator end() { return Blocks.rend(); }
+ rpo_iterator begin() { return Blocks.rbegin(); }
+ rpo_iterator end() { return Blocks.rend(); }
};
} // End llvm namespace
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
index 57af18e..921bd82 100644
--- a/include/llvm/ADT/STLExtras.h
+++ b/include/llvm/ADT/STLExtras.h
@@ -123,7 +123,6 @@ public:
typedef void reference; // Can't modify value returned by fn
typedef RootIt iterator_type;
- typedef mapped_iterator<RootIt, UnaryFunc> _Self;
inline const RootIt &getCurrent() const { return current; }
inline const UnaryFunc &getFunc() const { return Fn; }
@@ -135,34 +134,56 @@ public:
return Fn(*current); // little change
}
- _Self& operator++() { ++current; return *this; }
- _Self& operator--() { --current; return *this; }
- _Self operator++(int) { _Self __tmp = *this; ++current; return __tmp; }
- _Self operator--(int) { _Self __tmp = *this; --current; return __tmp; }
- _Self operator+ (difference_type n) const {
- return _Self(current + n, Fn);
+ mapped_iterator &operator++() {
+ ++current;
+ return *this;
}
- _Self& operator+= (difference_type n) { current += n; return *this; }
- _Self operator- (difference_type n) const {
- return _Self(current - n, Fn);
+ mapped_iterator &operator--() {
+ --current;
+ return *this;
+ }
+ mapped_iterator operator++(int) {
+ mapped_iterator __tmp = *this;
+ ++current;
+ return __tmp;
+ }
+ mapped_iterator operator--(int) {
+ mapped_iterator __tmp = *this;
+ --current;
+ return __tmp;
+ }
+ mapped_iterator operator+(difference_type n) const {
+ return mapped_iterator(current + n, Fn);
+ }
+ mapped_iterator &operator+=(difference_type n) {
+ current += n;
+ return *this;
+ }
+ mapped_iterator operator-(difference_type n) const {
+ return mapped_iterator(current - n, Fn);
+ }
+ mapped_iterator &operator-=(difference_type n) {
+ current -= n;
+ return *this;
}
- _Self& operator-= (difference_type n) { current -= n; return *this; }
reference operator[](difference_type n) const { return *(*this + n); }
- inline bool operator!=(const _Self &X) const { return !operator==(X); }
- inline bool operator==(const _Self &X) const { return current == X.current; }
- inline bool operator< (const _Self &X) const { return current < X.current; }
+ bool operator!=(const mapped_iterator &X) const { return !operator==(X); }
+ bool operator==(const mapped_iterator &X) const {
+ return current == X.current;
+ }
+ bool operator<(const mapped_iterator &X) const { return current < X.current; }
- inline difference_type operator-(const _Self &X) const {
+ difference_type operator-(const mapped_iterator &X) const {
return current - X.current;
}
};
-template <class _Iterator, class Func>
-inline mapped_iterator<_Iterator, Func>
-operator+(typename mapped_iterator<_Iterator, Func>::difference_type N,
- const mapped_iterator<_Iterator, Func>& X) {
- return mapped_iterator<_Iterator, Func>(X.getCurrent() - N, X.getFunc());
+template <class Iterator, class Func>
+inline mapped_iterator<Iterator, Func>
+operator+(typename mapped_iterator<Iterator, Func>::difference_type N,
+ const mapped_iterator<Iterator, Func> &X) {
+ return mapped_iterator<Iterator, Func>(X.getCurrent() - N, X.getFunc());
}
@@ -263,10 +284,11 @@ inline int (*get_array_pod_sort_comparator(const T &))
/// default to std::less.
template<class IteratorTy>
inline void array_pod_sort(IteratorTy Start, IteratorTy End) {
- // Don't dereference start iterator of empty sequence.
- if (Start == End) return;
- qsort(&*Start, End-Start, sizeof(*Start),
- get_array_pod_sort_comparator(*Start));
+ // Don't inefficiently call qsort with one element or trigger undefined
+ // behavior with an empty sequence.
+ auto NElts = End - Start;
+ if (NElts <= 1) return;
+ qsort(&*Start, NElts, sizeof(*Start), get_array_pod_sort_comparator(*Start));
}
template <class IteratorTy>
@@ -275,9 +297,11 @@ inline void array_pod_sort(
int (*Compare)(
const typename std::iterator_traits<IteratorTy>::value_type *,
const typename std::iterator_traits<IteratorTy>::value_type *)) {
- // Don't dereference start iterator of empty sequence.
- if (Start == End) return;
- qsort(&*Start, End - Start, sizeof(*Start),
+ // Don't inefficiently call qsort with one element or trigger undefined
+ // behavior with an empty sequence.
+ auto NElts = End - Start;
+ if (NElts <= 1) return;
+ qsort(&*Start, NElts, sizeof(*Start),
reinterpret_cast<int (*)(const void *, const void *)>(Compare));
}
diff --git a/include/llvm/ADT/SmallBitVector.h b/include/llvm/ADT/SmallBitVector.h
index 22e8ccd..ae3d645 100644
--- a/include/llvm/ADT/SmallBitVector.h
+++ b/include/llvm/ADT/SmallBitVector.h
@@ -66,6 +66,8 @@ public:
public:
reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
+ reference(const reference&) = default;
+
reference& operator=(reference t) {
*this = bool(t);
return *this;
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
index 14e2c7b..5b208b7 100644
--- a/include/llvm/ADT/SmallVector.h
+++ b/include/llvm/ADT/SmallVector.h
@@ -24,6 +24,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
+#include <initializer_list>
#include <iterator>
#include <memory>
@@ -432,6 +433,10 @@ public:
this->setEnd(this->end() + NumInputs);
}
+ void append(std::initializer_list<T> IL) {
+ append(IL.begin(), IL.end());
+ }
+
void assign(size_type NumElts, const T &Elt) {
clear();
if (this->capacity() < NumElts)
@@ -440,6 +445,11 @@ public:
std::uninitialized_fill(this->begin(), this->end(), Elt);
}
+ void assign(std::initializer_list<T> IL) {
+ clear();
+ append(IL);
+ }
+
iterator erase(iterator I) {
assert(I >= this->begin() && "Iterator to erase is out of bounds.");
assert(I < this->end() && "Erasing at past-the-end iterator.");
@@ -633,6 +643,10 @@ public:
return I;
}
+ void insert(iterator I, std::initializer_list<T> IL) {
+ insert(I, IL.begin(), IL.end());
+ }
+
template <typename... ArgTypes> void emplace_back(ArgTypes &&... Args) {
if (LLVM_UNLIKELY(this->EndX >= this->CapacityX))
this->grow();
@@ -865,6 +879,10 @@ public:
this->append(R.begin(), R.end());
}
+ SmallVector(std::initializer_list<T> IL) : SmallVectorImpl<T>(N) {
+ this->assign(IL);
+ }
+
SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(N) {
if (!RHS.empty())
SmallVectorImpl<T>::operator=(RHS);
@@ -895,6 +913,10 @@ public:
return *this;
}
+ const SmallVector &operator=(std::initializer_list<T> IL) {
+ this->assign(IL);
+ return *this;
+ }
};
template<typename T, unsigned N>
diff --git a/include/llvm/ADT/StringRef.h b/include/llvm/ADT/StringRef.h
index 6111c42..95660a4 100644
--- a/include/llvm/ADT/StringRef.h
+++ b/include/llvm/ADT/StringRef.h
@@ -238,9 +238,12 @@ namespace llvm {
/// \returns The index of the first occurrence of \p C, or npos if not
/// found.
size_t find(char C, size_t From = 0) const {
- for (size_t i = std::min(From, Length), e = Length; i != e; ++i)
- if (Data[i] == C)
- return i;
+ size_t FindBegin = std::min(From, Length);
+ if (FindBegin < Length) { // Avoid calling memchr with nullptr.
+ // Just forward to memchr, which is faster than a hand-rolled loop.
+ if (const void *P = ::memchr(Data + FindBegin, C, Length - FindBegin))
+ return static_cast<const char *>(P) - Data;
+ }
return npos;
}
diff --git a/include/llvm/ADT/Triple.h b/include/llvm/ADT/Triple.h
index 886f6fb..5fda775 100644
--- a/include/llvm/ADT/Triple.h
+++ b/include/llvm/ADT/Triple.h
@@ -86,6 +86,7 @@ public:
enum SubArchType {
NoSubArch,
+ ARMSubArch_v8_1a,
ARMSubArch_v8,
ARMSubArch_v7,
ARMSubArch_v7em,
@@ -93,6 +94,7 @@ public:
ARMSubArch_v7s,
ARMSubArch_v6,
ARMSubArch_v6m,
+ ARMSubArch_v6k,
ARMSubArch_v6t2,
ARMSubArch_v5,
ARMSubArch_v5te,
@@ -120,6 +122,7 @@ public:
enum OSType {
UnknownOS,
+ CloudABI,
Darwin,
DragonFly,
FreeBSD,
diff --git a/include/llvm/ADT/Twine.h b/include/llvm/ADT/Twine.h
index 9e9a4e1..51bb18d 100644
--- a/include/llvm/ADT/Twine.h
+++ b/include/llvm/ADT/Twine.h
@@ -10,6 +10,7 @@
#ifndef LLVM_ADT_TWINE_H
#define LLVM_ADT_TWINE_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
@@ -17,9 +18,6 @@
#include <string>
namespace llvm {
- template <typename T>
- class SmallVectorImpl;
- class StringRef;
class raw_ostream;
/// Twine - A lightweight data structure for efficiently representing the
@@ -100,6 +98,9 @@ namespace llvm {
/// A pointer to a StringRef instance.
StringRefKind,
+ /// A pointer to a SmallString instance.
+ SmallStringKind,
+
/// A char value reinterpreted as a pointer, to render as a character.
CharKind,
@@ -136,6 +137,7 @@ namespace llvm {
const char *cString;
const std::string *stdString;
const StringRef *stringRef;
+ const SmallVectorImpl<char> *smallString;
char character;
unsigned int decUI;
int decI;
@@ -166,17 +168,16 @@ namespace llvm {
}
/// Construct a binary twine.
- explicit Twine(const Twine &_LHS, const Twine &_RHS)
- : LHSKind(TwineKind), RHSKind(TwineKind) {
- LHS.twine = &_LHS;
- RHS.twine = &_RHS;
+ explicit Twine(const Twine &LHS, const Twine &RHS)
+ : LHSKind(TwineKind), RHSKind(TwineKind) {
+ this->LHS.twine = &LHS;
+ this->RHS.twine = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct a twine from explicit values.
- explicit Twine(Child _LHS, NodeKind _LHSKind,
- Child _RHS, NodeKind _RHSKind)
- : LHS(_LHS), RHS(_RHS), LHSKind(_LHSKind), RHSKind(_RHSKind) {
+ explicit Twine(Child LHS, NodeKind LHSKind, Child RHS, NodeKind RHSKind)
+ : LHS(LHS), RHS(RHS), LHSKind(LHSKind), RHSKind(RHSKind) {
assert(isValid() && "Invalid twine!");
}
@@ -184,32 +185,32 @@ namespace llvm {
/// when concatenating might cause undefined behavior or stack corruptions
Twine &operator=(const Twine &Other) = delete;
- /// isNull - Check for the null twine.
+ /// Check for the null twine.
bool isNull() const {
return getLHSKind() == NullKind;
}
- /// isEmpty - Check for the empty twine.
+ /// Check for the empty twine.
bool isEmpty() const {
return getLHSKind() == EmptyKind;
}
- /// isNullary - Check if this is a nullary twine (null or empty).
+ /// Check if this is a nullary twine (null or empty).
bool isNullary() const {
return isNull() || isEmpty();
}
- /// isUnary - Check if this is a unary twine.
+ /// Check if this is a unary twine.
bool isUnary() const {
return getRHSKind() == EmptyKind && !isNullary();
}
- /// isBinary - Check if this is a binary twine.
+ /// Check if this is a binary twine.
bool isBinary() const {
return getLHSKind() != NullKind && getRHSKind() != EmptyKind;
}
- /// isValid - Check if this is a valid twine (satisfying the invariants on
+ /// Check if this is a valid twine (satisfying the invariants on
/// order and number of arguments).
bool isValid() const {
// Nullary twines always have Empty on the RHS.
@@ -235,16 +236,16 @@ namespace llvm {
return true;
}
- /// getLHSKind - Get the NodeKind of the left-hand side.
+ /// Get the NodeKind of the left-hand side.
NodeKind getLHSKind() const { return LHSKind; }
- /// getRHSKind - Get the NodeKind of the right-hand side.
+ /// Get the NodeKind of the right-hand side.
NodeKind getRHSKind() const { return RHSKind; }
- /// printOneChild - Print one child from a twine.
+ /// Print one child from a twine.
void printOneChild(raw_ostream &OS, Child Ptr, NodeKind Kind) const;
- /// printOneChildRepr - Print the representation of one child from a twine.
+ /// Print the representation of one child from a twine.
void printOneChildRepr(raw_ostream &OS, Child Ptr,
NodeKind Kind) const;
@@ -257,6 +258,8 @@ namespace llvm {
assert(isValid() && "Invalid twine!");
}
+ Twine(const Twine &) = default;
+
/// Construct from a C string.
///
/// We take care here to optimize "" into the empty twine -- this will be
@@ -287,6 +290,13 @@ namespace llvm {
assert(isValid() && "Invalid twine!");
}
+ /// Construct from a SmallString.
+ /*implicit*/ Twine(const SmallVectorImpl<char> &Str)
+ : LHSKind(SmallStringKind), RHSKind(EmptyKind) {
+ LHS.smallString = &Str;
+ assert(isValid() && "Invalid twine!");
+ }
+
/// Construct from a char.
explicit Twine(char Val)
: LHSKind(CharKind), RHSKind(EmptyKind) {
@@ -347,18 +357,18 @@ namespace llvm {
// right thing. Yet.
/// Construct as the concatenation of a C string and a StringRef.
- /*implicit*/ Twine(const char *_LHS, const StringRef &_RHS)
- : LHSKind(CStringKind), RHSKind(StringRefKind) {
- LHS.cString = _LHS;
- RHS.stringRef = &_RHS;
+ /*implicit*/ Twine(const char *LHS, const StringRef &RHS)
+ : LHSKind(CStringKind), RHSKind(StringRefKind) {
+ this->LHS.cString = LHS;
+ this->RHS.stringRef = &RHS;
assert(isValid() && "Invalid twine!");
}
/// Construct as the concatenation of a StringRef and a C string.
- /*implicit*/ Twine(const StringRef &_LHS, const char *_RHS)
- : LHSKind(StringRefKind), RHSKind(CStringKind) {
- LHS.stringRef = &_LHS;
- RHS.cString = _RHS;
+ /*implicit*/ Twine(const StringRef &LHS, const char *RHS)
+ : LHSKind(StringRefKind), RHSKind(CStringKind) {
+ this->LHS.stringRef = &LHS;
+ this->RHS.cString = RHS;
assert(isValid() && "Invalid twine!");
}
@@ -384,14 +394,14 @@ namespace llvm {
/// @name Predicate Operations
/// @{
- /// isTriviallyEmpty - Check if this twine is trivially empty; a false
- /// return value does not necessarily mean the twine is empty.
+ /// Check if this twine is trivially empty; a false return value does not
+ /// necessarily mean the twine is empty.
bool isTriviallyEmpty() const {
return isNullary();
}
- /// isSingleStringRef - Return true if this twine can be dynamically
- /// accessed as a single StringRef value with getSingleStringRef().
+ /// Return true if this twine can be dynamically accessed as a single
+ /// StringRef value with getSingleStringRef().
bool isSingleStringRef() const {
if (getRHSKind() != EmptyKind) return false;
@@ -400,6 +410,7 @@ namespace llvm {
case CStringKind:
case StdStringKind:
case StringRefKind:
+ case SmallStringKind:
return true;
default:
return false;
@@ -416,15 +427,14 @@ namespace llvm {
/// @name Output & Conversion.
/// @{
- /// str - Return the twine contents as a std::string.
+ /// Return the twine contents as a std::string.
std::string str() const;
- /// toVector - Write the concatenated string into the given SmallString or
- /// SmallVector.
+ /// Write the concatenated string into the given SmallString or SmallVector.
void toVector(SmallVectorImpl<char> &Out) const;
- /// getSingleStringRef - This returns the twine as a single StringRef. This
- /// method is only valid if isSingleStringRef() is true.
+ /// This returns the twine as a single StringRef. This method is only valid
+ /// if isSingleStringRef() is true.
StringRef getSingleStringRef() const {
assert(isSingleStringRef() &&"This cannot be had as a single stringref!");
switch (getLHSKind()) {
@@ -433,18 +443,24 @@ namespace llvm {
case CStringKind: return StringRef(LHS.cString);
case StdStringKind: return StringRef(*LHS.stdString);
case StringRefKind: return *LHS.stringRef;
+ case SmallStringKind:
+ return StringRef(LHS.smallString->data(), LHS.smallString->size());
}
}
- /// toStringRef - This returns the twine as a single StringRef if it can be
+ /// This returns the twine as a single StringRef if it can be
/// represented as such. Otherwise the twine is written into the given
/// SmallVector and a StringRef to the SmallVector's data is returned.
- StringRef toStringRef(SmallVectorImpl<char> &Out) const;
+ StringRef toStringRef(SmallVectorImpl<char> &Out) const {
+ if (isSingleStringRef())
+ return getSingleStringRef();
+ toVector(Out);
+ return StringRef(Out.data(), Out.size());
+ }
- /// toNullTerminatedStringRef - This returns the twine as a single null
- /// terminated StringRef if it can be represented as such. Otherwise the
- /// twine is written into the given SmallVector and a StringRef to the
- /// SmallVector's data is returned.
+ /// This returns the twine as a single null terminated StringRef if it
+ /// can be represented as such. Otherwise the twine is written into the
+ /// given SmallVector and a StringRef to the SmallVector's data is returned.
///
/// The returned StringRef's size does not include the null terminator.
StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index 763f372..43bcc34 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -68,7 +68,7 @@ protected:
/// typically called by the run* methods of these subclasses. This may be
/// called multiple times.
///
- void InitializeAliasAnalysis(Pass *P);
+ void InitializeAliasAnalysis(Pass *P, const DataLayout *DL);
/// getAnalysisUsage - All alias analysis implementations should invoke this
/// directly (using AliasAnalysis::getAnalysisUsage(AU)).
@@ -84,11 +84,6 @@ public:
/// know the sizes of the potential memory references.
static uint64_t const UnknownSize = ~UINT64_C(0);
- /// getDataLayout - Return a pointer to the current DataLayout object, or
- /// null if no DataLayout object is available.
- ///
- const DataLayout *getDataLayout() const { return DL; }
-
/// getTargetLibraryInfo - Return a pointer to the current TargetLibraryInfo
/// object, or null if no TargetLibraryInfo object is available.
///
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
index afa7e6f..fc45903 100644
--- a/include/llvm/Analysis/AliasSetTracker.h
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -192,11 +192,6 @@ public:
}
bool operator!=(const iterator& x) const { return !operator==(x); }
- const iterator &operator=(const iterator &I) {
- CurNode = I.CurNode;
- return *this;
- }
-
value_type &operator*() const {
assert(CurNode && "Dereferencing AliasSet.end()!");
return *CurNode;
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
index 09d45ca..541a210 100644
--- a/include/llvm/Analysis/ConstantFolding.h
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -36,16 +36,15 @@ namespace llvm {
/// Note that this fails if not all of the operands are constant. Otherwise,
/// this function can only fail when attempting to fold instructions like loads
/// and stores, which have no constant expression form.
-Constant *ConstantFoldInstruction(Instruction *I,
- const DataLayout *TD = nullptr,
- const TargetLibraryInfo *TLI = nullptr);
+ Constant *ConstantFoldInstruction(Instruction *I, const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr);
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
/// using the specified DataLayout. If successful, the constant result is
/// result is returned, if not, null is returned.
-Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
- const DataLayout *TD = nullptr,
- const TargetLibraryInfo *TLI =nullptr);
+ Constant *
+ ConstantFoldConstantExpression(const ConstantExpr *CE, const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr);
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
/// specified operands. If successful, the constant result is returned, if not,
@@ -53,19 +52,19 @@ Constant *ConstantFoldConstantExpression(const ConstantExpr *CE,
/// fold instructions like loads and stores, which have no constant expression
/// form.
///
-Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
- ArrayRef<Constant *> Ops,
- const DataLayout *TD = nullptr,
- const TargetLibraryInfo *TLI = nullptr);
+ Constant *ConstantFoldInstOperands(unsigned Opcode, Type *DestTy,
+ ArrayRef<Constant *> Ops,
+ const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr);
/// ConstantFoldCompareInstOperands - Attempt to constant fold a compare
/// instruction (icmp/fcmp) with the specified operands. If it fails, it
/// returns a constant expression of the specified operands.
///
-Constant *ConstantFoldCompareInstOperands(unsigned Predicate,
- Constant *LHS, Constant *RHS,
- const DataLayout *TD = nullptr,
- const TargetLibraryInfo *TLI=nullptr);
+ Constant *
+ ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS,
+ Constant *RHS, const DataLayout &DL,
+ const TargetLibraryInfo *TLI = nullptr);
/// ConstantFoldInsertValueInstruction - Attempt to constant fold an insertvalue
/// instruction with the specified operands and indices. The constant result is
@@ -76,8 +75,7 @@ Constant *ConstantFoldInsertValueInstruction(Constant *Agg, Constant *Val,
/// ConstantFoldLoadFromConstPtr - Return the value that a load from C would
/// produce if it is constant and determinable. If this is not determinable,
/// return null.
-Constant *ConstantFoldLoadFromConstPtr(Constant *C,
- const DataLayout *TD = nullptr);
+Constant *ConstantFoldLoadFromConstPtr(Constant *C, const DataLayout &DL);
/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
/// getelementptr constantexpr, return the constant value being addressed by the
diff --git a/include/llvm/Analysis/ConstantsScanner.h b/include/llvm/Analysis/ConstantsScanner.h
deleted file mode 100644
index d3d0a44..0000000
--- a/include/llvm/Analysis/ConstantsScanner.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class implements an iterator to walk through the constants referenced by
-// a method. This is used by the Bitcode & Assembly writers to build constant
-// pools.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_CONSTANTSSCANNER_H
-#define LLVM_ANALYSIS_CONSTANTSSCANNER_H
-
-#include "llvm/IR/InstIterator.h"
-
-namespace llvm {
-
-class Constant;
-
-class constant_iterator : public std::iterator<std::forward_iterator_tag,
- const Constant, ptrdiff_t> {
- const_inst_iterator InstI; // Method instruction iterator
- unsigned OpIdx; // Operand index
-
- typedef constant_iterator _Self;
-
- inline bool isAtConstant() const {
- assert(!InstI.atEnd() && OpIdx < InstI->getNumOperands() &&
- "isAtConstant called with invalid arguments!");
- return isa<Constant>(InstI->getOperand(OpIdx));
- }
-
-public:
- inline constant_iterator(const Function *F) : InstI(inst_begin(F)), OpIdx(0) {
- // Advance to first constant... if we are not already at constant or end
- if (InstI != inst_end(F) && // InstI is valid?
- (InstI->getNumOperands() == 0 || !isAtConstant())) // Not at constant?
- operator++();
- }
-
- inline constant_iterator(const Function *F, bool) // end ctor
- : InstI(inst_end(F)), OpIdx(0) {
- }
-
- inline bool operator==(const _Self& x) const { return OpIdx == x.OpIdx &&
- InstI == x.InstI; }
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
-
- inline pointer operator*() const {
- assert(isAtConstant() && "Dereferenced an iterator at the end!");
- return cast<Constant>(InstI->getOperand(OpIdx));
- }
- inline pointer operator->() const { return operator*(); }
-
- inline _Self& operator++() { // Preincrement implementation
- ++OpIdx;
- do {
- unsigned NumOperands = InstI->getNumOperands();
- while (OpIdx < NumOperands && !isAtConstant()) {
- ++OpIdx;
- }
-
- if (OpIdx < NumOperands) return *this; // Found a constant!
- ++InstI;
- OpIdx = 0;
- } while (!InstI.atEnd());
-
- return *this; // At the end of the method
- }
-
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
- }
-
- inline bool atEnd() const { return InstI.atEnd(); }
-};
-
-inline constant_iterator constant_begin(const Function *F) {
- return constant_iterator(F);
-}
-
-inline constant_iterator constant_end(const Function *F) {
- return constant_iterator(F, true);
-}
-
-} // End llvm namespace
-
-#endif
diff --git a/include/llvm/Analysis/DependenceAnalysis.h b/include/llvm/Analysis/DependenceAnalysis.h
index e01aa54..ce0b899 100644
--- a/include/llvm/Analysis/DependenceAnalysis.h
+++ b/include/llvm/Analysis/DependenceAnalysis.h
@@ -217,13 +217,9 @@ namespace llvm {
/// input dependences are unordered.
class FullDependence : public Dependence {
public:
- FullDependence(Instruction *Src,
- Instruction *Dst,
- bool LoopIndependent,
+ FullDependence(Instruction *Src, Instruction *Dst, bool LoopIndependent,
unsigned Levels);
- ~FullDependence() {
- delete[] DV;
- }
+ ~FullDependence() { delete[] DV; }
/// isLoopIndependent - Returns true if this is a loop-independent
/// dependence.
@@ -266,6 +262,7 @@ namespace llvm {
/// if no subscript in the source or destination mention the induction
/// variable associated with the loop at this level.
bool isScalar(unsigned Level) const override;
+
private:
unsigned short Levels;
bool LoopIndependent;
diff --git a/include/llvm/Analysis/DominanceFrontierImpl.h b/include/llvm/Analysis/DominanceFrontierImpl.h
index 735bfb8..278d298 100644
--- a/include/llvm/Analysis/DominanceFrontierImpl.h
+++ b/include/llvm/Analysis/DominanceFrontierImpl.h
@@ -23,7 +23,6 @@
namespace llvm {
-namespace {
template <class BlockT>
class DFCalculateWorkObject {
public:
@@ -37,7 +36,6 @@ public:
const DomTreeNodeT *Node;
const DomTreeNodeT *parentNode;
};
-}
template <class BlockT>
void DominanceFrontierBase<BlockT>::removeBlock(BlockT *BB) {
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index d1f0370..ae9c1f5 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -122,7 +122,6 @@ class IVUsers : public LoopPass {
LoopInfo *LI;
DominatorTree *DT;
ScalarEvolution *SE;
- const DataLayout *DL;
SmallPtrSet<Instruction*,16> Processed;
/// IVUses - A list of all tracked IV uses of induction variable expressions
diff --git a/include/llvm/Analysis/InstructionSimplify.h b/include/llvm/Analysis/InstructionSimplify.h
index 1ebf981..706bd80 100644
--- a/include/llvm/Analysis/InstructionSimplify.h
+++ b/include/llvm/Analysis/InstructionSimplify.h
@@ -49,7 +49,7 @@ namespace llvm {
/// SimplifyAddInst - Given operands for an Add, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAddInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -58,7 +58,7 @@ namespace llvm {
/// SimplifySubInst - Given operands for a Sub, see if we can
/// fold the result. If not, this returns null.
Value *SimplifySubInst(Value *LHS, Value *RHS, bool isNSW, bool isNUW,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -67,7 +67,7 @@ namespace llvm {
/// Given operands for an FAdd, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFAddInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -76,7 +76,7 @@ namespace llvm {
/// Given operands for an FSub, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFSubInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -85,7 +85,7 @@ namespace llvm {
/// Given operands for an FMul, see if we can fold the result. If not, this
/// returns null.
Value *SimplifyFMulInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -93,7 +93,7 @@ namespace llvm {
/// SimplifyMulInst - Given operands for a Mul, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+ Value *SimplifyMulInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -101,8 +101,7 @@ namespace llvm {
/// SimplifySDivInst - Given operands for an SDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySDivInst(Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ Value *SimplifySDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -110,8 +109,7 @@ namespace llvm {
/// SimplifyUDivInst - Given operands for a UDiv, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyUDivInst(Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ Value *SimplifyUDivInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -120,7 +118,7 @@ namespace llvm {
/// SimplifyFDivInst - Given operands for an FDiv, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFDivInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -128,8 +126,7 @@ namespace llvm {
/// SimplifySRemInst - Given operands for an SRem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifySRemInst(Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ Value *SimplifySRemInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -137,8 +134,7 @@ namespace llvm {
/// SimplifyURemInst - Given operands for a URem, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyURemInst(Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ Value *SimplifyURemInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -147,7 +143,7 @@ namespace llvm {
/// SimplifyFRemInst - Given operands for an FRem, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFRemInst(Value *LHS, Value *RHS, FastMathFlags FMF,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -156,7 +152,7 @@ namespace llvm {
/// SimplifyShlInst - Given operands for a Shl, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyShlInst(Value *Op0, Value *Op1, bool isNSW, bool isNUW,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -165,7 +161,7 @@ namespace llvm {
/// SimplifyLShrInst - Given operands for a LShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyLShrInst(Value *Op0, Value *Op1, bool isExact,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -174,7 +170,7 @@ namespace llvm {
/// SimplifyAShrInst - Given operands for a AShr, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyAShrInst(Value *Op0, Value *Op1, bool isExact,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -182,7 +178,7 @@ namespace llvm {
/// SimplifyAndInst - Given operands for an And, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+ Value *SimplifyAndInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -190,7 +186,7 @@ namespace llvm {
/// SimplifyOrInst - Given operands for an Or, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+ Value *SimplifyOrInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -198,7 +194,7 @@ namespace llvm {
/// SimplifyXorInst - Given operands for a Xor, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout *TD = nullptr,
+ Value *SimplifyXorInst(Value *LHS, Value *RHS, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -207,7 +203,7 @@ namespace llvm {
/// SimplifyICmpInst - Given operands for an ICmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -216,7 +212,7 @@ namespace llvm {
/// SimplifyFCmpInst - Given operands for an FCmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -225,7 +221,7 @@ namespace llvm {
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
/// the result. If not, this returns null.
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -233,7 +229,7 @@ namespace llvm {
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
/// fold the result. If not, this returns null.
- Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout *TD = nullptr,
+ Value *SimplifyGEPInst(ArrayRef<Value *> Ops, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -242,8 +238,7 @@ namespace llvm {
/// SimplifyInsertValueInst - Given operands for an InsertValueInst, see if we
/// can fold the result. If not, this returns null.
Value *SimplifyInsertValueInst(Value *Agg, Value *Val,
- ArrayRef<unsigned> Idxs,
- const DataLayout *TD = nullptr,
+ ArrayRef<unsigned> Idxs, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -251,7 +246,7 @@ namespace llvm {
/// SimplifyTruncInst - Given operands for an TruncInst, see if we can fold
/// the result. If not, this returns null.
- Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout *TD = nullptr,
+ Value *SimplifyTruncInst(Value *Op, Type *Ty, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -263,7 +258,7 @@ namespace llvm {
/// SimplifyCmpInst - Given operands for a CmpInst, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -272,7 +267,7 @@ namespace llvm {
/// SimplifyBinOp - Given operands for a BinaryOperator, see if we can
/// fold the result. If not, this returns null.
Value *SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const DataLayout *TD = nullptr,
+ const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -282,8 +277,7 @@ namespace llvm {
/// In contrast to SimplifyBinOp, try to use FastMathFlag when folding the
/// result. In case we don't need FastMathFlags, simply fall to SimplifyBinOp.
Value *SimplifyFPBinOp(unsigned Opcode, Value *LHS, Value *RHS,
- const FastMathFlags &FMF,
- const DataLayout *TD = nullptr,
+ const FastMathFlags &FMF, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -294,7 +288,7 @@ namespace llvm {
///
/// If this call could not be simplified returns null.
Value *SimplifyCall(Value *V, User::op_iterator ArgBegin,
- User::op_iterator ArgEnd, const DataLayout *TD = nullptr,
+ User::op_iterator ArgEnd, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -304,8 +298,7 @@ namespace llvm {
/// result.
///
/// If this call could not be simplified returns null.
- Value *SimplifyCall(Value *V, ArrayRef<Value *> Args,
- const DataLayout *TD = nullptr,
+ Value *SimplifyCall(Value *V, ArrayRef<Value *> Args, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr,
@@ -313,7 +306,7 @@ namespace llvm {
/// SimplifyInstruction - See if we can compute a simplified version of this
/// instruction. If not, this returns null.
- Value *SimplifyInstruction(Instruction *I, const DataLayout *TD = nullptr,
+ Value *SimplifyInstruction(Instruction *I, const DataLayout &DL,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr);
@@ -327,7 +320,6 @@ namespace llvm {
///
/// The function returns true if any simplifications were performed.
bool replaceAndRecursivelySimplify(Instruction *I, Value *SimpleV,
- const DataLayout *TD = nullptr,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr);
@@ -339,7 +331,6 @@ namespace llvm {
/// of the users impacted. It returns true if any simplifications were
/// performed.
bool recursivelySimplifyInstruction(Instruction *I,
- const DataLayout *TD = nullptr,
const TargetLibraryInfo *TLI = nullptr,
const DominatorTree *DT = nullptr,
AssumptionCache *AC = nullptr);
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
index 3b51d44..655ce2d 100644
--- a/include/llvm/Analysis/IntervalIterator.h
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -78,7 +78,7 @@ inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
//
inline void addNodeToInterval(Interval *Int, Interval *I) {
// Add all of the nodes in I as new nodes in Int.
- copy(I->Nodes.begin(), I->Nodes.end(), back_inserter(Int->Nodes));
+ Int->Nodes.insert(Int->Nodes.end(), I->Nodes.begin(), I->Nodes.end());
}
@@ -94,7 +94,6 @@ class IntervalIterator {
bool IOwnMem; // If True, delete intervals when done with them
// See file header for conditions of use
public:
- typedef IntervalIterator<NodeTy, OrigContainer_t> _Self;
typedef std::forward_iterator_tag iterator_category;
IntervalIterator() {} // End iterator, empty stack
@@ -105,6 +104,12 @@ public:
}
}
+ IntervalIterator(IntervalIterator &&x)
+ : IntStack(std::move(x.IntStack)), Visited(std::move(x.Visited)),
+ OrigContainer(x.OrigContainer), IOwnMem(x.IOwnMem) {
+ x.IOwnMem = false;
+ }
+
IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
OrigContainer = &IP;
if (!ProcessInterval(IP.getRootInterval())) {
@@ -112,7 +117,7 @@ public:
}
}
- inline ~IntervalIterator() {
+ ~IntervalIterator() {
if (IOwnMem)
while (!IntStack.empty()) {
delete operator*();
@@ -120,15 +125,17 @@ public:
}
}
- inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
- inline bool operator!=(const _Self& x) const { return !operator==(x); }
+ bool operator==(const IntervalIterator &x) const {
+ return IntStack == x.IntStack;
+ }
+ bool operator!=(const IntervalIterator &x) const { return !(*this == x); }
- inline const Interval *operator*() const { return IntStack.back().first; }
- inline Interval *operator*() { return IntStack.back().first; }
- inline const Interval *operator->() const { return operator*(); }
- inline Interval *operator->() { return operator*(); }
+ const Interval *operator*() const { return IntStack.back().first; }
+ Interval *operator*() { return IntStack.back().first; }
+ const Interval *operator->() const { return operator*(); }
+ Interval *operator->() { return operator*(); }
- _Self& operator++() { // Preincrement
+ IntervalIterator &operator++() { // Preincrement
assert(!IntStack.empty() && "Attempting to use interval iterator at end!");
do {
// All of the intervals on the stack have been visited. Try visiting
@@ -150,8 +157,10 @@ public:
return *this;
}
- inline _Self operator++(int) { // Postincrement
- _Self tmp = *this; ++*this; return tmp;
+ IntervalIterator operator++(int) { // Postincrement
+ IntervalIterator tmp = *this;
+ ++*this;
+ return tmp;
}
private:
diff --git a/include/llvm/Analysis/LazyValueInfo.h b/include/llvm/Analysis/LazyValueInfo.h
index 51f6b0c..8e5bbfb 100644
--- a/include/llvm/Analysis/LazyValueInfo.h
+++ b/include/llvm/Analysis/LazyValueInfo.h
@@ -29,7 +29,6 @@ namespace llvm {
/// This pass computes, caches, and vends lazy value constraint information.
class LazyValueInfo : public FunctionPass {
AssumptionCache *AC;
- const DataLayout *DL;
class TargetLibraryInfo *TLI;
DominatorTree *DT;
void *PImpl;
diff --git a/include/llvm/Analysis/LibCallAliasAnalysis.h b/include/llvm/Analysis/LibCallAliasAnalysis.h
index 4c03c92..49e0dc8 100644
--- a/include/llvm/Analysis/LibCallAliasAnalysis.h
+++ b/include/llvm/Analysis/LibCallAliasAnalysis.h
@@ -15,6 +15,7 @@
#define LLVM_ANALYSIS_LIBCALLALIASANALYSIS_H
#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
namespace llvm {
@@ -48,11 +49,8 @@ namespace llvm {
void getAnalysisUsage(AnalysisUsage &AU) const override;
- bool runOnFunction(Function &F) override {
- InitializeAliasAnalysis(this); // set up super class
- return false;
- }
-
+ bool runOnFunction(Function &F) override;
+
/// getAdjustedAnalysisPointer - This method is used when a pass implements
/// an analysis interface through multiple inheritance. If needed, it
/// should override this to adjust the this pointer as needed for the
diff --git a/include/llvm/Analysis/LibCallSemantics.h b/include/llvm/Analysis/LibCallSemantics.h
index e6427a4..34831b2 100644
--- a/include/llvm/Analysis/LibCallSemantics.h
+++ b/include/llvm/Analysis/LibCallSemantics.h
@@ -181,7 +181,31 @@ class InvokeInst;
/// \brief Returns true if this personality function catches asynchronous
/// exceptions.
- bool isAsynchronousEHPersonality(EHPersonality Pers);
+ inline bool isAsynchronousEHPersonality(EHPersonality Pers) {
+ // The two SEH personality functions can catch asynch exceptions. We assume
+ // unknown personalities don't catch asynch exceptions.
+ switch (Pers) {
+ case EHPersonality::MSVC_X86SEH:
+ case EHPersonality::MSVC_Win64SEH:
+ return true;
+ default: return false;
+ }
+ llvm_unreachable("invalid enum");
+ }
+
+ /// \brief Returns true if this is an MSVC personality function.
+ inline bool isMSVCEHPersonality(EHPersonality Pers) {
+ // The two SEH personality functions can catch asynch exceptions. We assume
+ // unknown personalities don't catch asynch exceptions.
+ switch (Pers) {
+ case EHPersonality::MSVC_CXX:
+ case EHPersonality::MSVC_X86SEH:
+ case EHPersonality::MSVC_Win64SEH:
+ return true;
+ default: return false;
+ }
+ llvm_unreachable("invalid enum");
+ }
bool canSimplifyInvokeNoUnwind(const InvokeInst *II);
diff --git a/include/llvm/Analysis/Loads.h b/include/llvm/Analysis/Loads.h
index 0fe3453..42667d2 100644
--- a/include/llvm/Analysis/Loads.h
+++ b/include/llvm/Analysis/Loads.h
@@ -27,8 +27,7 @@ class MDNode;
/// specified pointer, we do a quick local scan of the basic block containing
/// ScanFrom, to determine if the address is already accessed.
bool isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom,
- unsigned Align,
- const DataLayout *TD = nullptr);
+ unsigned Align);
/// FindAvailableLoadedValue - Scan the ScanBB block backwards (starting at
/// the instruction before ScanFrom) checking to see if we have the value at
diff --git a/include/llvm/Analysis/LoopAccessAnalysis.h b/include/llvm/Analysis/LoopAccessAnalysis.h
index 323af98..0a9dc07 100644
--- a/include/llvm/Analysis/LoopAccessAnalysis.h
+++ b/include/llvm/Analysis/LoopAccessAnalysis.h
@@ -86,6 +86,210 @@ struct VectorizerParams {
static unsigned RuntimeMemoryCheckThreshold;
};
+/// \brief Checks memory dependences among accesses to the same underlying
+/// object to determine whether there vectorization is legal or not (and at
+/// which vectorization factor).
+///
+/// Note: This class will compute a conservative dependence for access to
+/// different underlying pointers. Clients, such as the loop vectorizer, will
+/// sometimes deal these potential dependencies by emitting runtime checks.
+///
+/// We use the ScalarEvolution framework to symbolically evalutate access
+/// functions pairs. Since we currently don't restructure the loop we can rely
+/// on the program order of memory accesses to determine their safety.
+/// At the moment we will only deem accesses as safe for:
+/// * A negative constant distance assuming program order.
+///
+/// Safe: tmp = a[i + 1]; OR a[i + 1] = x;
+/// a[i] = tmp; y = a[i];
+///
+/// The latter case is safe because later checks guarantuee that there can't
+/// be a cycle through a phi node (that is, we check that "x" and "y" is not
+/// the same variable: a header phi can only be an induction or a reduction, a
+/// reduction can't have a memory sink, an induction can't have a memory
+/// source). This is important and must not be violated (or we have to
+/// resort to checking for cycles through memory).
+///
+/// * A positive constant distance assuming program order that is bigger
+/// than the biggest memory access.
+///
+/// tmp = a[i] OR b[i] = x
+/// a[i+2] = tmp y = b[i+2];
+///
+/// Safe distance: 2 x sizeof(a[0]), and 2 x sizeof(b[0]), respectively.
+///
+/// * Zero distances and all accesses have the same size.
+///
+class MemoryDepChecker {
+public:
+ typedef PointerIntPair<Value *, 1, bool> MemAccessInfo;
+ typedef SmallPtrSet<MemAccessInfo, 8> MemAccessInfoSet;
+ /// \brief Set of potential dependent memory accesses.
+ typedef EquivalenceClasses<MemAccessInfo> DepCandidates;
+
+ /// \brief Dependece between memory access instructions.
+ struct Dependence {
+ /// \brief The type of the dependence.
+ enum DepType {
+ // No dependence.
+ NoDep,
+ // We couldn't determine the direction or the distance.
+ Unknown,
+ // Lexically forward.
+ Forward,
+ // Forward, but if vectorized, is likely to prevent store-to-load
+ // forwarding.
+ ForwardButPreventsForwarding,
+ // Lexically backward.
+ Backward,
+ // Backward, but the distance allows a vectorization factor of
+ // MaxSafeDepDistBytes.
+ BackwardVectorizable,
+ // Same, but may prevent store-to-load forwarding.
+ BackwardVectorizableButPreventsForwarding
+ };
+
+ /// \brief String version of the types.
+ static const char *DepName[];
+
+ /// \brief Index of the source of the dependence in the InstMap vector.
+ unsigned Source;
+ /// \brief Index of the destination of the dependence in the InstMap vector.
+ unsigned Destination;
+ /// \brief The type of the dependence.
+ DepType Type;
+
+ Dependence(unsigned Source, unsigned Destination, DepType Type)
+ : Source(Source), Destination(Destination), Type(Type) {}
+
+ /// \brief Dependence types that don't prevent vectorization.
+ static bool isSafeForVectorization(DepType Type);
+
+ /// \brief Dependence types that can be queried from the analysis.
+ static bool isInterestingDependence(DepType Type);
+
+ /// \brief Lexically backward dependence types.
+ bool isPossiblyBackward() const;
+
+ /// \brief Print the dependence. \p Instr is used to map the instruction
+ /// indices to instructions.
+ void print(raw_ostream &OS, unsigned Depth,
+ const SmallVectorImpl<Instruction *> &Instrs) const;
+ };
+
+ MemoryDepChecker(ScalarEvolution *Se, const Loop *L)
+ : SE(Se), InnermostLoop(L), AccessIdx(0),
+ ShouldRetryWithRuntimeCheck(false), SafeForVectorization(true),
+ RecordInterestingDependences(true) {}
+
+ /// \brief Register the location (instructions are given increasing numbers)
+ /// of a write access.
+ void addAccess(StoreInst *SI) {
+ Value *Ptr = SI->getPointerOperand();
+ Accesses[MemAccessInfo(Ptr, true)].push_back(AccessIdx);
+ InstMap.push_back(SI);
+ ++AccessIdx;
+ }
+
+ /// \brief Register the location (instructions are given increasing numbers)
+ /// of a write access.
+ void addAccess(LoadInst *LI) {
+ Value *Ptr = LI->getPointerOperand();
+ Accesses[MemAccessInfo(Ptr, false)].push_back(AccessIdx);
+ InstMap.push_back(LI);
+ ++AccessIdx;
+ }
+
+ /// \brief Check whether the dependencies between the accesses are safe.
+ ///
+ /// Only checks sets with elements in \p CheckDeps.
+ bool areDepsSafe(DepCandidates &AccessSets, MemAccessInfoSet &CheckDeps,
+ const ValueToValueMap &Strides);
+
+ /// \brief No memory dependence was encountered that would inhibit
+ /// vectorization.
+ bool isSafeForVectorization() const { return SafeForVectorization; }
+
+ /// \brief The maximum number of bytes of a vector register we can vectorize
+ /// the accesses safely with.
+ unsigned getMaxSafeDepDistBytes() { return MaxSafeDepDistBytes; }
+
+ /// \brief In same cases when the dependency check fails we can still
+ /// vectorize the loop with a dynamic array access check.
+ bool shouldRetryWithRuntimeCheck() { return ShouldRetryWithRuntimeCheck; }
+
+ /// \brief Returns the interesting dependences. If null is returned we
+ /// exceeded the MaxInterestingDependence threshold and this information is
+ /// not available.
+ const SmallVectorImpl<Dependence> *getInterestingDependences() const {
+ return RecordInterestingDependences ? &InterestingDependences : nullptr;
+ }
+
+ /// \brief The vector of memory access instructions. The indices are used as
+ /// instruction identifiers in the Dependence class.
+ const SmallVectorImpl<Instruction *> &getMemoryInstructions() const {
+ return InstMap;
+ }
+
+ /// \brief Find the set of instructions that read or write via \p Ptr.
+ SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
+ bool isWrite) const;
+
+private:
+ ScalarEvolution *SE;
+ const Loop *InnermostLoop;
+
+ /// \brief Maps access locations (ptr, read/write) to program order.
+ DenseMap<MemAccessInfo, std::vector<unsigned> > Accesses;
+
+ /// \brief Memory access instructions in program order.
+ SmallVector<Instruction *, 16> InstMap;
+
+ /// \brief The program order index to be used for the next instruction.
+ unsigned AccessIdx;
+
+ // We can access this many bytes in parallel safely.
+ unsigned MaxSafeDepDistBytes;
+
+ /// \brief If we see a non-constant dependence distance we can still try to
+ /// vectorize this loop with runtime checks.
+ bool ShouldRetryWithRuntimeCheck;
+
+ /// \brief No memory dependence was encountered that would inhibit
+ /// vectorization.
+ bool SafeForVectorization;
+
+ //// \brief True if InterestingDependences reflects the dependences in the
+ //// loop. If false we exceeded MaxInterestingDependence and
+ //// InterestingDependences is invalid.
+ bool RecordInterestingDependences;
+
+ /// \brief Interesting memory dependences collected during the analysis as
+ /// defined by isInterestingDependence. Only valid if
+ /// RecordInterestingDependences is true.
+ SmallVector<Dependence, 8> InterestingDependences;
+
+ /// \brief Check whether there is a plausible dependence between the two
+ /// accesses.
+ ///
+ /// Access \p A must happen before \p B in program order. The two indices
+ /// identify the index into the program order map.
+ ///
+ /// This function checks whether there is a plausible dependence (or the
+ /// absence of such can't be proved) between the two accesses. If there is a
+ /// plausible dependence but the dependence distance is bigger than one
+ /// element access it records this distance in \p MaxSafeDepDistBytes (if this
+ /// distance is smaller than any other distance encountered so far).
+ /// Otherwise, this function returns true signaling a possible dependence.
+ Dependence::DepType isDependent(const MemAccessInfo &A, unsigned AIdx,
+ const MemAccessInfo &B, unsigned BIdx,
+ const ValueToValueMap &Strides);
+
+ /// \brief Check whether the data dependence could prevent store-load
+ /// forwarding.
+ bool couldPreventStoreLoadForward(unsigned Distance, unsigned TypeByteSize);
+};
+
/// \brief Drive the analysis of memory accesses in the loop
///
/// This class is responsible for analyzing the memory accesses of a loop. It
@@ -128,10 +332,20 @@ public:
/// \brief Decide whether we need to issue a run-time check for pointer at
/// index \p I and \p J to prove their independence.
- bool needsChecking(unsigned I, unsigned J) const;
+ ///
+ /// If \p PtrPartition is set, it contains the partition number for
+ /// pointers (-1 if the pointer belongs to multiple partitions). In this
+ /// case omit checks between pointers belonging to the same partition.
+ bool needsChecking(unsigned I, unsigned J,
+ const SmallVectorImpl<int> *PtrPartition) const;
/// \brief Print the list run-time memory checks necessary.
- void print(raw_ostream &OS, unsigned Depth = 0) const;
+ ///
+ /// If \p PtrPartition is set, it contains the partition number for
+ /// pointers (-1 if the pointer belongs to multiple partitions). In this
+ /// case omit checks between pointers belonging to the same partition.
+ void print(raw_ostream &OS, unsigned Depth = 0,
+ const SmallVectorImpl<int> *PtrPartition = nullptr) const;
/// This flag indicates if we need to add the runtime check.
bool Need;
@@ -150,7 +364,7 @@ public:
SmallVector<unsigned, 2> AliasSetId;
};
- LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout *DL,
+ LoopAccessInfo(Loop *L, ScalarEvolution *SE, const DataLayout &DL,
const TargetLibraryInfo *TLI, AliasAnalysis *AA,
DominatorTree *DT, const ValueToValueMap &Strides);
@@ -162,6 +376,10 @@ public:
return &PtrRtCheck;
}
+ /// \brief Number of memchecks required to prove independence of otherwise
+ /// may-alias pointers.
+ unsigned getNumRuntimePointerChecks() const { return NumComparisons; }
+
/// Return true if the block BB needs to be predicated in order for the loop
/// to be vectorized.
static bool blockNeedsPredication(BasicBlock *BB, Loop *TheLoop,
@@ -179,13 +397,29 @@ public:
/// Returns a pair of instructions where the first element is the first
/// instruction generated in possibly a sequence of instructions and the
/// second value is the final comparator value or NULL if no check is needed.
+ ///
+ /// If \p PtrPartition is set, it contains the partition number for pointers
+ /// (-1 if the pointer belongs to multiple partitions). In this case omit
+ /// checks between pointers belonging to the same partition.
std::pair<Instruction *, Instruction *>
- addRuntimeCheck(Instruction *Loc) const;
+ addRuntimeCheck(Instruction *Loc,
+ const SmallVectorImpl<int> *PtrPartition = nullptr) const;
/// \brief The diagnostics report generated for the analysis. E.g. why we
/// couldn't analyze the loop.
const Optional<LoopAccessReport> &getReport() const { return Report; }
+ /// \brief the Memory Dependence Checker which can determine the
+ /// loop-independent and loop-carried dependences between memory accesses.
+ const MemoryDepChecker &getDepChecker() const { return DepChecker; }
+
+ /// \brief Return the list of instructions that use \p Ptr to read or write
+ /// memory.
+ SmallVector<Instruction *, 4> getInstructionsForAccess(Value *Ptr,
+ bool isWrite) const {
+ return DepChecker.getInstructionsForAccess(Ptr, isWrite);
+ }
+
/// \brief Print the information about the memory accesses in the loop.
void print(raw_ostream &OS, unsigned Depth = 0) const;
@@ -207,9 +441,18 @@ private:
/// We need to check that all of the pointers in this list are disjoint
/// at runtime.
RuntimePointerCheck PtrRtCheck;
+
+ /// \brief the Memory Dependence Checker which can determine the
+ /// loop-independent and loop-carried dependences between memory accesses.
+ MemoryDepChecker DepChecker;
+
+ /// \brief Number of memchecks required to prove independence of otherwise
+ /// may-alias pointers
+ unsigned NumComparisons;
+
Loop *TheLoop;
ScalarEvolution *SE;
- const DataLayout *DL;
+ const DataLayout &DL;
const TargetLibraryInfo *TLI;
AliasAnalysis *AA;
DominatorTree *DT;
@@ -280,7 +523,6 @@ private:
// The used analysis passes.
ScalarEvolution *SE;
- const DataLayout *DL;
const TargetLibraryInfo *TLI;
AliasAnalysis *AA;
DominatorTree *DT;
diff --git a/include/llvm/Analysis/LoopInfoImpl.h b/include/llvm/Analysis/LoopInfoImpl.h
index 3321f39..7cc4a77 100644
--- a/include/llvm/Analysis/LoopInfoImpl.h
+++ b/include/llvm/Analysis/LoopInfoImpl.h
@@ -402,7 +402,6 @@ static void discoverAndMapSubloop(LoopT *L, ArrayRef<BlockT*> Backedges,
L->reserveBlocks(NumBlocks);
}
-namespace {
/// Populate all loop data in a stable order during a single forward DFS.
template<class BlockT, class LoopT>
class PopulateLoopsDFS {
@@ -430,7 +429,6 @@ protected:
DFSStack.push_back(std::make_pair(Block, BlockTraits::child_begin(Block)));
}
};
-} // anonymous
/// Top-level driver for the forward DFS within the loop.
template<class BlockT, class LoopT>
diff --git a/include/llvm/Analysis/MemoryBuiltins.h b/include/llvm/Analysis/MemoryBuiltins.h
index d414680..805a43d 100644
--- a/include/llvm/Analysis/MemoryBuiltins.h
+++ b/include/llvm/Analysis/MemoryBuiltins.h
@@ -82,12 +82,6 @@ static inline CallInst *extractMallocCall(Value *I,
return const_cast<CallInst*>(extractMallocCall((const Value*)I, TLI));
}
-/// isArrayMalloc - Returns the corresponding CallInst if the instruction
-/// is a call to malloc whose array size can be determined and the array size
-/// is not constant 1. Otherwise, return NULL.
-const CallInst *isArrayMalloc(const Value *I, const DataLayout *DL,
- const TargetLibraryInfo *TLI);
-
/// getMallocType - Returns the PointerType resulting from the malloc call.
/// The PointerType depends on the number of bitcast uses of the malloc call:
/// 0: PointerType is the malloc calls' return type.
@@ -107,11 +101,10 @@ Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
/// then return that multiple. For non-array mallocs, the multiple is
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
/// determined.
-Value *getMallocArraySize(CallInst *CI, const DataLayout *DL,
+Value *getMallocArraySize(CallInst *CI, const DataLayout &DL,
const TargetLibraryInfo *TLI,
bool LookThroughSExt = false);
-
//===----------------------------------------------------------------------===//
// calloc Call Utility Functions.
//
@@ -147,11 +140,9 @@ static inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) {
/// underlying object pointed to by Ptr.
/// If RoundToAlign is true, then Size is rounded up to the aligment of allocas,
/// byval arguments, and global variables.
-bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout *DL,
+bool getObjectSize(const Value *Ptr, uint64_t &Size, const DataLayout &DL,
const TargetLibraryInfo *TLI, bool RoundToAlign = false);
-
-
typedef std::pair<APInt, APInt> SizeOffsetType;
/// \brief Evaluate the size and offset of an object pointed to by a Value*
@@ -159,7 +150,7 @@ typedef std::pair<APInt, APInt> SizeOffsetType;
class ObjectSizeOffsetVisitor
: public InstVisitor<ObjectSizeOffsetVisitor, SizeOffsetType> {
- const DataLayout *DL;
+ const DataLayout &DL;
const TargetLibraryInfo *TLI;
bool RoundToAlign;
unsigned IntTyBits;
@@ -173,7 +164,7 @@ class ObjectSizeOffsetVisitor
}
public:
- ObjectSizeOffsetVisitor(const DataLayout *DL, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetVisitor(const DataLayout &DL, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetType compute(Value *V);
@@ -222,7 +213,7 @@ class ObjectSizeOffsetEvaluator
typedef DenseMap<const Value*, WeakEvalType> CacheMapTy;
typedef SmallPtrSet<const Value*, 8> PtrSetTy;
- const DataLayout *DL;
+ const DataLayout &DL;
const TargetLibraryInfo *TLI;
LLVMContext &Context;
BuilderTy Builder;
@@ -238,7 +229,7 @@ class ObjectSizeOffsetEvaluator
SizeOffsetEvalType compute_(Value *V);
public:
- ObjectSizeOffsetEvaluator(const DataLayout *DL, const TargetLibraryInfo *TLI,
+ ObjectSizeOffsetEvaluator(const DataLayout &DL, const TargetLibraryInfo *TLI,
LLVMContext &Context, bool RoundToAlign = false);
SizeOffsetEvalType compute(Value *V);
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
index 77610b3..abc2b90 100644
--- a/include/llvm/Analysis/MemoryDependenceAnalysis.h
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -29,7 +29,6 @@ namespace llvm {
class CallSite;
class AliasAnalysis;
class AssumptionCache;
- class DataLayout;
class MemoryDependenceAnalysis;
class PredIteratorCache;
class DominatorTree;
@@ -324,7 +323,6 @@ namespace llvm {
/// Current AA implementation, just a cache.
AliasAnalysis *AA;
- const DataLayout *DL;
DominatorTree *DT;
AssumptionCache *AC;
std::unique_ptr<PredIteratorCache> PredCache;
@@ -421,8 +419,7 @@ namespace llvm {
static unsigned getLoadLoadClobberFullWidthSize(const Value *MemLocBase,
int64_t MemLocOffs,
unsigned MemLocSize,
- const LoadInst *LI,
- const DataLayout &DL);
+ const LoadInst *LI);
private:
MemDepResult getCallSiteDependencyFrom(CallSite C, bool isReadOnlyCall,
diff --git a/include/llvm/Analysis/PHITransAddr.h b/include/llvm/Analysis/PHITransAddr.h
index 38730d8..84bb9d8 100644
--- a/include/llvm/Analysis/PHITransAddr.h
+++ b/include/llvm/Analysis/PHITransAddr.h
@@ -36,9 +36,9 @@ namespace llvm {
class PHITransAddr {
/// Addr - The actual address we're analyzing.
Value *Addr;
-
- /// The DataLayout we are playing with if known, otherwise null.
- const DataLayout *DL;
+
+ /// The DataLayout we are playing with.
+ const DataLayout &DL;
/// TLI - The target library info if known, otherwise null.
const TargetLibraryInfo *TLI;
@@ -49,7 +49,7 @@ class PHITransAddr {
/// InstInputs - The inputs for our symbolic address.
SmallVector<Instruction*, 4> InstInputs;
public:
- PHITransAddr(Value *addr, const DataLayout *DL, AssumptionCache *AC)
+ PHITransAddr(Value *addr, const DataLayout &DL, AssumptionCache *AC)
: Addr(addr), DL(DL), TLI(nullptr), AC(AC) {
// If the address is an instruction, the whole thing is considered an input.
if (Instruction *I = dyn_cast<Instruction>(Addr))
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
index 530faa7..8d11e80 100644
--- a/include/llvm/Analysis/Passes.h
+++ b/include/llvm/Analysis/Passes.h
@@ -159,10 +159,6 @@ namespace llvm {
//
FunctionPass *createMemDepPrinter();
- // createJumpInstrTableInfoPass - This creates a pass that stores information
- // about the jump tables created by JumpInstrTables
- ImmutablePass *createJumpInstrTableInfoPass();
-
//===--------------------------------------------------------------------===//
//
// createMemDerefPrinter - This pass collects memory dereferenceability
diff --git a/include/llvm/Analysis/RegionIterator.h b/include/llvm/Analysis/RegionIterator.h
index 0daff58..ced58df 100644
--- a/include/llvm/Analysis/RegionIterator.h
+++ b/include/llvm/Analysis/RegionIterator.h
@@ -145,16 +145,6 @@ public:
++*this;
return tmp;
}
-
- inline const Self &operator=(const Self &I) {
- if (this != &I) {
- assert(getNode()->getParent() == I.getNode()->getParent()
- && "Cannot assign iterators of two different regions!");
- Node = I.Node;
- BItor = I.BItor;
- }
- return *this;
- }
};
@@ -240,16 +230,6 @@ public:
++*this;
return tmp;
}
-
- inline const Self &operator=(const Self &I) {
- if (this != &I) {
- assert(Node->getParent() == I.Node->getParent()
- && "Cannot assign iterators to two different regions!");
- Node = I.Node;
- Itor = I.Itor;
- }
- return *this;
- }
};
template<class NodeType, class BlockT, class RegionT>
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index c60cea9..4360414 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -232,10 +232,6 @@ namespace llvm {
///
LoopInfo *LI;
- /// The DataLayout information for the target we are targeting.
- ///
- const DataLayout *DL;
-
/// TLI - The target library information for the target we are targeting.
///
TargetLibraryInfo *TLI;
@@ -388,32 +384,31 @@ namespace llvm {
/// computeBlockDisposition - Compute a BlockDisposition value.
BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB);
- /// UnsignedRanges - Memoized results from getUnsignedRange
+ /// UnsignedRanges - Memoized results from getRange
DenseMap<const SCEV *, ConstantRange> UnsignedRanges;
- /// SignedRanges - Memoized results from getSignedRange
+ /// SignedRanges - Memoized results from getRange
DenseMap<const SCEV *, ConstantRange> SignedRanges;
- /// setUnsignedRange - Set the memoized unsigned range for the given SCEV.
- const ConstantRange &setUnsignedRange(const SCEV *S,
- const ConstantRange &CR) {
- std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
- UnsignedRanges.insert(std::make_pair(S, CR));
- if (!Pair.second)
- Pair.first->second = CR;
- return Pair.first->second;
- }
+ /// RangeSignHint - Used to parameterize getRange
+ enum RangeSignHint { HINT_RANGE_UNSIGNED, HINT_RANGE_SIGNED };
+
+ /// setRange - Set the memoized range for the given SCEV.
+ const ConstantRange &setRange(const SCEV *S, RangeSignHint Hint,
+ const ConstantRange &CR) {
+ DenseMap<const SCEV *, ConstantRange> &Cache =
+ Hint == HINT_RANGE_UNSIGNED ? UnsignedRanges : SignedRanges;
- /// setUnsignedRange - Set the memoized signed range for the given SCEV.
- const ConstantRange &setSignedRange(const SCEV *S,
- const ConstantRange &CR) {
std::pair<DenseMap<const SCEV *, ConstantRange>::iterator, bool> Pair =
- SignedRanges.insert(std::make_pair(S, CR));
+ Cache.insert(std::make_pair(S, CR));
if (!Pair.second)
Pair.first->second = CR;
return Pair.first->second;
}
+ /// getRange - Determine the range for a particular SCEV.
+ ConstantRange getRange(const SCEV *S, RangeSignHint Hint);
+
/// createSCEV - We know that there is no SCEV for the specified value.
/// Analyze the expression.
const SCEV *createSCEV(Value *V);
@@ -540,6 +535,15 @@ namespace llvm {
const SCEV *FoundLHS,
const SCEV *FoundRHS);
+ /// isImpliedCondOperandsViaRanges - Test whether the condition described by
+ /// Pred, LHS, and RHS is true whenever the condition described by Pred,
+ /// FoundLHS, and FoundRHS is true. Utility function used by
+ /// isImpliedCondOperands.
+ bool isImpliedCondOperandsViaRanges(ICmpInst::Predicate Pred,
+ const SCEV *LHS, const SCEV *RHS,
+ const SCEV *FoundLHS,
+ const SCEV *FoundRHS);
+
/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
/// in the header of its containing loop, we know the loop executes a
/// constant number of times, and the PHI node is just a recurrence
@@ -561,6 +565,15 @@ namespace llvm {
/// pointer.
bool checkValidity(const SCEV *S) const;
+ // Return true if `ExtendOpTy`({`Start`,+,`Step`}) can be proved to be equal
+ // to {`ExtendOpTy`(`Start`),+,`ExtendOpTy`(`Step`)}. This is equivalent to
+ // proving no signed (resp. unsigned) wrap in {`Start`,+,`Step`} if
+ // `ExtendOpTy` is `SCEVSignExtendExpr` (resp. `SCEVZeroExtendExpr`).
+ //
+ template<typename ExtendOpTy>
+ bool proveNoWrapByVaryingStart(const SCEV *Start, const SCEV *Step,
+ const Loop *L);
+
public:
static char ID; // Pass identification, replacement for typeid
ScalarEvolution();
@@ -834,11 +847,15 @@ namespace llvm {
/// getUnsignedRange - Determine the unsigned range for a particular SCEV.
///
- ConstantRange getUnsignedRange(const SCEV *S);
+ ConstantRange getUnsignedRange(const SCEV *S) {
+ return getRange(S, HINT_RANGE_UNSIGNED);
+ }
/// getSignedRange - Determine the signed range for a particular SCEV.
///
- ConstantRange getSignedRange(const SCEV *S);
+ ConstantRange getSignedRange(const SCEV *S) {
+ return getRange(S, HINT_RANGE_SIGNED);
+ }
/// isKnownNegative - Test if the given expression is known to be negative.
///
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
index b9bef97..b0b0946 100644
--- a/include/llvm/Analysis/ScalarEvolutionExpander.h
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -36,6 +36,7 @@ namespace llvm {
/// memory.
class SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
ScalarEvolution &SE;
+ const DataLayout &DL;
// New instructions receive a name to identifies them with the current pass.
const char* IVName;
@@ -91,10 +92,11 @@ namespace llvm {
public:
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
- explicit SCEVExpander(ScalarEvolution &se, const char *name)
- : SE(se), IVName(name), IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr),
- CanonicalMode(true), LSRMode(false),
- Builder(se.getContext(), TargetFolder(se.DL)) {
+ explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL,
+ const char *name)
+ : SE(se), DL(DL), IVName(name), IVIncInsertLoop(nullptr),
+ IVIncInsertPos(nullptr), CanonicalMode(true), LSRMode(false),
+ Builder(se.getContext(), TargetFolder(DL)) {
#ifndef NDEBUG
DebugType = "";
#endif
diff --git a/include/llvm/Analysis/TargetFolder.h b/include/llvm/Analysis/TargetFolder.h
index 587a7ef..f691296 100644
--- a/include/llvm/Analysis/TargetFolder.h
+++ b/include/llvm/Analysis/TargetFolder.h
@@ -30,7 +30,7 @@ class DataLayout;
/// TargetFolder - Create constants with target dependent folding.
class TargetFolder {
- const DataLayout *DL;
+ const DataLayout &DL;
/// Fold - Fold the constant using target specific information.
Constant *Fold(Constant *C) const {
@@ -41,7 +41,7 @@ class TargetFolder {
}
public:
- explicit TargetFolder(const DataLayout *DL) : DL(DL) {}
+ explicit TargetFolder(const DataLayout &DL) : DL(DL) {}
//===--------------------------------------------------------------------===//
// Binary Operators
diff --git a/include/llvm/Analysis/TargetLibraryInfo.def b/include/llvm/Analysis/TargetLibraryInfo.def
new file mode 100644
index 0000000..1c1fdfe
--- /dev/null
+++ b/include/llvm/Analysis/TargetLibraryInfo.def
@@ -0,0 +1,1029 @@
+//===-- TargetLibraryInfo.def - Library information -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// This .def file will either fill in the enum definition or fill in the
+// string representation array definition for TargetLibraryInfo.
+// Which is defined depends on whether TLI_DEFINE_ENUM is defined or
+// TLI_DEFINE_STRING is defined. Only one should be defined at a time.
+
+#if !(defined(TLI_DEFINE_ENUM) || defined(TLI_DEFINE_STRING))
+#error "Must define TLI_DEFINE_ENUM or TLI_DEFINE_STRING for TLI .def."
+#elif defined(TLI_DEFINE_ENUM) && defined(TLI_DEFINE_STRING)
+#error "Can only define one of TLI_DEFINE_ENUM or TLI_DEFINE_STRING at a time."
+#else
+// One of TLI_DEFINE_ENUM/STRING are defined.
+
+#if defined(TLI_DEFINE_ENUM)
+#define TLI_DEFINE_ENUM_INTERNAL(enum_variant) enum_variant,
+#define TLI_DEFINE_STRING_INTERNAL(string_repr)
+#else
+#define TLI_DEFINE_ENUM_INTERNAL(enum_variant)
+#define TLI_DEFINE_STRING_INTERNAL(string_repr) string_repr,
+#endif
+
+/// int _IO_getc(_IO_FILE * __fp);
+TLI_DEFINE_ENUM_INTERNAL(under_IO_getc)
+TLI_DEFINE_STRING_INTERNAL("_IO_getc")
+/// int _IO_putc(int __c, _IO_FILE * __fp);
+TLI_DEFINE_ENUM_INTERNAL(under_IO_putc)
+TLI_DEFINE_STRING_INTERNAL("_IO_putc")
+/// void operator delete[](void*);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPv)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPv")
+/// void operator delete[](void*, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPvRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPvRKSt9nothrow_t")
+/// void operator delete[](void*, unsigned int);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPvj)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPvj")
+/// void operator delete[](void*, unsigned long);
+TLI_DEFINE_ENUM_INTERNAL(ZdaPvm)
+TLI_DEFINE_STRING_INTERNAL("_ZdaPvm")
+/// void operator delete(void*);
+TLI_DEFINE_ENUM_INTERNAL(ZdlPv)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPv")
+/// void operator delete(void*, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZdlPvRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPvRKSt9nothrow_t")
+/// void operator delete(void*, unsigned int);
+TLI_DEFINE_ENUM_INTERNAL(ZdlPvj)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPvj")
+/// void operator delete(void*, unsigned long);
+TLI_DEFINE_ENUM_INTERNAL(ZdlPvm)
+TLI_DEFINE_STRING_INTERNAL("_ZdlPvm")
+/// void *new[](unsigned int);
+TLI_DEFINE_ENUM_INTERNAL(Znaj)
+TLI_DEFINE_STRING_INTERNAL("_Znaj")
+/// void *new[](unsigned int, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZnajRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZnajRKSt9nothrow_t")
+/// void *new[](unsigned long);
+TLI_DEFINE_ENUM_INTERNAL(Znam)
+TLI_DEFINE_STRING_INTERNAL("_Znam")
+/// void *new[](unsigned long, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZnamRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZnamRKSt9nothrow_t")
+/// void *new(unsigned int);
+TLI_DEFINE_ENUM_INTERNAL(Znwj)
+TLI_DEFINE_STRING_INTERNAL("_Znwj")
+/// void *new(unsigned int, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZnwjRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZnwjRKSt9nothrow_t")
+/// void *new(unsigned long);
+TLI_DEFINE_ENUM_INTERNAL(Znwm)
+TLI_DEFINE_STRING_INTERNAL("_Znwm")
+/// void *new(unsigned long, nothrow);
+TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t)
+TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t")
+/// double __cospi(double x);
+TLI_DEFINE_ENUM_INTERNAL(cospi)
+TLI_DEFINE_STRING_INTERNAL("__cospi")
+/// float __cospif(float x);
+TLI_DEFINE_ENUM_INTERNAL(cospif)
+TLI_DEFINE_STRING_INTERNAL("__cospif")
+/// int __cxa_atexit(void (*f)(void *), void *p, void *d);
+TLI_DEFINE_ENUM_INTERNAL(cxa_atexit)
+TLI_DEFINE_STRING_INTERNAL("__cxa_atexit")
+/// void __cxa_guard_abort(guard_t *guard);
+/// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
+TLI_DEFINE_ENUM_INTERNAL(cxa_guard_abort)
+TLI_DEFINE_STRING_INTERNAL("__cxa_guard_abort")
+/// int __cxa_guard_acquire(guard_t *guard);
+TLI_DEFINE_ENUM_INTERNAL(cxa_guard_acquire)
+TLI_DEFINE_STRING_INTERNAL("__cxa_guard_acquire")
+/// void __cxa_guard_release(guard_t *guard);
+TLI_DEFINE_ENUM_INTERNAL(cxa_guard_release)
+TLI_DEFINE_STRING_INTERNAL("__cxa_guard_release")
+/// int __isoc99_scanf (const char *format, ...)
+TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_scanf)
+TLI_DEFINE_STRING_INTERNAL("__isoc99_scanf")
+/// int __isoc99_sscanf(const char *s, const char *format, ...)
+TLI_DEFINE_ENUM_INTERNAL(dunder_isoc99_sscanf)
+TLI_DEFINE_STRING_INTERNAL("__isoc99_sscanf")
+/// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(memcpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__memcpy_chk")
+/// void *__memmove_chk(void *s1, const void *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(memmove_chk)
+TLI_DEFINE_STRING_INTERNAL("__memmove_chk")
+/// void *__memset_chk(void *s, char v, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(memset_chk)
+TLI_DEFINE_STRING_INTERNAL("__memset_chk")
+/// double __sincospi_stret(double x);
+TLI_DEFINE_ENUM_INTERNAL(sincospi_stret)
+TLI_DEFINE_STRING_INTERNAL("__sincospi_stret")
+/// float __sincospif_stret(float x);
+TLI_DEFINE_ENUM_INTERNAL(sincospif_stret)
+TLI_DEFINE_STRING_INTERNAL("__sincospif_stret")
+/// double __sinpi(double x);
+TLI_DEFINE_ENUM_INTERNAL(sinpi)
+TLI_DEFINE_STRING_INTERNAL("__sinpi")
+/// float __sinpif(float x);
+TLI_DEFINE_ENUM_INTERNAL(sinpif)
+TLI_DEFINE_STRING_INTERNAL("__sinpif")
+/// double __sqrt_finite(double x);
+TLI_DEFINE_ENUM_INTERNAL(sqrt_finite)
+TLI_DEFINE_STRING_INTERNAL("__sqrt_finite")
+/// float __sqrt_finite(float x);
+TLI_DEFINE_ENUM_INTERNAL(sqrtf_finite)
+TLI_DEFINE_STRING_INTERNAL("__sqrtf_finite")
+/// long double __sqrt_finite(long double x);
+TLI_DEFINE_ENUM_INTERNAL(sqrtl_finite)
+TLI_DEFINE_STRING_INTERNAL("__sqrtl_finite")
+/// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(stpcpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__stpcpy_chk")
+/// char *__stpncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(stpncpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__stpncpy_chk")
+/// char *__strcpy_chk(char *s1, const char *s2, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(strcpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__strcpy_chk")
+/// char * __strdup(const char *s);
+TLI_DEFINE_ENUM_INTERNAL(dunder_strdup)
+TLI_DEFINE_STRING_INTERNAL("__strdup")
+/// char *__strncpy_chk(char *s1, const char *s2, size_t n, size_t s1size);
+TLI_DEFINE_ENUM_INTERNAL(strncpy_chk)
+TLI_DEFINE_STRING_INTERNAL("__strncpy_chk")
+/// char *__strndup(const char *s, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(dunder_strndup)
+TLI_DEFINE_STRING_INTERNAL("__strndup")
+/// char * __strtok_r(char *s, const char *delim, char **save_ptr);
+TLI_DEFINE_ENUM_INTERNAL(dunder_strtok_r)
+TLI_DEFINE_STRING_INTERNAL("__strtok_r")
+/// int abs(int j);
+TLI_DEFINE_ENUM_INTERNAL(abs)
+TLI_DEFINE_STRING_INTERNAL("abs")
+/// int access(const char *path, int amode);
+TLI_DEFINE_ENUM_INTERNAL(access)
+TLI_DEFINE_STRING_INTERNAL("access")
+/// double acos(double x);
+TLI_DEFINE_ENUM_INTERNAL(acos)
+TLI_DEFINE_STRING_INTERNAL("acos")
+/// float acosf(float x);
+TLI_DEFINE_ENUM_INTERNAL(acosf)
+TLI_DEFINE_STRING_INTERNAL("acosf")
+/// double acosh(double x);
+TLI_DEFINE_ENUM_INTERNAL(acosh)
+TLI_DEFINE_STRING_INTERNAL("acosh")
+/// float acoshf(float x);
+TLI_DEFINE_ENUM_INTERNAL(acoshf)
+TLI_DEFINE_STRING_INTERNAL("acoshf")
+/// long double acoshl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(acoshl)
+TLI_DEFINE_STRING_INTERNAL("acoshl")
+/// long double acosl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(acosl)
+TLI_DEFINE_STRING_INTERNAL("acosl")
+/// double asin(double x);
+TLI_DEFINE_ENUM_INTERNAL(asin)
+TLI_DEFINE_STRING_INTERNAL("asin")
+/// float asinf(float x);
+TLI_DEFINE_ENUM_INTERNAL(asinf)
+TLI_DEFINE_STRING_INTERNAL("asinf")
+/// double asinh(double x);
+TLI_DEFINE_ENUM_INTERNAL(asinh)
+TLI_DEFINE_STRING_INTERNAL("asinh")
+/// float asinhf(float x);
+TLI_DEFINE_ENUM_INTERNAL(asinhf)
+TLI_DEFINE_STRING_INTERNAL("asinhf")
+/// long double asinhl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(asinhl)
+TLI_DEFINE_STRING_INTERNAL("asinhl")
+/// long double asinl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(asinl)
+TLI_DEFINE_STRING_INTERNAL("asinl")
+/// double atan(double x);
+TLI_DEFINE_ENUM_INTERNAL(atan)
+TLI_DEFINE_STRING_INTERNAL("atan")
+/// double atan2(double y, double x);
+TLI_DEFINE_ENUM_INTERNAL(atan2)
+TLI_DEFINE_STRING_INTERNAL("atan2")
+/// float atan2f(float y, float x);
+TLI_DEFINE_ENUM_INTERNAL(atan2f)
+TLI_DEFINE_STRING_INTERNAL("atan2f")
+/// long double atan2l(long double y, long double x);
+TLI_DEFINE_ENUM_INTERNAL(atan2l)
+TLI_DEFINE_STRING_INTERNAL("atan2l")
+/// float atanf(float x);
+TLI_DEFINE_ENUM_INTERNAL(atanf)
+TLI_DEFINE_STRING_INTERNAL("atanf")
+/// double atanh(double x);
+TLI_DEFINE_ENUM_INTERNAL(atanh)
+TLI_DEFINE_STRING_INTERNAL("atanh")
+/// float atanhf(float x);
+TLI_DEFINE_ENUM_INTERNAL(atanhf)
+TLI_DEFINE_STRING_INTERNAL("atanhf")
+/// long double atanhl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(atanhl)
+TLI_DEFINE_STRING_INTERNAL("atanhl")
+/// long double atanl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(atanl)
+TLI_DEFINE_STRING_INTERNAL("atanl")
+/// double atof(const char *str);
+TLI_DEFINE_ENUM_INTERNAL(atof)
+TLI_DEFINE_STRING_INTERNAL("atof")
+/// int atoi(const char *str);
+TLI_DEFINE_ENUM_INTERNAL(atoi)
+TLI_DEFINE_STRING_INTERNAL("atoi")
+/// long atol(const char *str);
+TLI_DEFINE_ENUM_INTERNAL(atol)
+TLI_DEFINE_STRING_INTERNAL("atol")
+/// long long atoll(const char *nptr);
+TLI_DEFINE_ENUM_INTERNAL(atoll)
+TLI_DEFINE_STRING_INTERNAL("atoll")
+/// int bcmp(const void *s1, const void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(bcmp)
+TLI_DEFINE_STRING_INTERNAL("bcmp")
+/// void bcopy(const void *s1, void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(bcopy)
+TLI_DEFINE_STRING_INTERNAL("bcopy")
+/// void bzero(void *s, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(bzero)
+TLI_DEFINE_STRING_INTERNAL("bzero")
+/// void *calloc(size_t count, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(calloc)
+TLI_DEFINE_STRING_INTERNAL("calloc")
+/// double cbrt(double x);
+TLI_DEFINE_ENUM_INTERNAL(cbrt)
+TLI_DEFINE_STRING_INTERNAL("cbrt")
+/// float cbrtf(float x);
+TLI_DEFINE_ENUM_INTERNAL(cbrtf)
+TLI_DEFINE_STRING_INTERNAL("cbrtf")
+/// long double cbrtl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(cbrtl)
+TLI_DEFINE_STRING_INTERNAL("cbrtl")
+/// double ceil(double x);
+TLI_DEFINE_ENUM_INTERNAL(ceil)
+TLI_DEFINE_STRING_INTERNAL("ceil")
+/// float ceilf(float x);
+TLI_DEFINE_ENUM_INTERNAL(ceilf)
+TLI_DEFINE_STRING_INTERNAL("ceilf")
+/// long double ceill(long double x);
+TLI_DEFINE_ENUM_INTERNAL(ceill)
+TLI_DEFINE_STRING_INTERNAL("ceill")
+/// int chmod(const char *path, mode_t mode);
+TLI_DEFINE_ENUM_INTERNAL(chmod)
+TLI_DEFINE_STRING_INTERNAL("chmod")
+/// int chown(const char *path, uid_t owner, gid_t group);
+TLI_DEFINE_ENUM_INTERNAL(chown)
+TLI_DEFINE_STRING_INTERNAL("chown")
+/// void clearerr(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(clearerr)
+TLI_DEFINE_STRING_INTERNAL("clearerr")
+/// int closedir(DIR *dirp);
+TLI_DEFINE_ENUM_INTERNAL(closedir)
+TLI_DEFINE_STRING_INTERNAL("closedir")
+/// double copysign(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(copysign)
+TLI_DEFINE_STRING_INTERNAL("copysign")
+/// float copysignf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(copysignf)
+TLI_DEFINE_STRING_INTERNAL("copysignf")
+/// long double copysignl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(copysignl)
+TLI_DEFINE_STRING_INTERNAL("copysignl")
+/// double cos(double x);
+TLI_DEFINE_ENUM_INTERNAL(cos)
+TLI_DEFINE_STRING_INTERNAL("cos")
+/// float cosf(float x);
+TLI_DEFINE_ENUM_INTERNAL(cosf)
+TLI_DEFINE_STRING_INTERNAL("cosf")
+/// double cosh(double x);
+TLI_DEFINE_ENUM_INTERNAL(cosh)
+TLI_DEFINE_STRING_INTERNAL("cosh")
+/// float coshf(float x);
+TLI_DEFINE_ENUM_INTERNAL(coshf)
+TLI_DEFINE_STRING_INTERNAL("coshf")
+/// long double coshl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(coshl)
+TLI_DEFINE_STRING_INTERNAL("coshl")
+/// long double cosl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(cosl)
+TLI_DEFINE_STRING_INTERNAL("cosl")
+/// char *ctermid(char *s);
+TLI_DEFINE_ENUM_INTERNAL(ctermid)
+TLI_DEFINE_STRING_INTERNAL("ctermid")
+/// double exp(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp)
+TLI_DEFINE_STRING_INTERNAL("exp")
+/// double exp10(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp10)
+TLI_DEFINE_STRING_INTERNAL("exp10")
+/// float exp10f(float x);
+TLI_DEFINE_ENUM_INTERNAL(exp10f)
+TLI_DEFINE_STRING_INTERNAL("exp10f")
+/// long double exp10l(long double x);
+TLI_DEFINE_ENUM_INTERNAL(exp10l)
+TLI_DEFINE_STRING_INTERNAL("exp10l")
+/// double exp2(double x);
+TLI_DEFINE_ENUM_INTERNAL(exp2)
+TLI_DEFINE_STRING_INTERNAL("exp2")
+/// float exp2f(float x);
+TLI_DEFINE_ENUM_INTERNAL(exp2f)
+TLI_DEFINE_STRING_INTERNAL("exp2f")
+/// long double exp2l(long double x);
+TLI_DEFINE_ENUM_INTERNAL(exp2l)
+TLI_DEFINE_STRING_INTERNAL("exp2l")
+/// float expf(float x);
+TLI_DEFINE_ENUM_INTERNAL(expf)
+TLI_DEFINE_STRING_INTERNAL("expf")
+/// long double expl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(expl)
+TLI_DEFINE_STRING_INTERNAL("expl")
+/// double expm1(double x);
+TLI_DEFINE_ENUM_INTERNAL(expm1)
+TLI_DEFINE_STRING_INTERNAL("expm1")
+/// float expm1f(float x);
+TLI_DEFINE_ENUM_INTERNAL(expm1f)
+TLI_DEFINE_STRING_INTERNAL("expm1f")
+/// long double expm1l(long double x);
+TLI_DEFINE_ENUM_INTERNAL(expm1l)
+TLI_DEFINE_STRING_INTERNAL("expm1l")
+/// double fabs(double x);
+TLI_DEFINE_ENUM_INTERNAL(fabs)
+TLI_DEFINE_STRING_INTERNAL("fabs")
+/// float fabsf(float x);
+TLI_DEFINE_ENUM_INTERNAL(fabsf)
+TLI_DEFINE_STRING_INTERNAL("fabsf")
+/// long double fabsl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(fabsl)
+TLI_DEFINE_STRING_INTERNAL("fabsl")
+/// int fclose(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fclose)
+TLI_DEFINE_STRING_INTERNAL("fclose")
+/// FILE *fdopen(int fildes, const char *mode);
+TLI_DEFINE_ENUM_INTERNAL(fdopen)
+TLI_DEFINE_STRING_INTERNAL("fdopen")
+/// int feof(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(feof)
+TLI_DEFINE_STRING_INTERNAL("feof")
+/// int ferror(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(ferror)
+TLI_DEFINE_STRING_INTERNAL("ferror")
+/// int fflush(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fflush)
+TLI_DEFINE_STRING_INTERNAL("fflush")
+/// int ffs(int i);
+TLI_DEFINE_ENUM_INTERNAL(ffs)
+TLI_DEFINE_STRING_INTERNAL("ffs")
+/// int ffsl(long int i);
+TLI_DEFINE_ENUM_INTERNAL(ffsl)
+TLI_DEFINE_STRING_INTERNAL("ffsl")
+/// int ffsll(long long int i);
+TLI_DEFINE_ENUM_INTERNAL(ffsll)
+TLI_DEFINE_STRING_INTERNAL("ffsll")
+/// int fgetc(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fgetc)
+TLI_DEFINE_STRING_INTERNAL("fgetc")
+/// int fgetpos(FILE *stream, fpos_t *pos);
+TLI_DEFINE_ENUM_INTERNAL(fgetpos)
+TLI_DEFINE_STRING_INTERNAL("fgetpos")
+/// char *fgets(char *s, int n, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fgets)
+TLI_DEFINE_STRING_INTERNAL("fgets")
+/// int fileno(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fileno)
+TLI_DEFINE_STRING_INTERNAL("fileno")
+/// int fiprintf(FILE *stream, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(fiprintf)
+TLI_DEFINE_STRING_INTERNAL("fiprintf")
+/// void flockfile(FILE *file);
+TLI_DEFINE_ENUM_INTERNAL(flockfile)
+TLI_DEFINE_STRING_INTERNAL("flockfile")
+/// double floor(double x);
+TLI_DEFINE_ENUM_INTERNAL(floor)
+TLI_DEFINE_STRING_INTERNAL("floor")
+/// float floorf(float x);
+TLI_DEFINE_ENUM_INTERNAL(floorf)
+TLI_DEFINE_STRING_INTERNAL("floorf")
+/// long double floorl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(floorl)
+TLI_DEFINE_STRING_INTERNAL("floorl")
+/// double fmax(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(fmax)
+TLI_DEFINE_STRING_INTERNAL("fmax")
+/// float fmaxf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(fmaxf)
+TLI_DEFINE_STRING_INTERNAL("fmaxf")
+/// long double fmaxl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(fmaxl)
+TLI_DEFINE_STRING_INTERNAL("fmaxl")
+/// double fmin(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(fmin)
+TLI_DEFINE_STRING_INTERNAL("fmin")
+/// float fminf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(fminf)
+TLI_DEFINE_STRING_INTERNAL("fminf")
+/// long double fminl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(fminl)
+TLI_DEFINE_STRING_INTERNAL("fminl")
+/// double fmod(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(fmod)
+TLI_DEFINE_STRING_INTERNAL("fmod")
+/// float fmodf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(fmodf)
+TLI_DEFINE_STRING_INTERNAL("fmodf")
+/// long double fmodl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(fmodl)
+TLI_DEFINE_STRING_INTERNAL("fmodl")
+/// FILE *fopen(const char *filename, const char *mode);
+TLI_DEFINE_ENUM_INTERNAL(fopen)
+TLI_DEFINE_STRING_INTERNAL("fopen")
+/// FILE *fopen64(const char *filename, const char *opentype)
+TLI_DEFINE_ENUM_INTERNAL(fopen64)
+TLI_DEFINE_STRING_INTERNAL("fopen64")
+/// int fprintf(FILE *stream, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(fprintf)
+TLI_DEFINE_STRING_INTERNAL("fprintf")
+/// int fputc(int c, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fputc)
+TLI_DEFINE_STRING_INTERNAL("fputc")
+/// int fputs(const char *s, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fputs)
+TLI_DEFINE_STRING_INTERNAL("fputs")
+/// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fread)
+TLI_DEFINE_STRING_INTERNAL("fread")
+/// void free(void *ptr);
+TLI_DEFINE_ENUM_INTERNAL(free)
+TLI_DEFINE_STRING_INTERNAL("free")
+/// double frexp(double num, int *exp);
+TLI_DEFINE_ENUM_INTERNAL(frexp)
+TLI_DEFINE_STRING_INTERNAL("frexp")
+/// float frexpf(float num, int *exp);
+TLI_DEFINE_ENUM_INTERNAL(frexpf)
+TLI_DEFINE_STRING_INTERNAL("frexpf")
+/// long double frexpl(long double num, int *exp);
+TLI_DEFINE_ENUM_INTERNAL(frexpl)
+TLI_DEFINE_STRING_INTERNAL("frexpl")
+/// int fscanf(FILE *stream, const char *format, ... );
+TLI_DEFINE_ENUM_INTERNAL(fscanf)
+TLI_DEFINE_STRING_INTERNAL("fscanf")
+/// int fseek(FILE *stream, long offset, int whence);
+TLI_DEFINE_ENUM_INTERNAL(fseek)
+TLI_DEFINE_STRING_INTERNAL("fseek")
+/// int fseeko(FILE *stream, off_t offset, int whence);
+TLI_DEFINE_ENUM_INTERNAL(fseeko)
+TLI_DEFINE_STRING_INTERNAL("fseeko")
+/// int fseeko64(FILE *stream, off64_t offset, int whence)
+TLI_DEFINE_ENUM_INTERNAL(fseeko64)
+TLI_DEFINE_STRING_INTERNAL("fseeko64")
+/// int fsetpos(FILE *stream, const fpos_t *pos);
+TLI_DEFINE_ENUM_INTERNAL(fsetpos)
+TLI_DEFINE_STRING_INTERNAL("fsetpos")
+/// int fstat(int fildes, struct stat *buf);
+TLI_DEFINE_ENUM_INTERNAL(fstat)
+TLI_DEFINE_STRING_INTERNAL("fstat")
+/// int fstat64(int filedes, struct stat64 *buf)
+TLI_DEFINE_ENUM_INTERNAL(fstat64)
+TLI_DEFINE_STRING_INTERNAL("fstat64")
+/// int fstatvfs(int fildes, struct statvfs *buf);
+TLI_DEFINE_ENUM_INTERNAL(fstatvfs)
+TLI_DEFINE_STRING_INTERNAL("fstatvfs")
+/// int fstatvfs64(int fildes, struct statvfs64 *buf);
+TLI_DEFINE_ENUM_INTERNAL(fstatvfs64)
+TLI_DEFINE_STRING_INTERNAL("fstatvfs64")
+/// long ftell(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(ftell)
+TLI_DEFINE_STRING_INTERNAL("ftell")
+/// off_t ftello(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(ftello)
+TLI_DEFINE_STRING_INTERNAL("ftello")
+/// off64_t ftello64(FILE *stream)
+TLI_DEFINE_ENUM_INTERNAL(ftello64)
+TLI_DEFINE_STRING_INTERNAL("ftello64")
+/// int ftrylockfile(FILE *file);
+TLI_DEFINE_ENUM_INTERNAL(ftrylockfile)
+TLI_DEFINE_STRING_INTERNAL("ftrylockfile")
+/// void funlockfile(FILE *file);
+TLI_DEFINE_ENUM_INTERNAL(funlockfile)
+TLI_DEFINE_STRING_INTERNAL("funlockfile")
+/// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(fwrite)
+TLI_DEFINE_STRING_INTERNAL("fwrite")
+/// int getc(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(getc)
+TLI_DEFINE_STRING_INTERNAL("getc")
+/// int getc_unlocked(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(getc_unlocked)
+TLI_DEFINE_STRING_INTERNAL("getc_unlocked")
+/// int getchar(void);
+TLI_DEFINE_ENUM_INTERNAL(getchar)
+TLI_DEFINE_STRING_INTERNAL("getchar")
+/// char *getenv(const char *name);
+TLI_DEFINE_ENUM_INTERNAL(getenv)
+TLI_DEFINE_STRING_INTERNAL("getenv")
+/// int getitimer(int which, struct itimerval *value);
+TLI_DEFINE_ENUM_INTERNAL(getitimer)
+TLI_DEFINE_STRING_INTERNAL("getitimer")
+/// int getlogin_r(char *name, size_t namesize);
+TLI_DEFINE_ENUM_INTERNAL(getlogin_r)
+TLI_DEFINE_STRING_INTERNAL("getlogin_r")
+/// struct passwd *getpwnam(const char *name);
+TLI_DEFINE_ENUM_INTERNAL(getpwnam)
+TLI_DEFINE_STRING_INTERNAL("getpwnam")
+/// char *gets(char *s);
+TLI_DEFINE_ENUM_INTERNAL(gets)
+TLI_DEFINE_STRING_INTERNAL("gets")
+/// int gettimeofday(struct timeval *tp, void *tzp);
+TLI_DEFINE_ENUM_INTERNAL(gettimeofday)
+TLI_DEFINE_STRING_INTERNAL("gettimeofday")
+/// uint32_t htonl(uint32_t hostlong);
+TLI_DEFINE_ENUM_INTERNAL(htonl)
+TLI_DEFINE_STRING_INTERNAL("htonl")
+/// uint16_t htons(uint16_t hostshort);
+TLI_DEFINE_ENUM_INTERNAL(htons)
+TLI_DEFINE_STRING_INTERNAL("htons")
+/// int iprintf(const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(iprintf)
+TLI_DEFINE_STRING_INTERNAL("iprintf")
+/// int isascii(int c);
+TLI_DEFINE_ENUM_INTERNAL(isascii)
+TLI_DEFINE_STRING_INTERNAL("isascii")
+/// int isdigit(int c);
+TLI_DEFINE_ENUM_INTERNAL(isdigit)
+TLI_DEFINE_STRING_INTERNAL("isdigit")
+/// long int labs(long int j);
+TLI_DEFINE_ENUM_INTERNAL(labs)
+TLI_DEFINE_STRING_INTERNAL("labs")
+/// int lchown(const char *path, uid_t owner, gid_t group);
+TLI_DEFINE_ENUM_INTERNAL(lchown)
+TLI_DEFINE_STRING_INTERNAL("lchown")
+/// double ldexp(double x, int n);
+TLI_DEFINE_ENUM_INTERNAL(ldexp)
+TLI_DEFINE_STRING_INTERNAL("ldexp")
+/// float ldexpf(float x, int n);
+TLI_DEFINE_ENUM_INTERNAL(ldexpf)
+TLI_DEFINE_STRING_INTERNAL("ldexpf")
+/// long double ldexpl(long double x, int n);
+TLI_DEFINE_ENUM_INTERNAL(ldexpl)
+TLI_DEFINE_STRING_INTERNAL("ldexpl")
+/// long long int llabs(long long int j);
+TLI_DEFINE_ENUM_INTERNAL(llabs)
+TLI_DEFINE_STRING_INTERNAL("llabs")
+/// double log(double x);
+TLI_DEFINE_ENUM_INTERNAL(log)
+TLI_DEFINE_STRING_INTERNAL("log")
+/// double log10(double x);
+TLI_DEFINE_ENUM_INTERNAL(log10)
+TLI_DEFINE_STRING_INTERNAL("log10")
+/// float log10f(float x);
+TLI_DEFINE_ENUM_INTERNAL(log10f)
+TLI_DEFINE_STRING_INTERNAL("log10f")
+/// long double log10l(long double x);
+TLI_DEFINE_ENUM_INTERNAL(log10l)
+TLI_DEFINE_STRING_INTERNAL("log10l")
+/// double log1p(double x);
+TLI_DEFINE_ENUM_INTERNAL(log1p)
+TLI_DEFINE_STRING_INTERNAL("log1p")
+/// float log1pf(float x);
+TLI_DEFINE_ENUM_INTERNAL(log1pf)
+TLI_DEFINE_STRING_INTERNAL("log1pf")
+/// long double log1pl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(log1pl)
+TLI_DEFINE_STRING_INTERNAL("log1pl")
+/// double log2(double x);
+TLI_DEFINE_ENUM_INTERNAL(log2)
+TLI_DEFINE_STRING_INTERNAL("log2")
+/// float log2f(float x);
+TLI_DEFINE_ENUM_INTERNAL(log2f)
+TLI_DEFINE_STRING_INTERNAL("log2f")
+/// double long double log2l(long double x);
+TLI_DEFINE_ENUM_INTERNAL(log2l)
+TLI_DEFINE_STRING_INTERNAL("log2l")
+/// double logb(double x);
+TLI_DEFINE_ENUM_INTERNAL(logb)
+TLI_DEFINE_STRING_INTERNAL("logb")
+/// float logbf(float x);
+TLI_DEFINE_ENUM_INTERNAL(logbf)
+TLI_DEFINE_STRING_INTERNAL("logbf")
+/// long double logbl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(logbl)
+TLI_DEFINE_STRING_INTERNAL("logbl")
+/// float logf(float x);
+TLI_DEFINE_ENUM_INTERNAL(logf)
+TLI_DEFINE_STRING_INTERNAL("logf")
+/// long double logl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(logl)
+TLI_DEFINE_STRING_INTERNAL("logl")
+/// int lstat(const char *path, struct stat *buf);
+TLI_DEFINE_ENUM_INTERNAL(lstat)
+TLI_DEFINE_STRING_INTERNAL("lstat")
+/// int lstat64(const char *path, struct stat64 *buf);
+TLI_DEFINE_ENUM_INTERNAL(lstat64)
+TLI_DEFINE_STRING_INTERNAL("lstat64")
+/// void *malloc(size_t size);
+TLI_DEFINE_ENUM_INTERNAL(malloc)
+TLI_DEFINE_STRING_INTERNAL("malloc")
+/// void *memalign(size_t boundary, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(memalign)
+TLI_DEFINE_STRING_INTERNAL("memalign")
+/// void *memccpy(void *s1, const void *s2, int c, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memccpy)
+TLI_DEFINE_STRING_INTERNAL("memccpy")
+/// void *memchr(const void *s, int c, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memchr)
+TLI_DEFINE_STRING_INTERNAL("memchr")
+/// int memcmp(const void *s1, const void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memcmp)
+TLI_DEFINE_STRING_INTERNAL("memcmp")
+/// void *memcpy(void *s1, const void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memcpy)
+TLI_DEFINE_STRING_INTERNAL("memcpy")
+/// void *memmove(void *s1, const void *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memmove)
+TLI_DEFINE_STRING_INTERNAL("memmove")
+// void *memrchr(const void *s, int c, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(memrchr)
+TLI_DEFINE_STRING_INTERNAL("memrchr")
+/// void *memset(void *b, int c, size_t len);
+TLI_DEFINE_ENUM_INTERNAL(memset)
+TLI_DEFINE_STRING_INTERNAL("memset")
+/// void memset_pattern16(void *b, const void *pattern16, size_t len);
+TLI_DEFINE_ENUM_INTERNAL(memset_pattern16)
+TLI_DEFINE_STRING_INTERNAL("memset_pattern16")
+/// int mkdir(const char *path, mode_t mode);
+TLI_DEFINE_ENUM_INTERNAL(mkdir)
+TLI_DEFINE_STRING_INTERNAL("mkdir")
+/// time_t mktime(struct tm *timeptr);
+TLI_DEFINE_ENUM_INTERNAL(mktime)
+TLI_DEFINE_STRING_INTERNAL("mktime")
+/// double modf(double x, double *iptr);
+TLI_DEFINE_ENUM_INTERNAL(modf)
+TLI_DEFINE_STRING_INTERNAL("modf")
+/// float modff(float, float *iptr);
+TLI_DEFINE_ENUM_INTERNAL(modff)
+TLI_DEFINE_STRING_INTERNAL("modff")
+/// long double modfl(long double value, long double *iptr);
+TLI_DEFINE_ENUM_INTERNAL(modfl)
+TLI_DEFINE_STRING_INTERNAL("modfl")
+/// double nearbyint(double x);
+TLI_DEFINE_ENUM_INTERNAL(nearbyint)
+TLI_DEFINE_STRING_INTERNAL("nearbyint")
+/// float nearbyintf(float x);
+TLI_DEFINE_ENUM_INTERNAL(nearbyintf)
+TLI_DEFINE_STRING_INTERNAL("nearbyintf")
+/// long double nearbyintl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(nearbyintl)
+TLI_DEFINE_STRING_INTERNAL("nearbyintl")
+/// uint32_t ntohl(uint32_t netlong);
+TLI_DEFINE_ENUM_INTERNAL(ntohl)
+TLI_DEFINE_STRING_INTERNAL("ntohl")
+/// uint16_t ntohs(uint16_t netshort);
+TLI_DEFINE_ENUM_INTERNAL(ntohs)
+TLI_DEFINE_STRING_INTERNAL("ntohs")
+/// int open(const char *path, int oflag, ... );
+TLI_DEFINE_ENUM_INTERNAL(open)
+TLI_DEFINE_STRING_INTERNAL("open")
+/// int open64(const char *filename, int flags[, mode_t mode])
+TLI_DEFINE_ENUM_INTERNAL(open64)
+TLI_DEFINE_STRING_INTERNAL("open64")
+/// DIR *opendir(const char *dirname);
+TLI_DEFINE_ENUM_INTERNAL(opendir)
+TLI_DEFINE_STRING_INTERNAL("opendir")
+/// int pclose(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(pclose)
+TLI_DEFINE_STRING_INTERNAL("pclose")
+/// void perror(const char *s);
+TLI_DEFINE_ENUM_INTERNAL(perror)
+TLI_DEFINE_STRING_INTERNAL("perror")
+/// FILE *popen(const char *command, const char *mode);
+TLI_DEFINE_ENUM_INTERNAL(popen)
+TLI_DEFINE_STRING_INTERNAL("popen")
+/// int posix_memalign(void **memptr, size_t alignment, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(posix_memalign)
+TLI_DEFINE_STRING_INTERNAL("posix_memalign")
+/// double pow(double x, double y);
+TLI_DEFINE_ENUM_INTERNAL(pow)
+TLI_DEFINE_STRING_INTERNAL("pow")
+/// float powf(float x, float y);
+TLI_DEFINE_ENUM_INTERNAL(powf)
+TLI_DEFINE_STRING_INTERNAL("powf")
+/// long double powl(long double x, long double y);
+TLI_DEFINE_ENUM_INTERNAL(powl)
+TLI_DEFINE_STRING_INTERNAL("powl")
+/// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
+TLI_DEFINE_ENUM_INTERNAL(pread)
+TLI_DEFINE_STRING_INTERNAL("pread")
+/// int printf(const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(printf)
+TLI_DEFINE_STRING_INTERNAL("printf")
+/// int putc(int c, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(putc)
+TLI_DEFINE_STRING_INTERNAL("putc")
+/// int putchar(int c);
+TLI_DEFINE_ENUM_INTERNAL(putchar)
+TLI_DEFINE_STRING_INTERNAL("putchar")
+/// int puts(const char *s);
+TLI_DEFINE_ENUM_INTERNAL(puts)
+TLI_DEFINE_STRING_INTERNAL("puts")
+/// ssize_t pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
+TLI_DEFINE_ENUM_INTERNAL(pwrite)
+TLI_DEFINE_STRING_INTERNAL("pwrite")
+/// void qsort(void *base, size_t nel, size_t width,
+/// int (*compar)(const void *, const void *));
+TLI_DEFINE_ENUM_INTERNAL(qsort)
+TLI_DEFINE_STRING_INTERNAL("qsort")
+/// ssize_t read(int fildes, void *buf, size_t nbyte);
+TLI_DEFINE_ENUM_INTERNAL(read)
+TLI_DEFINE_STRING_INTERNAL("read")
+/// ssize_t readlink(const char *path, char *buf, size_t bufsize);
+TLI_DEFINE_ENUM_INTERNAL(readlink)
+TLI_DEFINE_STRING_INTERNAL("readlink")
+/// void *realloc(void *ptr, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(realloc)
+TLI_DEFINE_STRING_INTERNAL("realloc")
+/// void *reallocf(void *ptr, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(reallocf)
+TLI_DEFINE_STRING_INTERNAL("reallocf")
+/// char *realpath(const char *file_name, char *resolved_name);
+TLI_DEFINE_ENUM_INTERNAL(realpath)
+TLI_DEFINE_STRING_INTERNAL("realpath")
+/// int remove(const char *path);
+TLI_DEFINE_ENUM_INTERNAL(remove)
+TLI_DEFINE_STRING_INTERNAL("remove")
+/// int rename(const char *old, const char *new);
+TLI_DEFINE_ENUM_INTERNAL(rename)
+TLI_DEFINE_STRING_INTERNAL("rename")
+/// void rewind(FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(rewind)
+TLI_DEFINE_STRING_INTERNAL("rewind")
+/// double rint(double x);
+TLI_DEFINE_ENUM_INTERNAL(rint)
+TLI_DEFINE_STRING_INTERNAL("rint")
+/// float rintf(float x);
+TLI_DEFINE_ENUM_INTERNAL(rintf)
+TLI_DEFINE_STRING_INTERNAL("rintf")
+/// long double rintl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(rintl)
+TLI_DEFINE_STRING_INTERNAL("rintl")
+/// int rmdir(const char *path);
+TLI_DEFINE_ENUM_INTERNAL(rmdir)
+TLI_DEFINE_STRING_INTERNAL("rmdir")
+/// double round(double x);
+TLI_DEFINE_ENUM_INTERNAL(round)
+TLI_DEFINE_STRING_INTERNAL("round")
+/// float roundf(float x);
+TLI_DEFINE_ENUM_INTERNAL(roundf)
+TLI_DEFINE_STRING_INTERNAL("roundf")
+/// long double roundl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(roundl)
+TLI_DEFINE_STRING_INTERNAL("roundl")
+/// int scanf(const char *restrict format, ... );
+TLI_DEFINE_ENUM_INTERNAL(scanf)
+TLI_DEFINE_STRING_INTERNAL("scanf")
+/// void setbuf(FILE *stream, char *buf);
+TLI_DEFINE_ENUM_INTERNAL(setbuf)
+TLI_DEFINE_STRING_INTERNAL("setbuf")
+/// int setitimer(int which, const struct itimerval *value,
+/// struct itimerval *ovalue);
+TLI_DEFINE_ENUM_INTERNAL(setitimer)
+TLI_DEFINE_STRING_INTERNAL("setitimer")
+/// int setvbuf(FILE *stream, char *buf, int type, size_t size);
+TLI_DEFINE_ENUM_INTERNAL(setvbuf)
+TLI_DEFINE_STRING_INTERNAL("setvbuf")
+/// double sin(double x);
+TLI_DEFINE_ENUM_INTERNAL(sin)
+TLI_DEFINE_STRING_INTERNAL("sin")
+/// float sinf(float x);
+TLI_DEFINE_ENUM_INTERNAL(sinf)
+TLI_DEFINE_STRING_INTERNAL("sinf")
+/// double sinh(double x);
+TLI_DEFINE_ENUM_INTERNAL(sinh)
+TLI_DEFINE_STRING_INTERNAL("sinh")
+/// float sinhf(float x);
+TLI_DEFINE_ENUM_INTERNAL(sinhf)
+TLI_DEFINE_STRING_INTERNAL("sinhf")
+/// long double sinhl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(sinhl)
+TLI_DEFINE_STRING_INTERNAL("sinhl")
+/// long double sinl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(sinl)
+TLI_DEFINE_STRING_INTERNAL("sinl")
+/// int siprintf(char *str, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(siprintf)
+TLI_DEFINE_STRING_INTERNAL("siprintf")
+/// int snprintf(char *s, size_t n, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(snprintf)
+TLI_DEFINE_STRING_INTERNAL("snprintf")
+/// int sprintf(char *str, const char *format, ...);
+TLI_DEFINE_ENUM_INTERNAL(sprintf)
+TLI_DEFINE_STRING_INTERNAL("sprintf")
+/// double sqrt(double x);
+TLI_DEFINE_ENUM_INTERNAL(sqrt)
+TLI_DEFINE_STRING_INTERNAL("sqrt")
+/// float sqrtf(float x);
+TLI_DEFINE_ENUM_INTERNAL(sqrtf)
+TLI_DEFINE_STRING_INTERNAL("sqrtf")
+/// long double sqrtl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(sqrtl)
+TLI_DEFINE_STRING_INTERNAL("sqrtl")
+/// int sscanf(const char *s, const char *format, ... );
+TLI_DEFINE_ENUM_INTERNAL(sscanf)
+TLI_DEFINE_STRING_INTERNAL("sscanf")
+/// int stat(const char *path, struct stat *buf);
+TLI_DEFINE_ENUM_INTERNAL(stat)
+TLI_DEFINE_STRING_INTERNAL("stat")
+/// int stat64(const char *path, struct stat64 *buf);
+TLI_DEFINE_ENUM_INTERNAL(stat64)
+TLI_DEFINE_STRING_INTERNAL("stat64")
+/// int statvfs(const char *path, struct statvfs *buf);
+TLI_DEFINE_ENUM_INTERNAL(statvfs)
+TLI_DEFINE_STRING_INTERNAL("statvfs")
+/// int statvfs64(const char *path, struct statvfs64 *buf)
+TLI_DEFINE_ENUM_INTERNAL(statvfs64)
+TLI_DEFINE_STRING_INTERNAL("statvfs64")
+/// char *stpcpy(char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(stpcpy)
+TLI_DEFINE_STRING_INTERNAL("stpcpy")
+/// char *stpncpy(char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(stpncpy)
+TLI_DEFINE_STRING_INTERNAL("stpncpy")
+/// int strcasecmp(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcasecmp)
+TLI_DEFINE_STRING_INTERNAL("strcasecmp")
+/// char *strcat(char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcat)
+TLI_DEFINE_STRING_INTERNAL("strcat")
+/// char *strchr(const char *s, int c);
+TLI_DEFINE_ENUM_INTERNAL(strchr)
+TLI_DEFINE_STRING_INTERNAL("strchr")
+/// int strcmp(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcmp)
+TLI_DEFINE_STRING_INTERNAL("strcmp")
+/// int strcoll(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcoll)
+TLI_DEFINE_STRING_INTERNAL("strcoll")
+/// char *strcpy(char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcpy)
+TLI_DEFINE_STRING_INTERNAL("strcpy")
+/// size_t strcspn(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strcspn)
+TLI_DEFINE_STRING_INTERNAL("strcspn")
+/// char *strdup(const char *s1);
+TLI_DEFINE_ENUM_INTERNAL(strdup)
+TLI_DEFINE_STRING_INTERNAL("strdup")
+/// size_t strlen(const char *s);
+TLI_DEFINE_ENUM_INTERNAL(strlen)
+TLI_DEFINE_STRING_INTERNAL("strlen")
+/// int strncasecmp(const char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strncasecmp)
+TLI_DEFINE_STRING_INTERNAL("strncasecmp")
+/// char *strncat(char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strncat)
+TLI_DEFINE_STRING_INTERNAL("strncat")
+/// int strncmp(const char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strncmp)
+TLI_DEFINE_STRING_INTERNAL("strncmp")
+/// char *strncpy(char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strncpy)
+TLI_DEFINE_STRING_INTERNAL("strncpy")
+/// char *strndup(const char *s1, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strndup)
+TLI_DEFINE_STRING_INTERNAL("strndup")
+/// size_t strnlen(const char *s, size_t maxlen);
+TLI_DEFINE_ENUM_INTERNAL(strnlen)
+TLI_DEFINE_STRING_INTERNAL("strnlen")
+/// char *strpbrk(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strpbrk)
+TLI_DEFINE_STRING_INTERNAL("strpbrk")
+/// char *strrchr(const char *s, int c);
+TLI_DEFINE_ENUM_INTERNAL(strrchr)
+TLI_DEFINE_STRING_INTERNAL("strrchr")
+/// size_t strspn(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strspn)
+TLI_DEFINE_STRING_INTERNAL("strspn")
+/// char *strstr(const char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strstr)
+TLI_DEFINE_STRING_INTERNAL("strstr")
+/// double strtod(const char *nptr, char **endptr);
+TLI_DEFINE_ENUM_INTERNAL(strtod)
+TLI_DEFINE_STRING_INTERNAL("strtod")
+/// float strtof(const char *nptr, char **endptr);
+TLI_DEFINE_ENUM_INTERNAL(strtof)
+TLI_DEFINE_STRING_INTERNAL("strtof")
+// char *strtok(char *s1, const char *s2);
+TLI_DEFINE_ENUM_INTERNAL(strtok)
+TLI_DEFINE_STRING_INTERNAL("strtok")
+// char *strtok_r(char *s, const char *sep, char **lasts);
+TLI_DEFINE_ENUM_INTERNAL(strtok_r)
+TLI_DEFINE_STRING_INTERNAL("strtok_r")
+/// long int strtol(const char *nptr, char **endptr, int base);
+TLI_DEFINE_ENUM_INTERNAL(strtol)
+TLI_DEFINE_STRING_INTERNAL("strtol")
+/// long double strtold(const char *nptr, char **endptr);
+TLI_DEFINE_ENUM_INTERNAL(strtold)
+TLI_DEFINE_STRING_INTERNAL("strtold")
+/// long long int strtoll(const char *nptr, char **endptr, int base);
+TLI_DEFINE_ENUM_INTERNAL(strtoll)
+TLI_DEFINE_STRING_INTERNAL("strtoll")
+/// unsigned long int strtoul(const char *nptr, char **endptr, int base);
+TLI_DEFINE_ENUM_INTERNAL(strtoul)
+TLI_DEFINE_STRING_INTERNAL("strtoul")
+/// unsigned long long int strtoull(const char *nptr, char **endptr, int base);
+TLI_DEFINE_ENUM_INTERNAL(strtoull)
+TLI_DEFINE_STRING_INTERNAL("strtoull")
+/// size_t strxfrm(char *s1, const char *s2, size_t n);
+TLI_DEFINE_ENUM_INTERNAL(strxfrm)
+TLI_DEFINE_STRING_INTERNAL("strxfrm")
+/// int system(const char *command);
+TLI_DEFINE_ENUM_INTERNAL(system)
+TLI_DEFINE_STRING_INTERNAL("system")
+/// double tan(double x);
+TLI_DEFINE_ENUM_INTERNAL(tan)
+TLI_DEFINE_STRING_INTERNAL("tan")
+/// float tanf(float x);
+TLI_DEFINE_ENUM_INTERNAL(tanf)
+TLI_DEFINE_STRING_INTERNAL("tanf")
+/// double tanh(double x);
+TLI_DEFINE_ENUM_INTERNAL(tanh)
+TLI_DEFINE_STRING_INTERNAL("tanh")
+/// float tanhf(float x);
+TLI_DEFINE_ENUM_INTERNAL(tanhf)
+TLI_DEFINE_STRING_INTERNAL("tanhf")
+/// long double tanhl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(tanhl)
+TLI_DEFINE_STRING_INTERNAL("tanhl")
+/// long double tanl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(tanl)
+TLI_DEFINE_STRING_INTERNAL("tanl")
+/// clock_t times(struct tms *buffer);
+TLI_DEFINE_ENUM_INTERNAL(times)
+TLI_DEFINE_STRING_INTERNAL("times")
+/// FILE *tmpfile(void);
+TLI_DEFINE_ENUM_INTERNAL(tmpfile)
+TLI_DEFINE_STRING_INTERNAL("tmpfile")
+/// FILE *tmpfile64(void)
+TLI_DEFINE_ENUM_INTERNAL(tmpfile64)
+TLI_DEFINE_STRING_INTERNAL("tmpfile64")
+/// int toascii(int c);
+TLI_DEFINE_ENUM_INTERNAL(toascii)
+TLI_DEFINE_STRING_INTERNAL("toascii")
+/// double trunc(double x);
+TLI_DEFINE_ENUM_INTERNAL(trunc)
+TLI_DEFINE_STRING_INTERNAL("trunc")
+/// float truncf(float x);
+TLI_DEFINE_ENUM_INTERNAL(truncf)
+TLI_DEFINE_STRING_INTERNAL("truncf")
+/// long double truncl(long double x);
+TLI_DEFINE_ENUM_INTERNAL(truncl)
+TLI_DEFINE_STRING_INTERNAL("truncl")
+/// int uname(struct utsname *name);
+TLI_DEFINE_ENUM_INTERNAL(uname)
+TLI_DEFINE_STRING_INTERNAL("uname")
+/// int ungetc(int c, FILE *stream);
+TLI_DEFINE_ENUM_INTERNAL(ungetc)
+TLI_DEFINE_STRING_INTERNAL("ungetc")
+/// int unlink(const char *path);
+TLI_DEFINE_ENUM_INTERNAL(unlink)
+TLI_DEFINE_STRING_INTERNAL("unlink")
+/// int unsetenv(const char *name);
+TLI_DEFINE_ENUM_INTERNAL(unsetenv)
+TLI_DEFINE_STRING_INTERNAL("unsetenv")
+/// int utime(const char *path, const struct utimbuf *times);
+TLI_DEFINE_ENUM_INTERNAL(utime)
+TLI_DEFINE_STRING_INTERNAL("utime")
+/// int utimes(const char *path, const struct timeval times[2]);
+TLI_DEFINE_ENUM_INTERNAL(utimes)
+TLI_DEFINE_STRING_INTERNAL("utimes")
+/// void *valloc(size_t size);
+TLI_DEFINE_ENUM_INTERNAL(valloc)
+TLI_DEFINE_STRING_INTERNAL("valloc")
+/// int vfprintf(FILE *stream, const char *format, va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vfprintf)
+TLI_DEFINE_STRING_INTERNAL("vfprintf")
+/// int vfscanf(FILE *stream, const char *format, va_list arg);
+TLI_DEFINE_ENUM_INTERNAL(vfscanf)
+TLI_DEFINE_STRING_INTERNAL("vfscanf")
+/// int vprintf(const char *restrict format, va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vprintf)
+TLI_DEFINE_STRING_INTERNAL("vprintf")
+/// int vscanf(const char *format, va_list arg);
+TLI_DEFINE_ENUM_INTERNAL(vscanf)
+TLI_DEFINE_STRING_INTERNAL("vscanf")
+/// int vsnprintf(char *s, size_t n, const char *format, va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vsnprintf)
+TLI_DEFINE_STRING_INTERNAL("vsnprintf")
+/// int vsprintf(char *s, const char *format, va_list ap);
+TLI_DEFINE_ENUM_INTERNAL(vsprintf)
+TLI_DEFINE_STRING_INTERNAL("vsprintf")
+/// int vsscanf(const char *s, const char *format, va_list arg);
+TLI_DEFINE_ENUM_INTERNAL(vsscanf)
+TLI_DEFINE_STRING_INTERNAL("vsscanf")
+/// ssize_t write(int fildes, const void *buf, size_t nbyte);
+TLI_DEFINE_ENUM_INTERNAL(write)
+TLI_DEFINE_STRING_INTERNAL("write")
+
+#undef TLI_DEFINE_ENUM_INTERNAL
+#undef TLI_DEFINE_STRING_INTERNAL
+#endif // One of TLI_DEFINE_ENUM/STRING are defined.
+
+#undef TLI_DEFINE_ENUM
+#undef TLI_DEFINE_STRING
diff --git a/include/llvm/Analysis/TargetLibraryInfo.h b/include/llvm/Analysis/TargetLibraryInfo.h
index 5c6f364..9579848 100644
--- a/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/include/llvm/Analysis/TargetLibraryInfo.h
@@ -11,6 +11,7 @@
#define LLVM_ANALYSIS_TARGETLIBRARYINFO_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/Function.h"
@@ -29,679 +30,20 @@
// END ANDROID-SPECIFIC
namespace llvm {
+/// VecDesc - Describes a possible vectorization of a function.
+/// Function 'VectorFnName' is equivalent to 'ScalarFnName' vectorized
+/// by a factor 'VectorizationFactor'.
+struct VecDesc {
+ const char *ScalarFnName;
+ const char *VectorFnName;
+ unsigned VectorizationFactor;
+};
class PreservedAnalyses;
namespace LibFunc {
enum Func {
- /// int _IO_getc(_IO_FILE * __fp);
- under_IO_getc,
- /// int _IO_putc(int __c, _IO_FILE * __fp);
- under_IO_putc,
- /// void operator delete[](void*);
- ZdaPv,
- /// void operator delete[](void*, nothrow);
- ZdaPvRKSt9nothrow_t,
- /// void operator delete[](void*, unsigned int);
- ZdaPvj,
- /// void operator delete[](void*, unsigned long);
- ZdaPvm,
- /// void operator delete(void*);
- ZdlPv,
- /// void operator delete(void*, nothrow);
- ZdlPvRKSt9nothrow_t,
- /// void operator delete(void*, unsigned int);
- ZdlPvj,
- /// void operator delete(void*, unsigned long);
- ZdlPvm,
- /// void *new[](unsigned int);
- Znaj,
- /// void *new[](unsigned int, nothrow);
- ZnajRKSt9nothrow_t,
- /// void *new[](unsigned long);
- Znam,
- /// void *new[](unsigned long, nothrow);
- ZnamRKSt9nothrow_t,
- /// void *new(unsigned int);
- Znwj,
- /// void *new(unsigned int, nothrow);
- ZnwjRKSt9nothrow_t,
- /// void *new(unsigned long);
- Znwm,
- /// void *new(unsigned long, nothrow);
- ZnwmRKSt9nothrow_t,
- /// double __cospi(double x);
- cospi,
- /// float __cospif(float x);
- cospif,
- /// int __cxa_atexit(void (*f)(void *), void *p, void *d);
- cxa_atexit,
- /// void __cxa_guard_abort(guard_t *guard);
- /// guard_t is int64_t in Itanium ABI or int32_t on ARM eabi.
- cxa_guard_abort,
- /// int __cxa_guard_acquire(guard_t *guard);
- cxa_guard_acquire,
- /// void __cxa_guard_release(guard_t *guard);
- cxa_guard_release,
- /// int __isoc99_scanf (const char *format, ...)
- dunder_isoc99_scanf,
- /// int __isoc99_sscanf(const char *s, const char *format, ...)
- dunder_isoc99_sscanf,
- /// void *__memcpy_chk(void *s1, const void *s2, size_t n, size_t s1size);
- memcpy_chk,
- /// void *__memmove_chk(void *s1, const void *s2, size_t n,
- /// size_t s1size);
- memmove_chk,
- /// void *__memset_chk(void *s, char v, size_t n, size_t s1size);
- memset_chk,
- /// double __sincospi_stret(double x);
- sincospi_stret,
- /// float __sincospif_stret(float x);
- sincospif_stret,
- /// double __sinpi(double x);
- sinpi,
- /// float __sinpif(float x);
- sinpif,
- /// double __sqrt_finite(double x);
- sqrt_finite,
- /// float __sqrt_finite(float x);
- sqrtf_finite,
- /// long double __sqrt_finite(long double x);
- sqrtl_finite,
- /// char *__stpcpy_chk(char *s1, const char *s2, size_t s1size);
- stpcpy_chk,
- /// char *__stpncpy_chk(char *s1, const char *s2, size_t n,
- /// size_t s1size);
- stpncpy_chk,
- /// char *__strcpy_chk(char *s1, const char *s2, size_t s1size);
- strcpy_chk,
- /// char * __strdup(const char *s);
- dunder_strdup,
- /// char *__strncpy_chk(char *s1, const char *s2, size_t n,
- /// size_t s1size);
- strncpy_chk,
- /// char *__strndup(const char *s, size_t n);
- dunder_strndup,
- /// char * __strtok_r(char *s, const char *delim, char **save_ptr);
- dunder_strtok_r,
- /// int abs(int j);
- abs,
- /// int access(const char *path, int amode);
- access,
- /// double acos(double x);
- acos,
- /// float acosf(float x);
- acosf,
- /// double acosh(double x);
- acosh,
- /// float acoshf(float x);
- acoshf,
- /// long double acoshl(long double x);
- acoshl,
- /// long double acosl(long double x);
- acosl,
- /// double asin(double x);
- asin,
- /// float asinf(float x);
- asinf,
- /// double asinh(double x);
- asinh,
- /// float asinhf(float x);
- asinhf,
- /// long double asinhl(long double x);
- asinhl,
- /// long double asinl(long double x);
- asinl,
- /// double atan(double x);
- atan,
- /// double atan2(double y, double x);
- atan2,
- /// float atan2f(float y, float x);
- atan2f,
- /// long double atan2l(long double y, long double x);
- atan2l,
- /// float atanf(float x);
- atanf,
- /// double atanh(double x);
- atanh,
- /// float atanhf(float x);
- atanhf,
- /// long double atanhl(long double x);
- atanhl,
- /// long double atanl(long double x);
- atanl,
- /// double atof(const char *str);
- atof,
- /// int atoi(const char *str);
- atoi,
- /// long atol(const char *str);
- atol,
- /// long long atoll(const char *nptr);
- atoll,
- /// int bcmp(const void *s1, const void *s2, size_t n);
- bcmp,
- /// void bcopy(const void *s1, void *s2, size_t n);
- bcopy,
- /// void bzero(void *s, size_t n);
- bzero,
- /// void *calloc(size_t count, size_t size);
- calloc,
- /// double cbrt(double x);
- cbrt,
- /// float cbrtf(float x);
- cbrtf,
- /// long double cbrtl(long double x);
- cbrtl,
- /// double ceil(double x);
- ceil,
- /// float ceilf(float x);
- ceilf,
- /// long double ceill(long double x);
- ceill,
- /// int chmod(const char *path, mode_t mode);
- chmod,
- /// int chown(const char *path, uid_t owner, gid_t group);
- chown,
- /// void clearerr(FILE *stream);
- clearerr,
- /// int closedir(DIR *dirp);
- closedir,
- /// double copysign(double x, double y);
- copysign,
- /// float copysignf(float x, float y);
- copysignf,
- /// long double copysignl(long double x, long double y);
- copysignl,
- /// double cos(double x);
- cos,
- /// float cosf(float x);
- cosf,
- /// double cosh(double x);
- cosh,
- /// float coshf(float x);
- coshf,
- /// long double coshl(long double x);
- coshl,
- /// long double cosl(long double x);
- cosl,
- /// char *ctermid(char *s);
- ctermid,
- /// double exp(double x);
- exp,
- /// double exp10(double x);
- exp10,
- /// float exp10f(float x);
- exp10f,
- /// long double exp10l(long double x);
- exp10l,
- /// double exp2(double x);
- exp2,
- /// float exp2f(float x);
- exp2f,
- /// long double exp2l(long double x);
- exp2l,
- /// float expf(float x);
- expf,
- /// long double expl(long double x);
- expl,
- /// double expm1(double x);
- expm1,
- /// float expm1f(float x);
- expm1f,
- /// long double expm1l(long double x);
- expm1l,
- /// double fabs(double x);
- fabs,
- /// float fabsf(float x);
- fabsf,
- /// long double fabsl(long double x);
- fabsl,
- /// int fclose(FILE *stream);
- fclose,
- /// FILE *fdopen(int fildes, const char *mode);
- fdopen,
- /// int feof(FILE *stream);
- feof,
- /// int ferror(FILE *stream);
- ferror,
- /// int fflush(FILE *stream);
- fflush,
- /// int ffs(int i);
- ffs,
- /// int ffsl(long int i);
- ffsl,
- /// int ffsll(long long int i);
- ffsll,
- /// int fgetc(FILE *stream);
- fgetc,
- /// int fgetpos(FILE *stream, fpos_t *pos);
- fgetpos,
- /// char *fgets(char *s, int n, FILE *stream);
- fgets,
- /// int fileno(FILE *stream);
- fileno,
- /// int fiprintf(FILE *stream, const char *format, ...);
- fiprintf,
- /// void flockfile(FILE *file);
- flockfile,
- /// double floor(double x);
- floor,
- /// float floorf(float x);
- floorf,
- /// long double floorl(long double x);
- floorl,
- /// double fmax(double x, double y);
- fmax,
- /// float fmaxf(float x, float y);
- fmaxf,
- /// long double fmaxl(long double x, long double y);
- fmaxl,
- /// double fmin(double x, double y);
- fmin,
- /// float fminf(float x, float y);
- fminf,
- /// long double fminl(long double x, long double y);
- fminl,
- /// double fmod(double x, double y);
- fmod,
- /// float fmodf(float x, float y);
- fmodf,
- /// long double fmodl(long double x, long double y);
- fmodl,
- /// FILE *fopen(const char *filename, const char *mode);
- fopen,
- /// FILE *fopen64(const char *filename, const char *opentype)
- fopen64,
- /// int fprintf(FILE *stream, const char *format, ...);
- fprintf,
- /// int fputc(int c, FILE *stream);
- fputc,
- /// int fputs(const char *s, FILE *stream);
- fputs,
- /// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream);
- fread,
- /// void free(void *ptr);
- free,
- /// double frexp(double num, int *exp);
- frexp,
- /// float frexpf(float num, int *exp);
- frexpf,
- /// long double frexpl(long double num, int *exp);
- frexpl,
- /// int fscanf(FILE *stream, const char *format, ... );
- fscanf,
- /// int fseek(FILE *stream, long offset, int whence);
- fseek,
- /// int fseeko(FILE *stream, off_t offset, int whence);
- fseeko,
- /// int fseeko64(FILE *stream, off64_t offset, int whence)
- fseeko64,
- /// int fsetpos(FILE *stream, const fpos_t *pos);
- fsetpos,
- /// int fstat(int fildes, struct stat *buf);
- fstat,
- /// int fstat64(int filedes, struct stat64 *buf)
- fstat64,
- /// int fstatvfs(int fildes, struct statvfs *buf);
- fstatvfs,
- /// int fstatvfs64(int fildes, struct statvfs64 *buf);
- fstatvfs64,
- /// long ftell(FILE *stream);
- ftell,
- /// off_t ftello(FILE *stream);
- ftello,
- /// off64_t ftello64(FILE *stream)
- ftello64,
- /// int ftrylockfile(FILE *file);
- ftrylockfile,
- /// void funlockfile(FILE *file);
- funlockfile,
- /// size_t fwrite(const void *ptr, size_t size, size_t nitems,
- /// FILE *stream);
- fwrite,
- /// int getc(FILE *stream);
- getc,
- /// int getc_unlocked(FILE *stream);
- getc_unlocked,
- /// int getchar(void);
- getchar,
- /// char *getenv(const char *name);
- getenv,
- /// int getitimer(int which, struct itimerval *value);
- getitimer,
- /// int getlogin_r(char *name, size_t namesize);
- getlogin_r,
- /// struct passwd *getpwnam(const char *name);
- getpwnam,
- /// char *gets(char *s);
- gets,
- /// int gettimeofday(struct timeval *tp, void *tzp);
- gettimeofday,
- /// uint32_t htonl(uint32_t hostlong);
- htonl,
- /// uint16_t htons(uint16_t hostshort);
- htons,
- /// int iprintf(const char *format, ...);
- iprintf,
- /// int isascii(int c);
- isascii,
- /// int isdigit(int c);
- isdigit,
- /// long int labs(long int j);
- labs,
- /// int lchown(const char *path, uid_t owner, gid_t group);
- lchown,
- /// double ldexp(double x, int n);
- ldexp,
- /// float ldexpf(float x, int n);
- ldexpf,
- /// long double ldexpl(long double x, int n);
- ldexpl,
- /// long long int llabs(long long int j);
- llabs,
- /// double log(double x);
- log,
- /// double log10(double x);
- log10,
- /// float log10f(float x);
- log10f,
- /// long double log10l(long double x);
- log10l,
- /// double log1p(double x);
- log1p,
- /// float log1pf(float x);
- log1pf,
- /// long double log1pl(long double x);
- log1pl,
- /// double log2(double x);
- log2,
- /// float log2f(float x);
- log2f,
- /// double long double log2l(long double x);
- log2l,
- /// double logb(double x);
- logb,
- /// float logbf(float x);
- logbf,
- /// long double logbl(long double x);
- logbl,
- /// float logf(float x);
- logf,
- /// long double logl(long double x);
- logl,
- /// int lstat(const char *path, struct stat *buf);
- lstat,
- /// int lstat64(const char *path, struct stat64 *buf);
- lstat64,
- /// void *malloc(size_t size);
- malloc,
- /// void *memalign(size_t boundary, size_t size);
- memalign,
- /// void *memccpy(void *s1, const void *s2, int c, size_t n);
- memccpy,
- /// void *memchr(const void *s, int c, size_t n);
- memchr,
- /// int memcmp(const void *s1, const void *s2, size_t n);
- memcmp,
- /// void *memcpy(void *s1, const void *s2, size_t n);
- memcpy,
- /// void *memmove(void *s1, const void *s2, size_t n);
- memmove,
- // void *memrchr(const void *s, int c, size_t n);
- memrchr,
- /// void *memset(void *b, int c, size_t len);
- memset,
- /// void memset_pattern16(void *b, const void *pattern16, size_t len);
- memset_pattern16,
- /// int mkdir(const char *path, mode_t mode);
- mkdir,
- /// time_t mktime(struct tm *timeptr);
- mktime,
- /// double modf(double x, double *iptr);
- modf,
- /// float modff(float, float *iptr);
- modff,
- /// long double modfl(long double value, long double *iptr);
- modfl,
- /// double nearbyint(double x);
- nearbyint,
- /// float nearbyintf(float x);
- nearbyintf,
- /// long double nearbyintl(long double x);
- nearbyintl,
- /// uint32_t ntohl(uint32_t netlong);
- ntohl,
- /// uint16_t ntohs(uint16_t netshort);
- ntohs,
- /// int open(const char *path, int oflag, ... );
- open,
- /// int open64(const char *filename, int flags[, mode_t mode])
- open64,
- /// DIR *opendir(const char *dirname);
- opendir,
- /// int pclose(FILE *stream);
- pclose,
- /// void perror(const char *s);
- perror,
- /// FILE *popen(const char *command, const char *mode);
- popen,
- /// int posix_memalign(void **memptr, size_t alignment, size_t size);
- posix_memalign,
- /// double pow(double x, double y);
- pow,
- /// float powf(float x, float y);
- powf,
- /// long double powl(long double x, long double y);
- powl,
- /// ssize_t pread(int fildes, void *buf, size_t nbyte, off_t offset);
- pread,
- /// int printf(const char *format, ...);
- printf,
- /// int putc(int c, FILE *stream);
- putc,
- /// int putchar(int c);
- putchar,
- /// int puts(const char *s);
- puts,
- /// ssize_t pwrite(int fildes, const void *buf, size_t nbyte,
- /// off_t offset);
- pwrite,
- /// void qsort(void *base, size_t nel, size_t width,
- /// int (*compar)(const void *, const void *));
- qsort,
- /// ssize_t read(int fildes, void *buf, size_t nbyte);
- read,
- /// ssize_t readlink(const char *path, char *buf, size_t bufsize);
- readlink,
- /// void *realloc(void *ptr, size_t size);
- realloc,
- /// void *reallocf(void *ptr, size_t size);
- reallocf,
- /// char *realpath(const char *file_name, char *resolved_name);
- realpath,
- /// int remove(const char *path);
- remove,
- /// int rename(const char *old, const char *new);
- rename,
- /// void rewind(FILE *stream);
- rewind,
- /// double rint(double x);
- rint,
- /// float rintf(float x);
- rintf,
- /// long double rintl(long double x);
- rintl,
- /// int rmdir(const char *path);
- rmdir,
- /// double round(double x);
- round,
- /// float roundf(float x);
- roundf,
- /// long double roundl(long double x);
- roundl,
- /// int scanf(const char *restrict format, ... );
- scanf,
- /// void setbuf(FILE *stream, char *buf);
- setbuf,
- /// int setitimer(int which, const struct itimerval *value,
- /// struct itimerval *ovalue);
- setitimer,
- /// int setvbuf(FILE *stream, char *buf, int type, size_t size);
- setvbuf,
- /// double sin(double x);
- sin,
- /// float sinf(float x);
- sinf,
- /// double sinh(double x);
- sinh,
- /// float sinhf(float x);
- sinhf,
- /// long double sinhl(long double x);
- sinhl,
- /// long double sinl(long double x);
- sinl,
- /// int siprintf(char *str, const char *format, ...);
- siprintf,
- /// int snprintf(char *s, size_t n, const char *format, ...);
- snprintf,
- /// int sprintf(char *str, const char *format, ...);
- sprintf,
- /// double sqrt(double x);
- sqrt,
- /// float sqrtf(float x);
- sqrtf,
- /// long double sqrtl(long double x);
- sqrtl,
- /// int sscanf(const char *s, const char *format, ... );
- sscanf,
- /// int stat(const char *path, struct stat *buf);
- stat,
- /// int stat64(const char *path, struct stat64 *buf);
- stat64,
- /// int statvfs(const char *path, struct statvfs *buf);
- statvfs,
- /// int statvfs64(const char *path, struct statvfs64 *buf)
- statvfs64,
- /// char *stpcpy(char *s1, const char *s2);
- stpcpy,
- /// char *stpncpy(char *s1, const char *s2, size_t n);
- stpncpy,
- /// int strcasecmp(const char *s1, const char *s2);
- strcasecmp,
- /// char *strcat(char *s1, const char *s2);
- strcat,
- /// char *strchr(const char *s, int c);
- strchr,
- /// int strcmp(const char *s1, const char *s2);
- strcmp,
- /// int strcoll(const char *s1, const char *s2);
- strcoll,
- /// char *strcpy(char *s1, const char *s2);
- strcpy,
- /// size_t strcspn(const char *s1, const char *s2);
- strcspn,
- /// char *strdup(const char *s1);
- strdup,
- /// size_t strlen(const char *s);
- strlen,
- /// int strncasecmp(const char *s1, const char *s2, size_t n);
- strncasecmp,
- /// char *strncat(char *s1, const char *s2, size_t n);
- strncat,
- /// int strncmp(const char *s1, const char *s2, size_t n);
- strncmp,
- /// char *strncpy(char *s1, const char *s2, size_t n);
- strncpy,
- /// char *strndup(const char *s1, size_t n);
- strndup,
- /// size_t strnlen(const char *s, size_t maxlen);
- strnlen,
- /// char *strpbrk(const char *s1, const char *s2);
- strpbrk,
- /// char *strrchr(const char *s, int c);
- strrchr,
- /// size_t strspn(const char *s1, const char *s2);
- strspn,
- /// char *strstr(const char *s1, const char *s2);
- strstr,
- /// double strtod(const char *nptr, char **endptr);
- strtod,
- /// float strtof(const char *nptr, char **endptr);
- strtof,
- // char *strtok(char *s1, const char *s2);
- strtok,
- // char *strtok_r(char *s, const char *sep, char **lasts);
- strtok_r,
- /// long int strtol(const char *nptr, char **endptr, int base);
- strtol,
- /// long double strtold(const char *nptr, char **endptr);
- strtold,
- /// long long int strtoll(const char *nptr, char **endptr, int base);
- strtoll,
- /// unsigned long int strtoul(const char *nptr, char **endptr, int base);
- strtoul,
- /// unsigned long long int strtoull(const char *nptr, char **endptr,
- /// int base);
- strtoull,
- /// size_t strxfrm(char *s1, const char *s2, size_t n);
- strxfrm,
- /// int system(const char *command);
- system,
- /// double tan(double x);
- tan,
- /// float tanf(float x);
- tanf,
- /// double tanh(double x);
- tanh,
- /// float tanhf(float x);
- tanhf,
- /// long double tanhl(long double x);
- tanhl,
- /// long double tanl(long double x);
- tanl,
- /// clock_t times(struct tms *buffer);
- times,
- /// FILE *tmpfile(void);
- tmpfile,
- /// FILE *tmpfile64(void)
- tmpfile64,
- /// int toascii(int c);
- toascii,
- /// double trunc(double x);
- trunc,
- /// float truncf(float x);
- truncf,
- /// long double truncl(long double x);
- truncl,
- /// int uname(struct utsname *name);
- uname,
- /// int ungetc(int c, FILE *stream);
- ungetc,
- /// int unlink(const char *path);
- unlink,
- /// int unsetenv(const char *name);
- unsetenv,
- /// int utime(const char *path, const struct utimbuf *times);
- utime,
- /// int utimes(const char *path, const struct timeval times[2]);
- utimes,
- /// void *valloc(size_t size);
- valloc,
- /// int vfprintf(FILE *stream, const char *format, va_list ap);
- vfprintf,
- /// int vfscanf(FILE *stream, const char *format, va_list arg);
- vfscanf,
- /// int vprintf(const char *restrict format, va_list ap);
- vprintf,
- /// int vscanf(const char *format, va_list arg);
- vscanf,
- /// int vsnprintf(char *s, size_t n, const char *format, va_list ap);
- vsnprintf,
- /// int vsprintf(char *s, const char *format, va_list ap);
- vsprintf,
- /// int vsscanf(const char *s, const char *format, va_list arg);
- vsscanf,
- /// ssize_t write(int fildes, const void *buf, size_t nbyte);
- write,
+#define TLI_DEFINE_ENUM
+#include "llvm/Analysis/TargetLibraryInfo.def"
NumLibFuncs
};
@@ -718,7 +60,7 @@ class TargetLibraryInfoImpl {
unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4];
llvm::DenseMap<unsigned, std::string> CustomNames;
- static const char* StandardNames[LibFunc::NumLibFuncs];
+ static const char *const StandardNames[LibFunc::NumLibFuncs];
enum AvailabilityState {
StandardName = 3, // (memset to all ones)
@@ -733,7 +75,25 @@ class TargetLibraryInfoImpl {
return static_cast<AvailabilityState>((AvailableArray[F/4] >> 2*(F&3)) & 3);
}
+ /// Vectorization descriptors - sorted by ScalarFnName.
+ std::vector<VecDesc> VectorDescs;
+ /// Scalarization descriptors - same content as VectorDescs but sorted based
+ /// on VectorFnName rather than ScalarFnName.
+ std::vector<VecDesc> ScalarDescs;
+
public:
+ /// \brief List of known vector-functions libraries.
+ ///
+ /// The vector-functions library defines, which functions are vectorizable
+ /// and with which factor. The library can be specified by either frontend,
+ /// or a commandline option, and then used by
+ /// addVectorizableFunctionsFromVecLib for filling up the tables of
+ /// vectorizable functions.
+ enum VectorLibrary {
+ NoLibrary, // Don't use any vector library.
+ Accelerate // Use Accelerate framework.
+ };
+
TargetLibraryInfoImpl();
explicit TargetLibraryInfoImpl(const Triple &T);
@@ -775,6 +135,41 @@ public:
///
/// This can be used for options like -fno-builtin.
void disableAllFunctions();
+
+ /// addVectorizableFunctions - Add a set of scalar -> vector mappings,
+ /// queryable via getVectorizedFunction and getScalarizedFunction.
+ void addVectorizableFunctions(ArrayRef<VecDesc> Fns);
+
+ /// Calls addVectorizableFunctions with a known preset of functions for the
+ /// given vector library.
+ void addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib);
+
+ /// isFunctionVectorizable - Return true if the function F has a
+ /// vector equivalent with vectorization factor VF.
+ bool isFunctionVectorizable(StringRef F, unsigned VF) const {
+ return !getVectorizedFunction(F, VF).empty();
+ }
+
+ /// isFunctionVectorizable - Return true if the function F has a
+ /// vector equivalent with any vectorization factor.
+ bool isFunctionVectorizable(StringRef F) const;
+
+ /// getVectorizedFunction - Return the name of the equivalent of
+ /// F, vectorized with factor VF. If no such mapping exists,
+ /// return the empty string.
+ StringRef getVectorizedFunction(StringRef F, unsigned VF) const;
+
+ /// isFunctionScalarizable - Return true if the function F has a
+ /// scalar equivalent, and set VF to be the vectorization factor.
+ bool isFunctionScalarizable(StringRef F, unsigned &VF) const {
+ return !getScalarizedFunction(F, VF).empty();
+ }
+
+ /// getScalarizedFunction - Return the name of the equivalent of
+ /// F, scalarized. If no such mapping exists, return the empty string.
+ ///
+ /// Set VF to the vectorization factor.
+ StringRef getScalarizedFunction(StringRef F, unsigned &VF) const;
};
/// \brief Provides information about what library functions are available for
@@ -811,10 +206,19 @@ public:
return Impl->getLibFunc(funcName, F);
}
- /// \brief Tests wether a library function is available.
+ /// \brief Tests whether a library function is available.
bool has(LibFunc::Func F) const {
return Impl->getState(F) != TargetLibraryInfoImpl::Unavailable;
}
+ bool isFunctionVectorizable(StringRef F, unsigned VF) const {
+ return Impl->isFunctionVectorizable(F, VF);
+ };
+ bool isFunctionVectorizable(StringRef F) const {
+ return Impl->isFunctionVectorizable(F);
+ };
+ StringRef getVectorizedFunction(StringRef F, unsigned VF) const {
+ return Impl->getVectorizedFunction(F, VF);
+ };
/// \brief Tests if the function is both available and a candidate for
/// optimized code generation.
diff --git a/include/llvm/Analysis/TargetTransformInfo.h b/include/llvm/Analysis/TargetTransformInfo.h
index 4998141..fdb2010 100644
--- a/include/llvm/Analysis/TargetTransformInfo.h
+++ b/include/llvm/Analysis/TargetTransformInfo.h
@@ -27,6 +27,7 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/Pass.h"
#include "llvm/Support/DataTypes.h"
+#include <functional>
namespace llvm {
@@ -330,6 +331,9 @@ public:
/// target.
bool shouldBuildLookupTables() const;
+ /// \brief Don't restrict interleaved unrolling to small loops.
+ bool enableAggressiveInterleaving(bool LoopHasReductions) const;
+
/// \brief Return hardware support for population count.
PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const;
@@ -448,6 +452,10 @@ public:
unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
ArrayRef<Type *> Tys) const;
+ /// \returns The cost of Call instructions.
+ unsigned getCallInstrCost(Function *F, Type *RetTy,
+ ArrayRef<Type *> Tys) const;
+
/// \returns The number of pieces into which the provided type must be
/// split during legalization. Zero is returned when the answer is unknown.
unsigned getNumberOfParts(Type *Tp) const;
@@ -530,6 +538,7 @@ public:
virtual unsigned getJumpBufAlignment() = 0;
virtual unsigned getJumpBufSize() = 0;
virtual bool shouldBuildLookupTables() = 0;
+ virtual bool enableAggressiveInterleaving(bool LoopHasReductions) = 0;
virtual PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) = 0;
virtual bool haveFastSqrt(Type *Ty) = 0;
virtual unsigned getFPOpCost(Type *Ty) = 0;
@@ -564,6 +573,8 @@ public:
bool IsPairwiseForm) = 0;
virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
ArrayRef<Type *> Tys) = 0;
+ virtual unsigned getCallInstrCost(Function *F, Type *RetTy,
+ ArrayRef<Type *> Tys) = 0;
virtual unsigned getNumberOfParts(Type *Tp) = 0;
virtual unsigned getAddressComputationCost(Type *Ty, bool IsComplex) = 0;
virtual unsigned getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) = 0;
@@ -647,6 +658,9 @@ public:
bool shouldBuildLookupTables() override {
return Impl.shouldBuildLookupTables();
}
+ bool enableAggressiveInterleaving(bool LoopHasReductions) override {
+ return Impl.enableAggressiveInterleaving(LoopHasReductions);
+ }
PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) override {
return Impl.getPopcntSupport(IntTyWidthInBit);
}
@@ -718,6 +732,10 @@ public:
ArrayRef<Type *> Tys) override {
return Impl.getIntrinsicInstrCost(ID, RetTy, Tys);
}
+ unsigned getCallInstrCost(Function *F, Type *RetTy,
+ ArrayRef<Type *> Tys) override {
+ return Impl.getCallInstrCost(F, RetTy, Tys);
+ }
unsigned getNumberOfParts(Type *Tp) override {
return Impl.getNumberOfParts(Tp);
}
diff --git a/include/llvm/Analysis/TargetTransformInfoImpl.h b/include/llvm/Analysis/TargetTransformInfoImpl.h
index 3e02c0c..f4bf07f 100644
--- a/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -235,6 +235,8 @@ public:
bool shouldBuildLookupTables() { return true; }
+ bool enableAggressiveInterleaving(bool LoopHasReductions) { return false; }
+
TTI::PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) {
return TTI::PSK_Software;
}
@@ -301,6 +303,10 @@ public:
return 1;
}
+ unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) {
+ return 1;
+ }
+
unsigned getNumberOfParts(Type *Tp) { return 0; }
unsigned getAddressComputationCost(Type *Tp, bool) { return 0; }
diff --git a/include/llvm/Analysis/ValueTracking.h b/include/llvm/Analysis/ValueTracking.h
index ac8c3b7..8955b7c 100644
--- a/include/llvm/Analysis/ValueTracking.h
+++ b/include/llvm/Analysis/ValueTracking.h
@@ -33,12 +33,12 @@ namespace llvm {
/// them in the KnownZero/KnownOne bit sets.
///
/// This function is defined on values with integer type, values with pointer
- /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// type, and vectors of integers. In the case
/// where V is a vector, the known zero and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
void computeKnownBits(Value *V, APInt &KnownZero, APInt &KnownOne,
- const DataLayout *TD = nullptr, unsigned Depth = 0,
+ const DataLayout &DL, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -50,7 +50,7 @@ namespace llvm {
/// ComputeSignBit - Determine whether the sign bit is known to be zero or
/// one. Convenience wrapper around computeKnownBits.
void ComputeSignBit(Value *V, bool &KnownZero, bool &KnownOne,
- const DataLayout *TD = nullptr, unsigned Depth = 0,
+ const DataLayout &DL, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -60,7 +60,8 @@ namespace llvm {
/// element is known to be a power of two when defined. Supports values with
/// integer or pointer type and vectors of integers. If 'OrZero' is set then
/// returns true if the given value is either a power of two or zero.
- bool isKnownToBeAPowerOfTwo(Value *V, bool OrZero = false, unsigned Depth = 0,
+ bool isKnownToBeAPowerOfTwo(Value *V, const DataLayout &DL,
+ bool OrZero = false, unsigned Depth = 0,
AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -69,8 +70,8 @@ namespace llvm {
/// when defined. For vectors return true if every element is known to be
/// non-zero when defined. Supports values with integer or pointer type and
/// vectors of integers.
- bool isKnownNonZero(Value *V, const DataLayout *TD = nullptr,
- unsigned Depth = 0, AssumptionCache *AC = nullptr,
+ bool isKnownNonZero(Value *V, const DataLayout &DL, unsigned Depth = 0,
+ AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -79,13 +80,12 @@ namespace llvm {
/// zero for bits that V cannot have.
///
/// This function is defined on values with integer type, values with pointer
- /// type (but only if TD is non-null), and vectors of integers. In the case
+ /// type, and vectors of integers. In the case
/// where V is a vector, the mask, known zero, and known one values are the
/// same width as the vector element, and the bit is set only if it is true
/// for all of the elements in the vector.
- bool MaskedValueIsZero(Value *V, const APInt &Mask,
- const DataLayout *TD = nullptr, unsigned Depth = 0,
- AssumptionCache *AC = nullptr,
+ bool MaskedValueIsZero(Value *V, const APInt &Mask, const DataLayout &DL,
+ unsigned Depth = 0, AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -97,7 +97,7 @@ namespace llvm {
///
/// 'Op' must have a scalar integer type.
///
- unsigned ComputeNumSignBits(Value *Op, const DataLayout *TD = nullptr,
+ unsigned ComputeNumSignBits(Value *Op, const DataLayout &DL,
unsigned Depth = 0, AssumptionCache *AC = nullptr,
const Instruction *CxtI = nullptr,
const DominatorTree *DT = nullptr);
@@ -142,11 +142,12 @@ 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 &DL);
static inline const Value *
GetPointerBaseWithConstantOffset(const Value *Ptr, int64_t &Offset,
- const DataLayout *TD) {
- return GetPointerBaseWithConstantOffset(const_cast<Value*>(Ptr), Offset,TD);
+ const DataLayout &DL) {
+ return GetPointerBaseWithConstantOffset(const_cast<Value *>(Ptr), Offset,
+ DL);
}
/// getConstantStringInfo - This function computes the length of a
@@ -167,21 +168,19 @@ namespace llvm {
/// being addressed. Note that the returned value has pointer type if the
/// specified value does. If the MaxLookup value is non-zero, it limits the
/// number of instructions to be stripped off.
- Value *GetUnderlyingObject(Value *V, const DataLayout *TD = nullptr,
+ Value *GetUnderlyingObject(Value *V, const DataLayout &DL,
unsigned MaxLookup = 6);
- static inline const Value *
- GetUnderlyingObject(const Value *V, const DataLayout *TD = nullptr,
- unsigned MaxLookup = 6) {
- return GetUnderlyingObject(const_cast<Value *>(V), TD, MaxLookup);
+ static inline const Value *GetUnderlyingObject(const Value *V,
+ const DataLayout &DL,
+ unsigned MaxLookup = 6) {
+ return GetUnderlyingObject(const_cast<Value *>(V), DL, MaxLookup);
}
/// GetUnderlyingObjects - This method is similar to GetUnderlyingObject
/// except that it can look through phi and select instructions and return
/// multiple objects.
- void GetUnderlyingObjects(Value *V,
- SmallVectorImpl<Value *> &Objects,
- const DataLayout *TD = nullptr,
- unsigned MaxLookup = 6);
+ void GetUnderlyingObjects(Value *V, SmallVectorImpl<Value *> &Objects,
+ const DataLayout &DL, unsigned MaxLookup = 6);
/// onlyUsedByLifetimeMarkers - Return true if the only users of this pointer
/// are lifetime markers.
@@ -205,8 +204,7 @@ namespace llvm {
/// the correct dominance relationships for the operands and users hold.
/// However, this method can return true for instructions that read memory;
/// for such instructions, moving them may change the resulting value.
- bool isSafeToSpeculativelyExecute(const Value *V,
- const DataLayout *TD = nullptr);
+ bool isSafeToSpeculativelyExecute(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
@@ -217,17 +215,16 @@ namespace llvm {
/// assume intrinsic, I, at the point in the control-flow identified by the
/// context instruction, CxtI.
bool isValidAssumeForContext(const Instruction *I, const Instruction *CxtI,
- const DataLayout *DL = nullptr,
const DominatorTree *DT = nullptr);
enum class OverflowResult { AlwaysOverflows, MayOverflow, NeverOverflows };
OverflowResult computeOverflowForUnsignedMul(Value *LHS, Value *RHS,
- const DataLayout *DL,
+ const DataLayout &DL,
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT);
OverflowResult computeOverflowForUnsignedAdd(Value *LHS, Value *RHS,
- const DataLayout *DL,
+ const DataLayout &DL,
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT);
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
index c20a160..18f6b9e 100644
--- a/include/llvm/Bitcode/BitstreamReader.h
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -24,8 +24,6 @@
namespace llvm {
-class Deserializer;
-
/// 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
@@ -164,7 +162,6 @@ struct BitstreamEntry {
/// Unlike iterators, BitstreamCursors are heavy-weight objects that should not
/// be passed by value.
class BitstreamCursor {
- friend class Deserializer;
BitstreamReader *BitStream;
size_t NextChar;
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
index 48bdabc..254949d 100644
--- a/include/llvm/Bitcode/ReaderWriter.h
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -29,12 +29,14 @@ namespace llvm {
class raw_ostream;
/// Read the header of the specified bitcode buffer and prepare for lazy
- /// deserialization of function bodies. If successful, this moves Buffer. On
+ /// deserialization of function bodies. If ShouldLazyLoadMetadata is true,
+ /// lazily load metadata as well. If successful, this moves Buffer. On
/// error, this *does not* move Buffer.
ErrorOr<Module *>
getLazyBitcodeModule(std::unique_ptr<MemoryBuffer> &&Buffer,
LLVMContext &Context,
- DiagnosticHandlerFunction DiagnosticHandler = nullptr);
+ DiagnosticHandlerFunction DiagnosticHandler = nullptr,
+ bool ShouldLazyLoadMetadata = false);
/// Read the header of the specified stream and prepare for lazy
/// deserialization and streaming of function bodies.
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index ac224d8..d364012 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -16,6 +16,7 @@
#ifndef LLVM_CODEGEN_ASMPRINTER_H
#define LLVM_CODEGEN_ASMPRINTER_H
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/IR/InlineAsm.h"
@@ -29,6 +30,8 @@ class ByteStreamer;
class GCStrategy;
class Constant;
class ConstantArray;
+class DIE;
+class DIEAbbrev;
class GCMetadataPrinter;
class GlobalValue;
class GlobalVariable;
@@ -100,9 +103,13 @@ public:
/// Map global GOT equivalent MCSymbols to GlobalVariables and keep track of
/// its number of uses by other globals.
typedef std::pair<const GlobalVariable *, unsigned> GOTEquivUsePair;
- DenseMap<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
+ MapVector<const MCSymbol *, GOTEquivUsePair> GlobalGOTEquivs;
private:
+ MCSymbol *CurrentFnBegin;
+ MCSymbol *CurrentFnEnd;
+ MCSymbol *CurExceptionSym;
+
// The garbage collection metadata printer table.
void *GCMetadataPrinters; // Really a DenseMap.
@@ -146,6 +153,10 @@ public:
///
unsigned getFunctionNumber() const;
+ MCSymbol *getFunctionBegin() const { return CurrentFnBegin; }
+ MCSymbol *getFunctionEnd() const { return CurrentFnEnd; }
+ MCSymbol *getCurExceptionSym();
+
/// Return information about object file lowering.
const TargetLoweringObjectFile &getObjFileLowering() const;
@@ -187,7 +198,6 @@ public:
/// Emit the specified function out to the OutStreamer.
bool runOnMachineFunction(MachineFunction &MF) override {
SetupMachineFunction(MF);
- EmitFunctionHeader();
EmitFunctionBody();
return false;
}
@@ -200,9 +210,6 @@ public:
/// runOnMachineFunction.
void SetupMachineFunction(MachineFunction &MF);
- /// This method emits the header for the current function.
- void EmitFunctionHeader();
-
/// This method emits the body and trailer for a function.
void EmitFunctionBody();
@@ -324,12 +331,7 @@ public:
// Symbol Lowering Routines.
//===------------------------------------------------------------------===//
public:
- /// Return the MCSymbol corresponding to the assembler temporary label with
- /// the specified stem and unique ID.
- MCSymbol *GetTempSymbol(const Twine &Name, unsigned ID) const;
-
- /// Return an assembler temporary label with the specified stem.
- MCSymbol *GetTempSymbol(const Twine &Name) const;
+ MCSymbol *createTempSymbol(const Twine &Name) const;
/// Return the MCSymbol for a private symbol with global value name as its
/// base, with the specified suffix.
@@ -417,37 +419,10 @@ public:
/// Emit the 4-byte offset of Label from the start of its section. This can
/// be done with a special directive if the target supports it (e.g. cygwin)
/// or by emitting it as an offset from a label at the start of the section.
- ///
- /// SectionLabel is a temporary label emitted at the start of the section
- /// that Label lives in.
- void EmitSectionOffset(const MCSymbol *Label,
- const MCSymbol *SectionLabel) const;
+ void emitSectionOffset(const MCSymbol *Label) const;
/// Get the value for DW_AT_APPLE_isa. Zero if no isa encoding specified.
- virtual unsigned getISAEncoding(const Function *) { return 0; }
-
- /// Emit a dwarf register operation for describing
- /// - a small value occupying only part of a register or
- /// - a register representing only part of a value.
- void EmitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits,
- unsigned OffsetInBits = 0) const;
-
-
- /// \brief Emit a partial DWARF register operation.
- /// \param MLoc the register
- /// \param PieceSize size and
- /// \param PieceOffset offset of the piece in bits, if this is one
- /// piece of an aggregate value.
- ///
- /// If size and offset is zero an operation for the entire
- /// register is emitted: Some targets do not provide a DWARF
- /// register number for every register. If this is the case, this
- /// function will attempt to emit a DWARF register by emitting a
- /// piece of a super-register or by piecing together multiple
- /// subregisters that alias the register.
- void EmitDwarfRegOpPiece(ByteStreamer &BS, const MachineLocation &MLoc,
- unsigned PieceSize = 0,
- unsigned PieceOffset = 0) const;
+ virtual unsigned getISAEncoding() { return 0; }
/// EmitDwarfRegOp - Emit a dwarf register operation.
virtual void EmitDwarfRegOp(ByteStreamer &BS,
@@ -460,6 +435,12 @@ public:
/// \brief Emit frame instruction to describe the layout of the frame.
void emitCFIInstruction(const MCCFIInstruction &Inst) const;
+ /// \brief Emit Dwarf abbreviation table.
+ void emitDwarfAbbrevs(const std::vector<DIEAbbrev *>& Abbrevs) const;
+
+ /// \brief Recursively emit Dwarf DIE tree.
+ void emitDwarfDIE(const DIE &Die) const;
+
//===------------------------------------------------------------------===//
// Inline Asm Support
//===------------------------------------------------------------------===//
@@ -510,11 +491,14 @@ private:
mutable const MachineInstr *LastMI;
mutable unsigned LastFn;
mutable unsigned Counter;
- mutable unsigned SetCounter;
+
+ /// This method emits the header for the current function.
+ void EmitFunctionHeader();
/// Emit a blob of inline asm to the output streamer.
void
- EmitInlineAsm(StringRef Str, const MDNode *LocMDNode = nullptr,
+ EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
+ const MDNode *LocMDNode = nullptr,
InlineAsm::AsmDialect AsmDialect = InlineAsm::AD_ATT) const;
/// This method formats and emits the specified machine instruction that is an
diff --git a/include/llvm/CodeGen/BasicTTIImpl.h b/include/llvm/CodeGen/BasicTTIImpl.h
index ff85b06..e1e5112 100644
--- a/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/include/llvm/CodeGen/BasicTTIImpl.h
@@ -21,6 +21,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
namespace llvm {
@@ -527,18 +528,29 @@ public:
// Assume that we need to scalarize this intrinsic.
unsigned ScalarizationCost = 0;
unsigned ScalarCalls = 1;
+ Type *ScalarRetTy = RetTy;
if (RetTy->isVectorTy()) {
ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
+ ScalarRetTy = RetTy->getScalarType();
}
+ SmallVector<Type *, 4> ScalarTys;
for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
- if (Tys[i]->isVectorTy()) {
- ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
- ScalarCalls = std::max(ScalarCalls, RetTy->getVectorNumElements());
+ Type *Ty = Tys[i];
+ if (Ty->isVectorTy()) {
+ ScalarizationCost += getScalarizationOverhead(Ty, false, true);
+ ScalarCalls = std::max(ScalarCalls, Ty->getVectorNumElements());
+ Ty = Ty->getScalarType();
}
+ ScalarTys.push_back(Ty);
}
+ if (ScalarCalls == 1)
+ return 1; // Return cost of a scalar intrinsic. Assume it to be cheap.
- return ScalarCalls + ScalarizationCost;
+ unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost(
+ IID, ScalarRetTy, ScalarTys);
+
+ return ScalarCalls * ScalarCost + ScalarizationCost;
}
// Look for intrinsics that can be lowered directly or turned into a scalar
// intrinsic call.
@@ -648,16 +660,46 @@ public:
// this will emit a costly libcall, adding call overhead and spills. Make it
// very expensive.
if (RetTy->isVectorTy()) {
- unsigned Num = RetTy->getVectorNumElements();
- unsigned Cost = static_cast<T *>(this)->getIntrinsicInstrCost(
- IID, RetTy->getScalarType(), Tys);
- return 10 * Cost * Num;
+ unsigned ScalarizationCost = getScalarizationOverhead(RetTy, true, false);
+ unsigned ScalarCalls = RetTy->getVectorNumElements();
+ SmallVector<Type *, 4> ScalarTys;
+ for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
+ Type *Ty = Tys[i];
+ if (Ty->isVectorTy())
+ Ty = Ty->getScalarType();
+ ScalarTys.push_back(Ty);
+ }
+ unsigned ScalarCost = static_cast<T *>(this)->getIntrinsicInstrCost(
+ IID, RetTy->getScalarType(), ScalarTys);
+ for (unsigned i = 0, ie = Tys.size(); i != ie; ++i) {
+ if (Tys[i]->isVectorTy()) {
+ ScalarizationCost += getScalarizationOverhead(Tys[i], false, true);
+ ScalarCalls = std::max(ScalarCalls, Tys[i]->getVectorNumElements());
+ }
+ }
+
+ return ScalarCalls * ScalarCost + ScalarizationCost;
}
// This is going to be turned into a library call, make it expensive.
return 10;
}
+ /// \brief Compute a cost of the given call instruction.
+ ///
+ /// Compute the cost of calling function F with return type RetTy and
+ /// argument types Tys. F might be nullptr, in this case the cost of an
+ /// arbitrary call with the specified signature will be returned.
+ /// This is used, for instance, when we estimate call of a vector
+ /// counterpart of the given function.
+ /// \param F Called function, might be nullptr.
+ /// \param RetTy Return value types.
+ /// \param Tys Argument types.
+ /// \returns The cost of Call instruction.
+ unsigned getCallInstrCost(Function *F, Type *RetTy, ArrayRef<Type *> Tys) {
+ return 10;
+ }
+
unsigned getNumberOfParts(Type *Tp) {
std::pair<unsigned, MVT> LT = getTLI()->getTypeLegalizationCost(Tp);
return LT.first;
diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h
index e310aef..7803898 100644
--- a/include/llvm/CodeGen/DIE.h
+++ b/include/llvm/CodeGen/DIE.h
@@ -95,7 +95,7 @@ public:
/// Emit - Print the abbreviation using the specified asm printer.
///
- void Emit(AsmPrinter *AP) const;
+ void Emit(const AsmPrinter *AP) const;
#ifndef NDEBUG
void print(raw_ostream &O);
@@ -230,11 +230,11 @@ public:
/// EmitValue - Emit value via the Dwarf writer.
///
- virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const = 0;
+ virtual void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
- virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const = 0;
+ virtual unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const = 0;
#ifndef NDEBUG
virtual void print(raw_ostream &O) const = 0;
@@ -275,13 +275,14 @@ public:
/// EmitValue - Emit integer of appropriate size.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
uint64_t getValue() const { return Integer; }
+ void setValue(uint64_t Val) { Integer = Val; }
/// SizeOf - Determine size of integer value in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
@@ -302,7 +303,7 @@ public:
/// EmitValue - Emit expression value.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// getValue - Get MCExpr.
///
@@ -310,7 +311,7 @@ public:
/// SizeOf - Determine size of expression value in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isExpr; }
@@ -331,7 +332,7 @@ public:
/// EmitValue - Emit label value.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// getValue - Get MCSymbol.
///
@@ -339,7 +340,7 @@ public:
/// SizeOf - Determine size of label value in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
@@ -362,11 +363,11 @@ public:
/// EmitValue - Emit delta value.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of delta value in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
@@ -392,11 +393,11 @@ public:
/// EmitValue - Emit delta value.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of delta value in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *D) { return D->getType() == isString; }
@@ -421,17 +422,17 @@ public:
/// EmitValue - Emit debug information entry offset.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of debug information entry in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override {
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override {
return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP)
: sizeof(int32_t);
}
/// Returns size of a ref_addr entry.
- static unsigned getRefAddrSize(AsmPrinter *AP);
+ static unsigned getRefAddrSize(const AsmPrinter *AP);
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
@@ -451,10 +452,10 @@ public:
: DIEValue(isTypeSignature), Unit(Unit) {}
/// \brief Emit type unit signature.
- void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const override;
/// Returns size of a ref_sig8 entry.
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override {
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override {
assert(Form == dwarf::DW_FORM_ref_sig8);
return 8;
}
@@ -479,7 +480,7 @@ public:
/// ComputeSize - Calculate the size of the location expression.
///
- unsigned ComputeSize(AsmPrinter *AP) const;
+ unsigned ComputeSize(const AsmPrinter *AP) const;
/// BestForm - Choose the best form for data.
///
@@ -498,11 +499,11 @@ public:
/// EmitValue - Emit location data.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
@@ -522,7 +523,7 @@ public:
/// ComputeSize - Calculate the size of the location expression.
///
- unsigned ComputeSize(AsmPrinter *AP) const;
+ unsigned ComputeSize(const AsmPrinter *AP) const;
/// BestForm - Choose the best form for data.
///
@@ -538,11 +539,11 @@ public:
/// EmitValue - Emit location data.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
@@ -568,11 +569,11 @@ public:
/// EmitValue - Emit location data.
///
- void EmitValue(AsmPrinter *AP, dwarf::Form Form) const override;
+ void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const override;
/// SizeOf - Determine size of location data in bytes.
///
- unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const override;
+ unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const override;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *E) { return E->getType() == isLocList; }
diff --git a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h b/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
deleted file mode 100644
index ec8e2ef..0000000
--- a/include/llvm/CodeGen/ForwardControlFlowIntegrity.h
+++ /dev/null
@@ -1,122 +0,0 @@
-//===-- ForwardControlFlowIntegrity.h: Forward-Edge CFI ---------*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass instruments indirect calls with checks to ensure that these calls
-// pass through the appropriate jump-instruction table generated by
-// JumpInstrTables.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
-#define LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Pass.h"
-#include "llvm/Target/TargetOptions.h"
-#include <string>
-
-namespace llvm {
-
-class AnalysisUsage;
-class BasicBlock;
-class Constant;
-class Function;
-class Instruction;
-class Module;
-class Value;
-
-/// ForwardControlFlowIntegrity uses the information from JumpInstrTableInfo to
-/// prepend checks to indirect calls to make sure that these calls target valid
-/// locations.
-class ForwardControlFlowIntegrity : public ModulePass {
-public:
- static char ID;
-
- ForwardControlFlowIntegrity();
- ForwardControlFlowIntegrity(JumpTable::JumpTableType JTT,
- CFIntegrity CFIType,
- bool CFIEnforcing, std::string CFIFuncName);
- ~ForwardControlFlowIntegrity() override;
-
- /// Runs the CFI pass on a given module. This works best if the module in
- /// question is the result of link-time optimization (see lib/LTO).
- bool runOnModule(Module &M) override;
- const char *getPassName() const override {
- return "Forward Control-Flow Integrity";
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
-private:
- typedef SmallVector<Instruction *, 64> CallSet;
-
- /// A structure that is used to keep track of constant table information.
- struct CFIConstants {
- Constant *StartValue;
- Constant *MaskValue;
- Constant *Size;
- };
-
- /// A map from function type to the base of the table for this type and a mask
- /// for the table
- typedef DenseMap<FunctionType *, CFIConstants> CFITables;
-
- CallSet IndirectCalls;
-
- /// The type of jumptable implementation.
- JumpTable::JumpTableType JTType;
-
- /// The type of CFI check to add before each indirect call.
- CFIntegrity CFIType;
-
- /// A value that controls whether or not CFI violations cause a halt.
- bool CFIEnforcing;
-
- /// The name of the function to call in case of a CFI violation when
- /// CFIEnforcing is false. There is a default function that ignores
- /// violations.
- std::string CFIFuncName;
-
- /// The alignment of each entry in the table, from JumpInstrTableInfo. The
- /// JumpInstrTableInfo class always makes this a power of two.
- uint64_t ByteAlignment;
-
- /// The base-2 logarithm of ByteAlignment, needed for some of the transforms
- /// (like CFIntegrity::Ror)
- unsigned LogByteAlignment;
-
- /// Adds checks to each indirect call site to make sure that it is calling a
- /// function in our jump table.
- void updateIndirectCalls(Module &M, CFITables &CFIT);
-
- /// Walks the instructions to find all the indirect calls.
- void getIndirectCalls(Module &M);
-
- /// Adds a function that handles violations in non-enforcing mode
- /// (!CFIEnforcing). The default warning function simply returns, since the
- /// exact details of how to handle CFI violations depend on the application.
- void addWarningFunction(Module &M);
-
- /// Rewrites a function pointer in a call/invoke instruction to force it into
- /// a table.
- void rewriteFunctionPointer(Module &M, Instruction *I, Value *FunPtr,
- Constant *JumpTableStart, Constant *JumpTableMask,
- Constant *JumpTableSize);
-
- /// Inserts a check and a call to a warning function at a given instruction
- /// that must be an indirect call.
- void insertWarning(Module &M, BasicBlock *Block, Instruction *I,
- Value *FunPtr);
-};
-
-ModulePass *
-createForwardControlFlowIntegrityPass(JumpTable::JumpTableType JTT,
- CFIntegrity CFIType,
- bool CFIEnforcing, StringRef CFIFuncName);
-}
-
-#endif // LLVM_CODEGEN_FORWARDCONTROLFLOWINTEGRITY_H
diff --git a/include/llvm/CodeGen/ISDOpcodes.h b/include/llvm/CodeGen/ISDOpcodes.h
index 8a31f7e..2d1c8cd 100644
--- a/include/llvm/CodeGen/ISDOpcodes.h
+++ b/include/llvm/CodeGen/ISDOpcodes.h
@@ -689,8 +689,6 @@ namespace ISD {
// Masked load and store
MLOAD, MSTORE,
- // Masked gather and scatter
- MGATHER, MSCATTER,
/// This corresponds to the llvm.lifetime.* intrinsics. The first operand
/// is the chain and the second operand is the alloca pointer.
diff --git a/include/llvm/CodeGen/JumpInstrTables.h b/include/llvm/CodeGen/JumpInstrTables.h
deleted file mode 100644
index 005bc1e..0000000
--- a/include/llvm/CodeGen/JumpInstrTables.h
+++ /dev/null
@@ -1,105 +0,0 @@
-//===-- JumpInstrTables.h: Jump-Instruction Tables --------------*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief An implementation of tables consisting of jump instructions
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_JUMPINSTRTABLES_H
-#define LLVM_CODEGEN_JUMPINSTRTABLES_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Pass.h"
-#include "llvm/Target/TargetOptions.h"
-
-namespace llvm {
-class Constant;
-class Function;
-class FunctionType;
-class JumpInstrTableInfo;
-class Module;
-
-/// A class to manage a set of jump tables indexed on function type. It looks at
-/// each function in the module to find all the functions that have the
-/// jumptable attribute set. For each such function, it creates a new
-/// jump-instruction-table function and stores the mapping in the ImmutablePass
-/// JumpInstrTableInfo.
-///
-/// These special functions get lowered in AsmPrinter to assembly of the form:
-/// \verbatim
-/// .globl f
-/// .type f,@function
-/// .align 8,0x90
-/// f:
-/// jmp f_orig@PLT
-/// \endverbatim
-///
-/// Support for an architecture depends on three functions in TargetInstrInfo:
-/// getUnconditionalBranch, getTrap, and getJumpInstrTableEntryBound. AsmPrinter
-/// uses these to generate the appropriate instructions for the jump statement
-/// (an unconditional branch) and for padding to make the table have a size that
-/// is a power of two. This padding uses a trap instruction to ensure that calls
-/// to this area halt the program. The default implementations of these
-/// functions call llvm_unreachable, except for getJumpInstrTableEntryBound,
-/// which returns 0 by default.
-class JumpInstrTables : public ModulePass {
-public:
- static char ID;
-
- JumpInstrTables();
- JumpInstrTables(JumpTable::JumpTableType JTT);
- virtual ~JumpInstrTables();
- bool runOnModule(Module &M) override;
- const char *getPassName() const override { return "Jump-Instruction Tables"; }
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// Creates a jump-instruction table function for the Target and adds it to
- /// the tables.
- Function *insertEntry(Module &M, Function *Target);
-
- /// Checks to see if there is already a table for the given FunctionType.
- bool hasTable(FunctionType *FunTy);
-
- /// Maps the function into a subset of function types, depending on the
- /// jump-instruction table style selected from JumpTableTypes in
- /// JumpInstrTables.cpp. The choice of mapping determines the number of
- /// jump-instruction tables generated by this pass. E.g., the simplest mapping
- /// converts every function type into void f(); so, all functions end up in a
- /// single table.
- static FunctionType *transformType(JumpTable::JumpTableType JTT,
- FunctionType *FunTy);
-private:
- /// The metadata used while a jump table is being built
- struct TableMeta {
- /// The number of this table
- unsigned TableNum;
-
- /// The current number of jump entries in the table.
- unsigned Count;
- };
-
- typedef DenseMap<FunctionType *, struct TableMeta> JumpMap;
-
- /// The current state of functions and jump entries in the table(s).
- JumpMap Metadata;
-
- /// The ImmutablePass that stores information about the generated tables.
- JumpInstrTableInfo *JITI;
-
- /// The total number of tables.
- unsigned TableCount;
-
- /// The type of tables to build.
- JumpTable::JumpTableType JTType;
-};
-
-/// Creates a JumpInstrTables pass for the given type of jump table.
-ModulePass *createJumpInstrTablesPass(JumpTable::JumpTableType JTT);
-}
-
-#endif /* LLVM_CODEGEN_JUMPINSTRTABLES_H */
diff --git a/include/llvm/CodeGen/LatencyPriorityQueue.h b/include/llvm/CodeGen/LatencyPriorityQueue.h
index cf601ae..f347f66 100644
--- a/include/llvm/CodeGen/LatencyPriorityQueue.h
+++ b/include/llvm/CodeGen/LatencyPriorityQueue.h
@@ -83,8 +83,6 @@ namespace llvm {
void remove(SUnit *SU) override;
- void dump(ScheduleDAG* DAG) const override;
-
// scheduledNode - As nodes are scheduled, we look to see if there are any
// successor nodes that have a single unscheduled predecessor. If so, that
// single predecessor has a higher priority, since scheduling it will make
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
index 21634cb..9b8b91c 100644
--- a/include/llvm/CodeGen/LiveInterval.h
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -199,7 +199,7 @@ namespace llvm {
// of live ranges of physical registers in computeRegUnitRange.
// After that the set is flushed to the segment vector and deleted.
typedef std::set<Segment> SegmentSet;
- SegmentSet *segmentSet;
+ std::unique_ptr<SegmentSet> segmentSet;
typedef Segments::iterator iterator;
iterator begin() { return segments.begin(); }
@@ -218,15 +218,13 @@ namespace llvm {
const_vni_iterator vni_end() const { return valnos.end(); }
/// Constructs a new LiveRange object.
- LiveRange(bool UseSegmentSet = false) : segmentSet(nullptr) {
- if (UseSegmentSet)
- segmentSet = new SegmentSet();
- }
+ LiveRange(bool UseSegmentSet = false)
+ : segmentSet(UseSegmentSet ? llvm::make_unique<SegmentSet>()
+ : nullptr) {}
/// Constructs a new LiveRange object by copying segments and valnos from
/// another LiveRange.
- LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator)
- : segmentSet(nullptr) {
+ LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) {
assert(Other.segmentSet == nullptr &&
"Copying of LiveRanges with active SegmentSets is not supported");
@@ -240,8 +238,6 @@ namespace llvm {
}
}
- ~LiveRange() { delete segmentSet; }
-
/// advanceTo - Advance the specified iterator to point to the Segment
/// containing the specified position, or end() if the position is past the
/// end of the range. If no Segment contains this position, but the
@@ -745,8 +741,6 @@ namespace llvm {
#endif
private:
- LiveInterval& operator=(const LiveInterval& rhs) = delete;
-
/// Appends @p Range to SubRanges list.
void appendSubRange(SubRange *Range) {
Range->Next = SubRanges;
diff --git a/include/llvm/CodeGen/LivePhysRegs.h b/include/llvm/CodeGen/LivePhysRegs.h
index 4aa53a9..f44d627 100644
--- a/include/llvm/CodeGen/LivePhysRegs.h
+++ b/include/llvm/CodeGen/LivePhysRegs.h
@@ -57,9 +57,9 @@ public:
}
/// \brief Clear and initialize the LivePhysRegs set.
- void init(const TargetRegisterInfo *_TRI) {
- assert(_TRI && "Invalid TargetRegisterInfo pointer.");
- TRI = _TRI;
+ void init(const TargetRegisterInfo *TRI) {
+ assert(TRI && "Invalid TargetRegisterInfo pointer.");
+ this->TRI = TRI;
LiveRegs.clear();
LiveRegs.setUniverse(TRI->getNumRegs());
}
diff --git a/include/llvm/CodeGen/LiveStackAnalysis.h b/include/llvm/CodeGen/LiveStackAnalysis.h
index df68398..f495507 100644
--- a/include/llvm/CodeGen/LiveStackAnalysis.h
+++ b/include/llvm/CodeGen/LiveStackAnalysis.h
@@ -21,6 +21,7 @@
#include "llvm/Support/Allocator.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <map>
+#include <unordered_map>
namespace llvm {
@@ -33,7 +34,7 @@ namespace llvm {
/// S2IMap - Stack slot indices to live interval mapping.
///
- typedef std::map<int, LiveInterval> SS2IntervalMap;
+ typedef std::unordered_map<int, LiveInterval> SS2IntervalMap;
SS2IntervalMap S2IMap;
/// S2RCMap - Stack slot indices to register class mapping.
diff --git a/include/llvm/CodeGen/MachineDominators.h b/include/llvm/CodeGen/MachineDominators.h
index a6980a6..19f4e2d 100644
--- a/include/llvm/CodeGen/MachineDominators.h
+++ b/include/llvm/CodeGen/MachineDominators.h
@@ -45,9 +45,6 @@ class MachineDominatorTree : public MachineFunctionPass {
MachineBasicBlock *FromBB;
MachineBasicBlock *ToBB;
MachineBasicBlock *NewBB;
- CriticalEdge(MachineBasicBlock *FromBB, MachineBasicBlock *ToBB,
- MachineBasicBlock *NewBB)
- : FromBB(FromBB), ToBB(ToBB), NewBB(NewBB) {}
};
/// \brief Pile up all the critical edges to be split.
@@ -67,74 +64,7 @@ class MachineDominatorTree : public MachineFunctionPass {
/// the fast query path of DT as much as possible.
///
/// \post CriticalEdgesToSplit.empty().
- void applySplitCriticalEdges() const {
- // Bail out early if there is nothing to do.
- if (CriticalEdgesToSplit.empty())
- return;
-
- // For each element in CriticalEdgesToSplit, remember whether or
- // not element is the new immediate domminator of its successor.
- // The mapping is done by index, i.e., the information for the ith
- // element of CriticalEdgesToSplit is the ith element of IsNewIDom.
- SmallVector<bool, 32> IsNewIDom;
- IsNewIDom.resize(CriticalEdgesToSplit.size());
- size_t Idx = 0;
-
- // Collect all the dominance properties info, before invalidating
- // the underlying DT.
- for (CriticalEdge &Edge : CriticalEdgesToSplit) {
- // Update dominator information.
- MachineBasicBlock *Succ = Edge.ToBB;
- MachineDomTreeNode *SucccDTNode = DT->getNode(Succ);
-
- IsNewIDom[Idx] = true;
- for (MachineBasicBlock *PredBB : Succ->predecessors()) {
- if (PredBB == Edge.NewBB)
- continue;
- // If we are in this situation:
- // FromBB1 FromBB2
- // + +
- // + + + +
- // + + + +
- // ... Split1 Split2 ...
- // + +
- // + +
- // +
- // Succ
- // Instead of checking the domiance property with Split2, we
- // check it with FromBB2 since Split2 is still unknown of the
- // underlying DT structure.
- if (NewBBs.count(PredBB)) {
- assert(PredBB->pred_size() == 1 && "A basic block resulting from a "
- "critical edge split has more "
- "than one predecessor!");
- PredBB = *PredBB->pred_begin();
- }
- if (!DT->dominates(SucccDTNode, DT->getNode(PredBB))) {
- IsNewIDom[Idx] = false;
- break;
- }
- }
- ++Idx;
- }
-
- // Now, update DT with the collected dominance properties info.
- Idx = 0;
- for (CriticalEdge &Edge : CriticalEdgesToSplit) {
- // We know FromBB dominates NewBB.
- MachineDomTreeNode *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB);
- MachineDomTreeNode *SucccDTNode = DT->getNode(Edge.ToBB);
-
- // If all the other predecessors of "Succ" are dominated by "Succ" itself
- // then the new block is the new immediate dominator of "Succ". Otherwise,
- // the new block doesn't dominate anything.
- if (IsNewIDom[Idx])
- DT->changeImmediateDominator(SucccDTNode, NewDTNode);
- ++Idx;
- }
- NewBBs.clear();
- CriticalEdgesToSplit.clear();
- }
+ void applySplitCriticalEdges() const;
public:
static char ID; // Pass ID, replacement for typeid
@@ -307,7 +237,7 @@ public:
(void)Inserted;
assert(Inserted &&
"A basic block inserted via edge splitting cannot appear twice");
- CriticalEdgesToSplit.push_back(CriticalEdge(FromBB, ToBB, NewBB));
+ CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB});
}
};
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
index 4ba4a97..333dcdb 100644
--- a/include/llvm/CodeGen/MachineInstr.h
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -257,9 +257,7 @@ public:
/// this DBG_VALUE instruction.
DIExpression getDebugExpression() const {
assert(isDebugValue() && "not a DBG_VALUE");
- DIExpression Expr(getOperand(3).getMetadata());
- assert(Expr.Verify() && "not a DIExpression");
- return Expr;
+ return cast<MDExpression>(getOperand(3).getMetadata());
}
/// emitError - Emit an error referring to the source location of this
@@ -1113,8 +1111,7 @@ public:
//
// Debugging support
//
- void print(raw_ostream &OS, const TargetMachine *TM = nullptr,
- bool SkipOpers = false) const;
+ void print(raw_ostream &OS, bool SkipOpers = false) const;
void dump() const;
//===--------------------------------------------------------------------===//
@@ -1170,6 +1167,12 @@ public:
assert(NumMemRefs == NewMemRefsEnd - NewMemRefs && "Too many memrefs");
}
+ /// clearMemRefs - Clear this MachineInstr's memory reference descriptor list.
+ void clearMemRefs() {
+ MemRefs = nullptr;
+ NumMemRefs = 0;
+ }
+
private:
/// getRegInfo - If this instruction is embedded into a MachineFunction,
/// return the MachineRegisterInfo object for the current function, otherwise
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
index 8859b6a..e6cb494 100644
--- a/include/llvm/CodeGen/MachineInstrBuilder.h
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -356,7 +356,7 @@ inline MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL,
unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) {
assert(DIVariable(Variable).Verify() && "not a DIVariable");
- assert(DIExpression(Expr).Verify() && "not a DIExpression");
+ assert(DIExpression(Expr)->isValid() && "not a DIExpression");
if (IsIndirect)
return BuildMI(MF, DL, MCID)
.addReg(Reg, RegState::Debug)
@@ -383,7 +383,7 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
unsigned Reg, unsigned Offset,
const MDNode *Variable, const MDNode *Expr) {
assert(DIVariable(Variable).Verify() && "not a DIVariable");
- assert(DIExpression(Expr).Verify() && "not a DIExpression");
+ assert(DIExpression(Expr)->isValid() && "not a DIExpression");
MachineFunction &MF = *BB.getParent();
MachineInstr *MI =
BuildMI(MF, DL, MCID, IsIndirect, Reg, Offset, Variable, Expr);
diff --git a/include/llvm/CodeGen/MachineMemOperand.h b/include/llvm/CodeGen/MachineMemOperand.h
index eb5086c..a16c294 100644
--- a/include/llvm/CodeGen/MachineMemOperand.h
+++ b/include/llvm/CodeGen/MachineMemOperand.h
@@ -199,6 +199,24 @@ public:
/// Profile - Gather unique data for the object.
///
void Profile(FoldingSetNodeID &ID) const;
+
+ friend bool operator==(const MachineMemOperand &LHS,
+ const MachineMemOperand &RHS) {
+ return LHS.getValue() == RHS.getValue() &&
+ LHS.getPseudoValue() == RHS.getPseudoValue() &&
+ LHS.getSize() == RHS.getSize() &&
+ LHS.getOffset() == RHS.getOffset() &&
+ LHS.getFlags() == RHS.getFlags() &&
+ LHS.getAAInfo() == RHS.getAAInfo() &&
+ LHS.getRanges() == RHS.getRanges() &&
+ LHS.getAlignment() == RHS.getAlignment() &&
+ LHS.getAddrSpace() == RHS.getAddrSpace();
+ }
+
+ friend bool operator!=(const MachineMemOperand &LHS,
+ const MachineMemOperand &RHS) {
+ return !(LHS == RHS);
+ }
};
raw_ostream &operator<<(raw_ostream &OS, const MachineMemOperand &MRO);
diff --git a/include/llvm/CodeGen/MachineOperand.h b/include/llvm/CodeGen/MachineOperand.h
index eed1e57..04d5361 100644
--- a/include/llvm/CodeGen/MachineOperand.h
+++ b/include/llvm/CodeGen/MachineOperand.h
@@ -217,7 +217,7 @@ public:
///
void clearParent() { ParentMI = nullptr; }
- void print(raw_ostream &os, const TargetMachine *TM = nullptr) const;
+ void print(raw_ostream &os, const TargetRegisterInfo *TRI = nullptr) const;
//===--------------------------------------------------------------------===//
// Accessors that tell you what kind of MachineOperand you're looking at.
diff --git a/include/llvm/CodeGen/MachineRegisterInfo.h b/include/llvm/CodeGen/MachineRegisterInfo.h
index abb04de..001d09f 100644
--- a/include/llvm/CodeGen/MachineRegisterInfo.h
+++ b/include/llvm/CodeGen/MachineRegisterInfo.h
@@ -182,7 +182,18 @@ public:
/// information.
void invalidateLiveness() { TracksLiveness = false; }
- bool tracksSubRegLiveness() const { return TracksSubRegLiveness; }
+ /// Returns true if liveness for register class @p RC should be tracked at
+ /// the subregister level.
+ bool shouldTrackSubRegLiveness(const TargetRegisterClass &RC) const {
+ return subRegLivenessEnabled() && RC.HasDisjunctSubRegs;
+ }
+ bool shouldTrackSubRegLiveness(unsigned VReg) const {
+ assert(TargetRegisterInfo::isVirtualRegister(VReg) && "Must pass a VReg");
+ return shouldTrackSubRegLiveness(*getRegClass(VReg));
+ }
+ bool subRegLivenessEnabled() const {
+ return TracksSubRegLiveness;
+ }
void enableSubRegLiveness(bool Enable = true) {
TracksSubRegLiveness = Enable;
@@ -829,7 +840,6 @@ public:
typedef std::iterator<std::forward_iterator_tag,
MachineInstr, ptrdiff_t>::pointer pointer;
- defusechain_iterator(const defusechain_iterator &I) : Op(I.Op) {}
defusechain_iterator() : Op(nullptr) {}
bool operator==(const defusechain_iterator &x) const {
@@ -932,7 +942,6 @@ public:
typedef std::iterator<std::forward_iterator_tag,
MachineInstr, ptrdiff_t>::pointer pointer;
- defusechain_instr_iterator(const defusechain_instr_iterator &I) : Op(I.Op){}
defusechain_instr_iterator() : Op(nullptr) {}
bool operator==(const defusechain_instr_iterator &x) const {
diff --git a/include/llvm/CodeGen/MachineValueType.h b/include/llvm/CodeGen/MachineValueType.h
index 7ad782f..3eb4d0b 100644
--- a/include/llvm/CodeGen/MachineValueType.h
+++ b/include/llvm/CodeGen/MachineValueType.h
@@ -161,8 +161,8 @@ namespace llvm {
SimpleValueType SimpleTy;
- MVT() : SimpleTy((SimpleValueType)(INVALID_SIMPLE_VALUE_TYPE)) {}
- MVT(SimpleValueType SVT) : SimpleTy(SVT) { }
+ LLVM_CONSTEXPR MVT() : SimpleTy(INVALID_SIMPLE_VALUE_TYPE) {}
+ LLVM_CONSTEXPR MVT(SimpleValueType SVT) : SimpleTy(SVT) { }
bool operator>(const MVT& S) const { return SimpleTy > S.SimpleTy; }
bool operator<(const MVT& S) const { return SimpleTy < S.SimpleTy; }
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
index 65b17d3..48e1f21 100644
--- a/include/llvm/CodeGen/Passes.h
+++ b/include/llvm/CodeGen/Passes.h
@@ -612,13 +612,13 @@ namespace llvm {
ModulePass *createForwardControlFlowIntegrityPass();
} // End llvm namespace
-/// This initializer registers TargetMachine constructor, so the pass being
-/// initialized can use target dependent interfaces. Please do not move this
-/// macro to be together with INITIALIZE_PASS, which is a complete target
-/// independent initializer, and we don't want to make libScalarOpts depend
-/// on libCodeGen.
-#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
- static void* initialize##passName##PassOnce(PassRegistry &Registry) { \
+/// Target machine pass initializer for passes with dependencies. Use with
+/// INITIALIZE_TM_PASS_END.
+#define INITIALIZE_TM_PASS_BEGIN INITIALIZE_PASS_BEGIN
+
+/// Target machine pass initializer for passes with dependencies. Use with
+/// INITIALIZE_TM_PASS_BEGIN.
+#define INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis) \
PassInfo *PI = new PassInfo(name, arg, & passName ::ID, \
PassInfo::NormalCtor_t(callDefaultCtor< passName >), cfg, analysis, \
PassInfo::TargetMachineCtor_t(callTargetMachineCtor< passName >)); \
@@ -629,4 +629,13 @@ namespace llvm {
CALL_ONCE_INITIALIZATION(initialize##passName##PassOnce) \
}
+/// This initializer registers TargetMachine constructor, so the pass being
+/// initialized can use target dependent interfaces. Please do not move this
+/// macro to be together with INITIALIZE_PASS, which is a complete target
+/// independent initializer, and we don't want to make libScalarOpts depend
+/// on libCodeGen.
+#define INITIALIZE_TM_PASS(passName, arg, name, cfg, analysis) \
+ INITIALIZE_TM_PASS_BEGIN(passName, arg, name, cfg, analysis) \
+ INITIALIZE_TM_PASS_END(passName, arg, name, cfg, analysis)
+
#endif
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index c7bb07b..6046e46 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -544,8 +544,10 @@ private:
public:
SpillCostComparator(const Graph& G) : G(G) {}
bool operator()(NodeId N1Id, NodeId N2Id) {
- PBQPNum N1SC = G.getNodeCosts(N1Id)[0] / G.getNodeDegree(N1Id);
- PBQPNum N2SC = G.getNodeCosts(N2Id)[0] / G.getNodeDegree(N2Id);
+ PBQPNum N1SC = G.getNodeCosts(N1Id)[0];
+ PBQPNum N2SC = G.getNodeCosts(N2Id)[0];
+ if (N1SC == N2SC)
+ return G.getNodeDegree(N1Id) < G.getNodeDegree(N2Id);
return N1SC < N2SC;
}
private:
diff --git a/include/llvm/CodeGen/ResourcePriorityQueue.h b/include/llvm/CodeGen/ResourcePriorityQueue.h
index 114fe7c..0097e04 100644
--- a/include/llvm/CodeGen/ResourcePriorityQueue.h
+++ b/include/llvm/CodeGen/ResourcePriorityQueue.h
@@ -64,7 +64,7 @@ namespace llvm {
/// ResourcesModel - Represents VLIW state.
/// Not limited to VLIW targets per say, but assumes
/// definition of DFA by a target.
- DFAPacketizer *ResourcesModel;
+ std::unique_ptr<DFAPacketizer> ResourcesModel;
/// Resource model - packet/bundle model. Purely
/// internal at the time.
@@ -77,10 +77,6 @@ namespace llvm {
public:
ResourcePriorityQueue(SelectionDAGISel *IS);
- ~ResourcePriorityQueue() {
- delete ResourcesModel;
- }
-
bool isBottomUp() const override { return false; }
void initNodes(std::vector<SUnit> &sunits) override;
@@ -124,8 +120,6 @@ namespace llvm {
void remove(SUnit *SU) override;
- void dump(ScheduleDAG* DAG) const override;
-
/// scheduledNode - Main resource tracking point.
void scheduledNode(SUnit *Node) override;
bool isResourceAvailable(SUnit *SU);
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
index 64c9c47..2be5de6 100644
--- a/include/llvm/CodeGen/RuntimeLibcalls.h
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -425,6 +425,10 @@ namespace RTLIB {
/// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
/// UNKNOWN_LIBCALL if there is none.
Libcall getUINTTOFP(EVT OpVT, EVT RetVT);
+
+ /// Return the SYNC_FETCH_AND_* value for the given opcode and type, or
+ /// UNKNOWN_LIBCALL if there is none.
+ Libcall getATOMIC(unsigned Opc, MVT VT);
}
}
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
index 80aee8c..8391314 100644
--- a/include/llvm/CodeGen/ScheduleDAG.h
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -628,12 +628,6 @@ namespace llvm {
}
bool operator!=(const SUnitIterator& x) const { return !operator==(x); }
- const SUnitIterator &operator=(const SUnitIterator &I) {
- assert(I.Node==Node && "Cannot assign iterators to two different nodes!");
- Operand = I.Operand;
- return *this;
- }
-
pointer operator*() const {
return Node->Preds[Operand].getSUnit();
}
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
index d53e66d..7acdfc7 100644
--- a/include/llvm/CodeGen/SelectionDAGISel.h
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -80,12 +80,12 @@ public:
virtual SDNode *Select(SDNode *N) = 0;
/// SelectInlineAsmMemoryOperand - Select the specified address as a target
- /// addressing mode, according to the specified constraint code. If this does
+ /// addressing mode, according to the specified constraint. If this does
/// not match or is not implemented, return true. The resultant operands
/// (which will appear in the machine instruction) should be added to the
/// OutOps vector.
virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
- char ConstraintCode,
+ unsigned ConstraintID,
std::vector<SDValue> &OutOps) {
return true;
}
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index 0b6240f..2b3e08c 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -50,8 +50,7 @@ template <typename T> struct DenseMapInfo;
template <typename T> struct simplify_type;
template <typename T> struct ilist_traits;
-/// isBinOpWithFlags - Returns true if the opcode is a binary operation
-/// with flags.
+/// Returns true if the opcode is a binary operation with flags.
static bool isBinOpWithFlags(unsigned Opcode) {
switch (Opcode) {
case ISD::SDIV:
@@ -71,7 +70,7 @@ static bool isBinOpWithFlags(unsigned Opcode) {
void checkForCycles(const SDNode *N, const SelectionDAG *DAG = nullptr,
bool force = false);
-/// SDVTList - This represents a list of ValueType's that has been intern'd by
+/// This represents a list of ValueType's that has been intern'd by
/// a SelectionDAG. Instances of this simple value class are returned by
/// SelectionDAG::getVTList(...).
///
@@ -83,11 +82,11 @@ struct SDVTList {
namespace ISD {
/// Node predicates
- /// isBuildVectorAllOnes - Return true if the specified node is a
+ /// Return true if the specified node is a
/// BUILD_VECTOR where all of the elements are ~0 or undef.
bool isBuildVectorAllOnes(const SDNode *N);
- /// isBuildVectorAllZeros - Return true if the specified node is a
+ /// Return true if the specified node is a
/// BUILD_VECTOR where all of the elements are 0 or undef.
bool isBuildVectorAllZeros(const SDNode *N);
@@ -95,18 +94,22 @@ namespace ISD {
/// all ConstantSDNode or undef.
bool isBuildVectorOfConstantSDNodes(const SDNode *N);
- /// isScalarToVector - Return true if the specified node is a
+ /// \brief Return true if the specified node is a BUILD_VECTOR node of
+ /// all ConstantFPSDNode or undef.
+ bool isBuildVectorOfConstantFPSDNodes(const SDNode *N);
+
+ /// Return true if the specified node is a
/// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
/// element is not an undef.
bool isScalarToVector(const SDNode *N);
- /// allOperandsUndef - Return true if the node has at least one operand
+ /// Return true if the node has at least one operand
/// and all operands of the specified node are ISD::UNDEF.
bool allOperandsUndef(const SDNode *N);
} // end llvm:ISD namespace
//===----------------------------------------------------------------------===//
-/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple
+/// Unlike LLVM values, Selection DAG nodes may return multiple
/// values as the result of a computation. Many nodes return multiple values,
/// from loads (which define a token and a return value) to ADDC (which returns
/// a result and a carry value), to calls (which may return an arbitrary number
@@ -153,11 +156,10 @@ public:
return SDValue(Node, R);
}
- // isOperandOf - Return true if this node is an operand of N.
+ // Return true if this node is an operand of N.
bool isOperandOf(SDNode *N) const;
- /// getValueType - Return the ValueType of the referenced return value.
- ///
+ /// Return the ValueType of the referenced return value.
inline EVT getValueType() const;
/// Return the simple ValueType of the referenced return value.
@@ -165,8 +167,7 @@ public:
return getValueType().getSimpleVT();
}
- /// getValueSizeInBits - Returns the size of the value in bits.
- ///
+ /// Returns the size of the value in bits.
unsigned getValueSizeInBits() const {
return getValueType().getSizeInBits();
}
@@ -188,22 +189,18 @@ public:
inline void dump() const;
inline void dumpr() const;
- /// reachesChainWithoutSideEffects - Return true if this operand (which must
- /// be a chain) reaches the specified operand without crossing any
- /// side-effecting instructions. In practice, this looks through token
- /// factors and non-volatile loads. In order to remain efficient, this only
+ /// Return true if this operand (which must be a chain) reaches the
+ /// specified operand without crossing any side-effecting instructions.
+ /// In practice, this looks through token factors and non-volatile loads.
+ /// In order to remain efficient, this only
/// looks a couple of nodes in, it does not do an exhaustive search.
bool reachesChainWithoutSideEffects(SDValue Dest,
unsigned Depth = 2) const;
- /// use_empty - Return true if there are no nodes using value ResNo
- /// of Node.
- ///
+ /// Return true if there are no nodes using value ResNo of Node.
inline bool use_empty() const;
- /// hasOneUse - Return true if there is exactly one node using value
- /// ResNo of Node.
- ///
+ /// Return true if there is exactly one node using value ResNo of Node.
inline bool hasOneUse() const;
};
@@ -230,7 +227,7 @@ template<> struct DenseMapInfo<SDValue> {
template <> struct isPodLike<SDValue> { static const bool value = true; };
-/// simplify_type specializations - Allow casting operators to work directly on
+/// Allow casting operators to work directly on
/// SDValues as if they were SDNode*'s.
template<> struct simplify_type<SDValue> {
typedef SDNode* SimpleType;
@@ -245,7 +242,7 @@ template<> struct simplify_type<const SDValue> {
}
};
-/// SDUse - Represents a use of a SDNode. This class holds an SDValue,
+/// Represents a use of a SDNode. This class holds an SDValue,
/// which records the SDNode being used and the result number, a
/// pointer to the SDNode using the value, and Next and Prev pointers,
/// which link together all the uses of an SDNode.
@@ -272,30 +269,30 @@ public:
/// the SDValue.
const SDValue &get() const { return Val; }
- /// getUser - This returns the SDNode that contains this Use.
+ /// This returns the SDNode that contains this Use.
SDNode *getUser() { return User; }
- /// getNext - Get the next SDUse in the use list.
+ /// Get the next SDUse in the use list.
SDUse *getNext() const { return Next; }
- /// getNode - Convenience function for get().getNode().
+ /// Convenience function for get().getNode().
SDNode *getNode() const { return Val.getNode(); }
- /// getResNo - Convenience function for get().getResNo().
+ /// Convenience function for get().getResNo().
unsigned getResNo() const { return Val.getResNo(); }
- /// getValueType - Convenience function for get().getValueType().
+ /// Convenience function for get().getValueType().
EVT getValueType() const { return Val.getValueType(); }
- /// operator== - Convenience function for get().operator==
+ /// Convenience function for get().operator==
bool operator==(const SDValue &V) const {
return Val == V;
}
- /// operator!= - Convenience function for get().operator!=
+ /// Convenience function for get().operator!=
bool operator!=(const SDValue &V) const {
return Val != V;
}
- /// operator< - Convenience function for get().operator<
+ /// Convenience function for get().operator<
bool operator<(const SDValue &V) const {
return Val < V;
}
@@ -306,13 +303,13 @@ private:
void setUser(SDNode *p) { User = p; }
- /// set - Remove this use from its existing use list, assign it the
+ /// Remove this use from its existing use list, assign it the
/// given value, and add it to the new value's node's use list.
inline void set(const SDValue &V);
- /// setInitial - like set, but only supports initializing a newly-allocated
+ /// Like set, but only supports initializing a newly-allocated
/// SDUse with a non-null value.
inline void setInitial(const SDValue &V);
- /// setNode - like set, but only sets the Node portion of the value,
+ /// Like set, but only sets the Node portion of the value,
/// leaving the ResNo portion unmodified.
inline void setNode(SDNode *N);
@@ -339,47 +336,45 @@ template<> struct simplify_type<SDUse> {
};
-/// SDNode - Represents one node in the SelectionDAG.
+/// Represents one node in the SelectionDAG.
///
class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
private:
- /// NodeType - The operation that this node performs.
- ///
+ /// The operation that this node performs.
int16_t NodeType;
- /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true,
+ /// This is true if OperandList was new[]'d. If true,
/// then they will be delete[]'d when the node is destroyed.
uint16_t OperandsNeedDelete : 1;
- /// HasDebugValue - This tracks whether this node has one or more dbg_value
+ /// This tracks whether this node has one or more dbg_value
/// nodes corresponding to it.
uint16_t HasDebugValue : 1;
protected:
- /// SubclassData - This member is defined by this class, but is not used for
+ /// This member is defined by this class, but is not used for
/// anything. Subclasses can use it to hold whatever state they find useful.
/// This field is initialized to zero by the ctor.
uint16_t SubclassData : 14;
private:
- /// NodeId - Unique id per SDNode in the DAG.
+ /// Unique id per SDNode in the DAG.
int NodeId;
- /// OperandList - The values that are used by this operation.
- ///
+ /// The values that are used by this operation.
SDUse *OperandList;
- /// ValueList - The types of the values this node defines. SDNode's may
+ /// The types of the values this node defines. SDNode's may
/// define multiple values simultaneously.
const EVT *ValueList;
- /// UseList - List of uses for this SDNode.
+ /// List of uses for this SDNode.
SDUse *UseList;
- /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+ /// The number of entries in the Operand/Value list.
unsigned short NumOperands, NumValues;
- /// debugLoc - source line information.
+ /// Source line information.
DebugLoc debugLoc;
// The ordering of the SDNodes. It roughly corresponds to the ordering of the
@@ -389,7 +384,7 @@ private:
// this ordering.
unsigned IROrder;
- /// getValueTypeList - Return a pointer to the specified value type.
+ /// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);
friend class SelectionDAG;
@@ -400,17 +395,17 @@ public:
// Accessors
//
- /// getOpcode - Return the SelectionDAG opcode value for this node. For
+ /// Return the SelectionDAG opcode value for this node. For
/// pre-isel nodes (those for which isMachineOpcode returns false), these
/// are the opcode values in the ISD and <target>ISD namespaces. For
/// post-isel opcodes, see getMachineOpcode.
unsigned getOpcode() const { return (unsigned short)NodeType; }
- /// isTargetOpcode - Test if this node has a target-specific opcode (in the
+ /// Test if this node has a target-specific opcode (in the
/// \<target\>ISD namespace).
bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
- /// isTargetMemoryOpcode - Test if this node has a target-specific
+ /// Test if this node has a target-specific
/// memory-referencing opcode (in the \<target\>ISD namespace and
/// greater than FIRST_TARGET_MEMORY_OPCODE).
bool isTargetMemoryOpcode() const {
@@ -427,11 +422,11 @@ public:
NodeType == ISD::INTRINSIC_VOID) && ((SubclassData >> 13) & 1);
}
- /// isMachineOpcode - Test if this node has a post-isel opcode, directly
+ /// Test if this node has a post-isel opcode, directly
/// corresponding to a MachineInstr opcode.
bool isMachineOpcode() const { return NodeType < 0; }
- /// getMachineOpcode - This may only be called if isMachineOpcode returns
+ /// This may only be called if isMachineOpcode returns
/// true. It returns the MachineInstr opcode value that the node's opcode
/// corresponds to.
unsigned getMachineOpcode() const {
@@ -439,50 +434,44 @@ public:
return ~NodeType;
}
- /// getHasDebugValue - get this bit.
+ /// Get this bit.
bool getHasDebugValue() const { return HasDebugValue; }
- /// setHasDebugValue - set this bit.
+ /// Set this bit.
void setHasDebugValue(bool b) { HasDebugValue = b; }
- /// use_empty - Return true if there are no uses of this node.
- ///
+ /// Return true if there are no uses of this node.
bool use_empty() const { return UseList == nullptr; }
- /// hasOneUse - Return true if there is exactly one use of this node.
- ///
+ /// Return true if there is exactly one use of this node.
bool hasOneUse() const {
return !use_empty() && std::next(use_begin()) == use_end();
}
- /// use_size - Return the number of uses of this node. This method takes
+ /// Return the number of uses of this node. This method takes
/// time proportional to the number of uses.
- ///
size_t use_size() const { return std::distance(use_begin(), use_end()); }
- /// getNodeId - Return the unique node id.
- ///
+ /// Return the unique node id.
int getNodeId() const { return NodeId; }
- /// setNodeId - Set unique node id.
+ /// Set unique node id.
void setNodeId(int Id) { NodeId = Id; }
- /// getIROrder - Return the node ordering.
- ///
+ /// Return the node ordering.
unsigned getIROrder() const { return IROrder; }
- /// setIROrder - Set the node ordering.
- ///
+ /// Set the node ordering.
void setIROrder(unsigned Order) { IROrder = Order; }
- /// getDebugLoc - Return the source location info.
+ /// Return the source location info.
const DebugLoc &getDebugLoc() const { return debugLoc; }
- /// setDebugLoc - Set source location info. Try to avoid this, putting
+ /// Set source location info. Try to avoid this, putting
/// it in the constructor is preferable.
void setDebugLoc(DebugLoc dl) { debugLoc = std::move(dl); }
- /// use_iterator - This class provides iterator support for SDUse
+ /// This class provides iterator support for SDUse
/// operands that use a specific SDNode.
class use_iterator
: public std::iterator<std::forward_iterator_tag, SDUse, ptrdiff_t> {
@@ -506,7 +495,7 @@ public:
return !operator==(x);
}
- /// atEnd - return true if this iterator is at the end of uses list.
+ /// Return true if this iterator is at the end of uses list.
bool atEnd() const { return Op == nullptr; }
// Iterator traversal: forward iteration only.
@@ -530,17 +519,14 @@ public:
SDUse &getUse() const { return *Op; }
- /// getOperandNo - Retrieve the operand # of this use in its user.
- ///
+ /// Retrieve the operand # of this use in its user.
unsigned getOperandNo() const {
assert(Op && "Cannot dereference end iterator!");
return (unsigned)(Op - Op->getUser()->OperandList);
}
};
- /// use_begin/use_end - Provide iteration support to walk over all uses
- /// of an SDNode.
-
+ /// Provide iteration support to walk over all uses of an SDNode.
use_iterator use_begin() const {
return use_iterator(UseList);
}
@@ -554,37 +540,34 @@ public:
return iterator_range<use_iterator>(use_begin(), use_end());
}
- /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
- /// indicated value. This method ignores uses of other values defined by this
- /// operation.
+ /// Return true if there are exactly NUSES uses of the indicated value.
+ /// This method ignores uses of other values defined by this operation.
bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
- /// hasAnyUseOfValue - Return true if there are any use of the indicated
- /// value. This method ignores uses of other values defined by this operation.
+ /// Return true if there are any use of the indicated value.
+ /// This method ignores uses of other values defined by this operation.
bool hasAnyUseOfValue(unsigned Value) const;
- /// isOnlyUserOf - Return true if this node is the only use of N.
- ///
+ /// Return true if this node is the only use of N.
bool isOnlyUserOf(SDNode *N) const;
- /// isOperandOf - Return true if this node is an operand of N.
- ///
+ /// Return true if this node is an operand of N.
bool isOperandOf(SDNode *N) const;
- /// isPredecessorOf - Return true if this node is a predecessor of N.
+ /// Return true if this node is a predecessor of N.
/// NOTE: Implemented on top of hasPredecessor and every bit as
/// expensive. Use carefully.
bool isPredecessorOf(const SDNode *N) const {
return N->hasPredecessor(this);
}
- /// hasPredecessor - Return true if N is a predecessor of this node.
+ /// Return true if N is a predecessor of this node.
/// N is either an operand of this node, or can be reached by recursively
/// traversing up the operands.
/// NOTE: This is an expensive method. Use it carefully.
bool hasPredecessor(const SDNode *N) const;
- /// hasPredecesorHelper - Return true if N is a predecessor of this node.
+ /// Return true if N is a predecessor of this node.
/// N is either an operand of this node, or can be reached by recursively
/// traversing up the operands.
/// In this helper the Visited and worklist sets are held externally to
@@ -597,12 +580,10 @@ public:
SmallPtrSetImpl<const SDNode *> &Visited,
SmallVectorImpl<const SDNode *> &Worklist) const;
- /// getNumOperands - Return the number of values used by this operation.
- ///
+ /// Return the number of values used by this operation.
unsigned getNumOperands() const { return NumOperands; }
- /// getConstantOperandVal - Helper method returns the integer value of a
- /// ConstantSDNode operand.
+ /// Helper method returns the integer value of a ConstantSDNode operand.
uint64_t getConstantOperandVal(unsigned Num) const;
const SDValue &getOperand(unsigned Num) const {
@@ -620,7 +601,7 @@ public:
return X;
}
- /// getGluedNode - If this node has a glue operand, return the node
+ /// If this node has a glue operand, return the node
/// to which the glue operand points. Otherwise return NULL.
SDNode *getGluedNode() const {
if (getNumOperands() != 0 &&
@@ -645,7 +626,7 @@ public:
return FoundNode;
}
- /// getGluedUser - If this node has a glue value with a user, return
+ /// If this node has a glue value with a user, return
/// the user (there is at most one). Otherwise return NULL.
SDNode *getGluedUser() const {
for (use_iterator UI = use_begin(), UE = use_end(); UI != UE; ++UI)
@@ -654,26 +635,21 @@ public:
return nullptr;
}
- /// getNumValues - Return the number of values defined/returned by this
- /// operator.
- ///
+ /// Return the number of values defined/returned by this operator.
unsigned getNumValues() const { return NumValues; }
- /// getValueType - Return the type of a specified result.
- ///
+ /// Return the type of a specified result.
EVT getValueType(unsigned ResNo) const {
assert(ResNo < NumValues && "Illegal result number!");
return ValueList[ResNo];
}
/// Return the type of a specified result as a simple type.
- ///
MVT getSimpleValueType(unsigned ResNo) const {
return getValueType(ResNo).getSimpleVT();
}
- /// getValueSizeInBits - Returns MVT::getSizeInBits(getValueType(ResNo)).
- ///
+ /// Returns MVT::getSizeInBits(getValueType(ResNo)).
unsigned getValueSizeInBits(unsigned ResNo) const {
return getValueType(ResNo).getSizeInBits();
}
@@ -682,8 +658,7 @@ public:
value_iterator value_begin() const { return ValueList; }
value_iterator value_end() const { return ValueList+NumValues; }
- /// getOperationName - Return the opcode of this operation for printing.
- ///
+ /// Return the opcode of this operation for printing.
std::string getOperationName(const SelectionDAG *G = nullptr) const;
static const char* getIndexedModeName(ISD::MemIndexedMode AM);
void print_types(raw_ostream &OS, const SelectionDAG *G) const;
@@ -691,7 +666,7 @@ public:
void print(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
void printr(raw_ostream &OS, const SelectionDAG *G = nullptr) const;
- /// printrFull - Print a SelectionDAG node and all children down to
+ /// Print a SelectionDAG node and all children down to
/// the leaves. The given SelectionDAG allows target-specific nodes
/// to be printed in human-readable form. Unlike printr, this will
/// print the whole DAG, including children that appear multiple
@@ -699,7 +674,7 @@ public:
///
void printrFull(raw_ostream &O, const SelectionDAG *G = nullptr) const;
- /// printrWithDepth - Print a SelectionDAG node and children up to
+ /// Print a SelectionDAG node and children up to
/// depth "depth." The given SelectionDAG allows target-specific
/// nodes to be printed in human-readable form. Unlike printr, this
/// will print children that appear multiple times wherever they are
@@ -709,30 +684,29 @@ public:
unsigned depth = 100) const;
- /// dump - Dump this node, for debugging.
+ /// Dump this node, for debugging.
void dump() const;
- /// dumpr - Dump (recursively) this node and its use-def subgraph.
+ /// Dump (recursively) this node and its use-def subgraph.
void dumpr() const;
- /// dump - Dump this node, for debugging.
+ /// Dump this node, for debugging.
/// The given SelectionDAG allows target-specific nodes to be printed
/// in human-readable form.
void dump(const SelectionDAG *G) const;
- /// dumpr - Dump (recursively) this node and its use-def subgraph.
+ /// Dump (recursively) this node and its use-def subgraph.
/// The given SelectionDAG allows target-specific nodes to be printed
/// in human-readable form.
void dumpr(const SelectionDAG *G) const;
- /// dumprFull - printrFull to dbgs(). The given SelectionDAG allows
+ /// printrFull to dbgs(). The given SelectionDAG allows
/// target-specific nodes to be printed in human-readable form.
/// Unlike dumpr, this will print the whole DAG, including children
/// that appear multiple times.
- ///
void dumprFull(const SelectionDAG *G = nullptr) const;
- /// dumprWithDepth - printrWithDepth to dbgs(). The given
+ /// printrWithDepth to dbgs(). The given
/// SelectionDAG allows target-specific nodes to be printed in
/// human-readable form. Unlike dumpr, this will print children
/// that appear multiple times wherever they are used.
@@ -740,12 +714,10 @@ public:
void dumprWithDepth(const SelectionDAG *G = nullptr,
unsigned depth = 100) const;
- /// Profile - Gather unique data for the node.
- ///
+ /// Gather unique data for the node.
void Profile(FoldingSetNodeID &ID) const;
- /// addUse - This method should only be used by the SDUse class.
- ///
+ /// This method should only be used by the SDUse class.
void addUse(SDUse &U) { U.addToList(&UseList); }
protected:
@@ -786,7 +758,7 @@ protected:
"NumValues wasn't wide enough for its operands!");
}
- /// InitOperands - Initialize the operands list of this with 1 operand.
+ /// Initialize the operands list of this with 1 operand.
void InitOperands(SDUse *Ops, const SDValue &Op0) {
Ops[0].setUser(this);
Ops[0].setInitial(Op0);
@@ -795,7 +767,7 @@ protected:
checkForCycles(this);
}
- /// InitOperands - Initialize the operands list of this with 2 operands.
+ /// Initialize the operands list of this with 2 operands.
void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) {
Ops[0].setUser(this);
Ops[0].setInitial(Op0);
@@ -806,7 +778,7 @@ protected:
checkForCycles(this);
}
- /// InitOperands - Initialize the operands list of this with 3 operands.
+ /// Initialize the operands list of this with 3 operands.
void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
const SDValue &Op2) {
Ops[0].setUser(this);
@@ -820,7 +792,7 @@ protected:
checkForCycles(this);
}
- /// InitOperands - Initialize the operands list of this with 4 operands.
+ /// Initialize the operands list of this with 4 operands.
void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
const SDValue &Op2, const SDValue &Op3) {
Ops[0].setUser(this);
@@ -836,7 +808,7 @@ protected:
checkForCycles(this);
}
- /// InitOperands - Initialize the operands list of this with N operands.
+ /// Initialize the operands list of this with N operands.
void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) {
for (unsigned i = 0; i != N; ++i) {
Ops[i].setUser(this);
@@ -849,8 +821,7 @@ protected:
checkForCycles(this);
}
- /// DropOperands - Release the operands and set this node to have
- /// zero operands.
+ /// Release the operands and set this node to have zero operands.
void DropOperands();
};
@@ -972,7 +943,7 @@ inline void SDUse::setNode(SDNode *N) {
if (N) N->addUse(*this);
}
-/// UnarySDNode - This class is used for single-operand SDNodes. This is solely
+/// This class is used for single-operand SDNodes. This is solely
/// to allow co-allocation of node operands with the node itself.
class UnarySDNode : public SDNode {
SDUse Op;
@@ -984,7 +955,7 @@ public:
}
};
-/// BinarySDNode - This class is used for two-operand SDNodes. This is solely
+/// This class is used for two-operand SDNodes. This is solely
/// to allow co-allocation of node operands with the node itself.
class BinarySDNode : public SDNode {
SDUse Ops[2];
@@ -996,7 +967,7 @@ public:
}
};
-/// BinaryWithFlagsSDNode - This class is an extension of BinarySDNode
+/// This class is an extension of BinarySDNode
/// used from those opcodes that have associated extra flags.
class BinaryWithFlagsSDNode : public BinarySDNode {
enum { NUW = (1 << 0), NSW = (1 << 1), EXACT = (1 << 2) };
@@ -1005,8 +976,7 @@ public:
BinaryWithFlagsSDNode(unsigned Opc, unsigned Order, DebugLoc dl, SDVTList VTs,
SDValue X, SDValue Y)
: BinarySDNode(Opc, Order, dl, VTs, X, Y) {}
- /// getRawSubclassData - Return the SubclassData value, which contains an
- /// encoding of the flags.
+ /// Return the SubclassData value, which contains an encoding of the flags.
/// This function should be used to add subclass data to the NodeID value.
unsigned getRawSubclassData() const { return SubclassData; }
void setHasNoUnsignedWrap(bool b) {
@@ -1026,7 +996,7 @@ public:
}
};
-/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
+/// This class is used for three-operand SDNodes. This is solely
/// to allow co-allocation of node operands with the node itself.
class TernarySDNode : public SDNode {
SDUse Ops[3];
@@ -1039,7 +1009,7 @@ public:
};
-/// HandleSDNode - This class is used to form a handle around another node that
+/// This class is used to form a handle around another node that
/// is persistent and is updated across invocations of replaceAllUsesWith on its
/// operand. This node should be directly created by end-users and not added to
/// the AllNodes list.
@@ -1074,11 +1044,11 @@ public:
/// Abstact virtual class for operations for memory operations
class MemSDNode : public SDNode {
private:
- // MemoryVT - VT of in-memory value.
+ // VT of in-memory value.
EVT MemoryVT;
protected:
- /// MMO - Memory reference information.
+ /// Memory reference information.
MachineMemOperand *MMO;
public:
@@ -1099,7 +1069,7 @@ public:
return MMO->getAlignment();
}
- /// getRawSubclassData - Return the SubclassData value, which contains an
+ /// Return the SubclassData value, which contains an
/// encoding of the volatile flag, as well as bits used by subclasses. This
/// function should only be used to compute a FoldingSetNodeID value.
unsigned getRawSubclassData() const {
@@ -1128,10 +1098,10 @@ public:
/// Returns the Ranges that describes the dereference.
const MDNode *getRanges() const { return MMO->getRanges(); }
- /// getMemoryVT - Return the type of the in-memory value.
+ /// Return the type of the in-memory value.
EVT getMemoryVT() const { return MemoryVT; }
- /// getMemOperand - Return a MachineMemOperand object describing the memory
+ /// Return a MachineMemOperand object describing the memory
/// reference performed by operation.
MachineMemOperand *getMemOperand() const { return MMO; }
@@ -1139,12 +1109,12 @@ public:
return MMO->getPointerInfo();
}
- /// getAddressSpace - Return the address space for the associated pointer
+ /// Return the address space for the associated pointer
unsigned getAddressSpace() const {
return getPointerInfo().getAddrSpace();
}
- /// refineAlignment - Update this MemSDNode's MachineMemOperand information
+ /// Update this MemSDNode's MachineMemOperand information
/// to reflect the alignment of NewMMO, if it has a greater alignment.
/// This must only be used when the new alignment applies to all users of
/// this MachineMemOperand.
@@ -1186,8 +1156,7 @@ public:
}
};
-/// AtomicSDNode - A SDNode reprenting atomic operations.
-///
+/// A SDNode reprenting atomic operations.
class AtomicSDNode : public MemSDNode {
SDUse Ops[4];
@@ -1300,7 +1269,7 @@ public:
}
};
-/// MemIntrinsicSDNode - This SDNode is used for target intrinsics that touch
+/// This SDNode is used for target intrinsics that touch
/// memory and need an associated MachineMemOperand. Its opcode may be
/// INTRINSIC_VOID, INTRINSIC_W_CHAIN, PREFETCH, or a target-specific opcode
/// with a value not less than FIRST_TARGET_MEMORY_OPCODE.
@@ -1323,7 +1292,7 @@ public:
}
};
-/// ShuffleVectorSDNode - This SDNode is used to implement the code generator
+/// This SDNode is used to implement the code generator
/// support for the llvm IR shufflevector instruction. It combines elements
/// from two input vectors into a new input vector, with the selection and
/// ordering of elements determined by an array of integers, referred to as
@@ -1367,6 +1336,21 @@ public:
}
static bool isSplatMask(const int *Mask, EVT VT);
+ /// Change values in a shuffle permute mask assuming
+ /// the two vector operands have swapped position.
+ static void commuteMask(SmallVectorImpl<int> &Mask) {
+ unsigned NumElems = Mask.size();
+ for (unsigned i = 0; i != NumElems; ++i) {
+ int idx = Mask[i];
+ if (idx < 0)
+ continue;
+ else if (idx < (int)NumElems)
+ Mask[i] = idx + NumElems;
+ else
+ Mask[i] = idx - NumElems;
+ }
+ }
+
static bool classof(const SDNode *N) {
return N->getOpcode() == ISD::VECTOR_SHUFFLE;
}
@@ -1411,19 +1395,19 @@ public:
const APFloat& getValueAPF() const { return Value->getValueAPF(); }
const ConstantFP *getConstantFPValue() const { return Value; }
- /// isZero - Return true if the value is positive or negative zero.
+ /// Return true if the value is positive or negative zero.
bool isZero() const { return Value->isZero(); }
- /// isNaN - Return true if the value is a NaN.
+ /// Return true if the value is a NaN.
bool isNaN() const { return Value->isNaN(); }
- /// isInfinity - Return true if the value is an infinity
+ /// Return true if the value is an infinity
bool isInfinity() const { return Value->isInfinity(); }
- /// isNegative - Return true if the value is negative.
+ /// Return true if the value is negative.
bool isNegative() const { return Value->isNegative(); }
- /// isExactlyValue - We don't rely on operator== working on double values, as
+ /// We don't rely on operator== working on double values, as
/// it returns true for things that are clearly not equal, like -0.0 and 0.0.
/// As such, this method can be used to do an exact bit-for-bit comparison of
/// two floating point values.
@@ -1607,13 +1591,12 @@ public:
}
};
-/// BuildVectorSDNode - A "pseudo-class" with methods for operating on
-/// BUILD_VECTORs.
+/// A "pseudo-class" with methods for operating on BUILD_VECTORs.
class BuildVectorSDNode : public SDNode {
// These are constructed as SDNodes and then cast to BuildVectorSDNodes.
explicit BuildVectorSDNode() = delete;
public:
- /// isConstantSplat - Check if this is a constant splat, and if so, find the
+ /// Check if this is a constant splat, and if so, find the
/// smallest element size that splats the vector. If MinSplatBits is
/// nonzero, the element size must be at least that large. Note that the
/// splat element may be the entire vector (i.e., a one element vector).
@@ -1656,7 +1639,7 @@ public:
}
};
-/// SrcValueSDNode - An SDNode that holds an arbitrary LLVM IR Value. This is
+/// An SDNode that holds an arbitrary LLVM IR Value. This is
/// used when the SelectionDAG needs to make a simple reference to something
/// in the LLVM IR representation.
///
@@ -1668,7 +1651,7 @@ class SrcValueSDNode : public SDNode {
: SDNode(ISD::SRCVALUE, 0, DebugLoc(), getSDVTList(MVT::Other)), V(v) {}
public:
- /// getValue - return the contained Value.
+ /// Return the contained Value.
const Value *getValue() const { return V; }
static bool classof(const SDNode *N) {
@@ -1795,7 +1778,7 @@ public:
}
};
-/// CvtRndSatSDNode - NOTE: avoid using this node as this may disappear in the
+/// NOTE: avoid using this node as this may disappear in the
/// future and most targets don't support it.
class CvtRndSatSDNode : public SDNode {
ISD::CvtCode CvtCode;
@@ -1814,7 +1797,7 @@ public:
}
};
-/// VTSDNode - This class is used to represent EVT's, which are used
+/// This class is used to represent EVT's, which are used
/// to parameterize some operations.
class VTSDNode : public SDNode {
EVT ValueType;
@@ -1832,8 +1815,7 @@ public:
}
};
-/// LSBaseSDNode - Base class for LoadSDNode and StoreSDNode
-///
+/// Base class for LoadSDNode and StoreSDNode
class LSBaseSDNode : public MemSDNode {
//! Operand array for load and store
/*!
@@ -1859,16 +1841,16 @@ public:
return getOperand(getOpcode() == ISD::LOAD ? 2 : 3);
}
- /// getAddressingMode - Return the addressing mode for this load or store:
+ /// Return the addressing mode for this load or store:
/// unindexed, pre-inc, pre-dec, post-inc, or post-dec.
ISD::MemIndexedMode getAddressingMode() const {
return ISD::MemIndexedMode((SubclassData >> 2) & 7);
}
- /// isIndexed - Return true if this is a pre/post inc/dec load/store.
+ /// Return true if this is a pre/post inc/dec load/store.
bool isIndexed() const { return getAddressingMode() != ISD::UNINDEXED; }
- /// isUnindexed - Return true if this is NOT a pre/post inc/dec load/store.
+ /// Return true if this is NOT a pre/post inc/dec load/store.
bool isUnindexed() const { return getAddressingMode() == ISD::UNINDEXED; }
static bool classof(const SDNode *N) {
@@ -1877,8 +1859,7 @@ public:
}
};
-/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
-///
+/// This class is used to represent ISD::LOAD nodes.
class LoadSDNode : public LSBaseSDNode {
friend class SelectionDAG;
LoadSDNode(SDValue *ChainPtrOff, unsigned Order, DebugLoc dl, SDVTList VTs,
@@ -1892,7 +1873,7 @@ class LoadSDNode : public LSBaseSDNode {
}
public:
- /// getExtensionType - Return whether this is a plain node,
+ /// Return whether this is a plain node,
/// or one of the varieties of value-extending loads.
ISD::LoadExtType getExtensionType() const {
return ISD::LoadExtType(SubclassData & 3);
@@ -1906,8 +1887,7 @@ public:
}
};
-/// StoreSDNode - This class is used to represent ISD::STORE nodes.
-///
+/// This class is used to represent ISD::STORE nodes.
class StoreSDNode : public LSBaseSDNode {
friend class SelectionDAG;
StoreSDNode(SDValue *ChainValuePtrOff, unsigned Order, DebugLoc dl,
@@ -1922,7 +1902,7 @@ class StoreSDNode : public LSBaseSDNode {
}
public:
- /// isTruncatingStore - Return true if the op does a truncation before store.
+ /// Return true if the op does a truncation before store.
/// For integers this is the same as doing a TRUNCATE and storing the result.
/// For floats, it is the same as doing an FP_ROUND and storing the result.
bool isTruncatingStore() const { return SubclassData & 1; }
@@ -1936,9 +1916,7 @@ public:
}
};
-/// MaskedLoadStoreSDNode - This is a base class is used to represent MLOAD and
-/// MSTORE nodes
-///
+/// This base class is used to represent MLOAD and MSTORE nodes
class MaskedLoadStoreSDNode : public MemSDNode {
// Operands
SDUse Ops[4];
@@ -1964,8 +1942,7 @@ public:
}
};
-/// MaskedLoadSDNode - This class is used to represent an MLOAD node
-///
+/// This class is used to represent an MLOAD node
class MaskedLoadSDNode : public MaskedLoadStoreSDNode {
public:
friend class SelectionDAG;
@@ -1986,8 +1963,7 @@ public:
}
};
-/// MaskedStoreSDNode - This class is used to represent an MSTORE node
-///
+/// This class is used to represent an MSTORE node
class MaskedStoreSDNode : public MaskedLoadStoreSDNode {
public:
@@ -1999,7 +1975,7 @@ public:
VTs, MemVT, MMO) {
SubclassData |= (unsigned short)isTrunc;
}
- /// isTruncatingStore - Return true if the op does a truncation before store.
+ /// Return true if the op does a truncation before store.
/// For integers this is the same as doing a TRUNCATE and storing the result.
/// For floats, it is the same as doing an FP_ROUND and storing the result.
bool isTruncatingStore() const { return SubclassData & 1; }
@@ -2011,10 +1987,9 @@ public:
}
};
-/// MachineSDNode - An SDNode that represents everything that will be needed
+/// An SDNode that represents everything that will be needed
/// to construct a MachineInstr. These nodes are created during the
/// instruction selection proper phase.
-///
class MachineSDNode : public SDNode {
public:
typedef MachineMemOperand **mmo_iterator;
@@ -2024,11 +1999,11 @@ private:
MachineSDNode(unsigned Opc, unsigned Order, const DebugLoc DL, SDVTList VTs)
: SDNode(Opc, Order, DL, VTs), MemRefs(nullptr), MemRefsEnd(nullptr) {}
- /// LocalOperands - Operands for this instruction, if they fit here. If
+ /// Operands for this instruction, if they fit here. If
/// they don't, this field is unused.
SDUse LocalOperands[4];
- /// MemRefs - Memory reference descriptions for this instruction.
+ /// Memory reference descriptions for this instruction.
mmo_iterator MemRefs;
mmo_iterator MemRefsEnd;
@@ -2037,7 +2012,7 @@ public:
mmo_iterator memoperands_end() const { return MemRefsEnd; }
bool memoperands_empty() const { return MemRefsEnd == MemRefs; }
- /// setMemRefs - Assign this MachineSDNodes's memory reference descriptor
+ /// Assign this MachineSDNodes's memory reference descriptor
/// list. This does not transfer ownership.
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd) {
for (mmo_iterator MMI = NewMemRefs, MME = NewMemRefsEnd; MMI != MME; ++MMI)
@@ -2063,12 +2038,6 @@ public:
}
bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
- const SDNodeIterator &operator=(const SDNodeIterator &I) {
- assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
- Operand = I.Operand;
- return *this;
- }
-
pointer operator*() const {
return Node->getOperand(Operand).getNode();
}
@@ -2108,60 +2077,51 @@ template <> struct GraphTraits<SDNode*> {
}
};
-/// LargestSDNode - The largest SDNode class.
-///
+/// The largest SDNode class.
typedef AtomicSDNode LargestSDNode;
-/// MostAlignedSDNode - The SDNode class with the greatest alignment
-/// requirement.
-///
+/// The SDNode class with the greatest alignment requirement.
typedef GlobalAddressSDNode MostAlignedSDNode;
namespace ISD {
- /// isNormalLoad - Returns true if the specified node is a non-extending
- /// and unindexed load.
+ /// Returns true if the specified node is a non-extending and unindexed load.
inline bool isNormalLoad(const SDNode *N) {
const LoadSDNode *Ld = dyn_cast<LoadSDNode>(N);
return Ld && Ld->getExtensionType() == ISD::NON_EXTLOAD &&
Ld->getAddressingMode() == ISD::UNINDEXED;
}
- /// isNON_EXTLoad - Returns true if the specified node is a non-extending
- /// load.
+ /// Returns true if the specified node is a non-extending load.
inline bool isNON_EXTLoad(const SDNode *N) {
return isa<LoadSDNode>(N) &&
cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
}
- /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
- ///
+ /// Returns true if the specified node is a EXTLOAD.
inline bool isEXTLoad(const SDNode *N) {
return isa<LoadSDNode>(N) &&
cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
}
- /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
- ///
+ /// Returns true if the specified node is a SEXTLOAD.
inline bool isSEXTLoad(const SDNode *N) {
return isa<LoadSDNode>(N) &&
cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
}
- /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
- ///
+ /// Returns true if the specified node is a ZEXTLOAD.
inline bool isZEXTLoad(const SDNode *N) {
return isa<LoadSDNode>(N) &&
cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
}
- /// isUNINDEXEDLoad - Returns true if the specified node is an unindexed load.
- ///
+ /// Returns true if the specified node is an unindexed load.
inline bool isUNINDEXEDLoad(const SDNode *N) {
return isa<LoadSDNode>(N) &&
cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
}
- /// isNormalStore - Returns true if the specified node is a non-truncating
+ /// Returns true if the specified node is a non-truncating
/// and unindexed store.
inline bool isNormalStore(const SDNode *N) {
const StoreSDNode *St = dyn_cast<StoreSDNode>(N);
@@ -2169,20 +2129,17 @@ namespace ISD {
St->getAddressingMode() == ISD::UNINDEXED;
}
- /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
- /// store.
+ /// Returns true if the specified node is a non-truncating store.
inline bool isNON_TRUNCStore(const SDNode *N) {
return isa<StoreSDNode>(N) && !cast<StoreSDNode>(N)->isTruncatingStore();
}
- /// isTRUNCStore - Returns true if the specified node is a truncating
- /// store.
+ /// Returns true if the specified node is a truncating store.
inline bool isTRUNCStore(const SDNode *N) {
return isa<StoreSDNode>(N) && cast<StoreSDNode>(N)->isTruncatingStore();
}
- /// isUNINDEXEDStore - Returns true if the specified node is an
- /// unindexed store.
+ /// Returns true if the specified node is an unindexed store.
inline bool isUNINDEXEDStore(const SDNode *N) {
return isa<StoreSDNode>(N) &&
cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
diff --git a/include/llvm/CodeGen/StackMapLivenessAnalysis.h b/include/llvm/CodeGen/StackMapLivenessAnalysis.h
deleted file mode 100644
index f67a6e9..0000000
--- a/include/llvm/CodeGen/StackMapLivenessAnalysis.h
+++ /dev/null
@@ -1,64 +0,0 @@
-//===--- StackMapLivenessAnalysis - StackMap Liveness Analysis --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass calculates the liveness for each basic block in a function and
-// attaches the register live-out information to a patchpoint intrinsic (if
-// present).
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H
-#define LLVM_CODEGEN_STACKMAPLIVENESSANALYSIS_H
-
-#include "llvm/CodeGen/LivePhysRegs.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-
-
-namespace llvm {
-
-/// \brief This pass calculates the liveness information for each basic block in
-/// a function and attaches the register live-out information to a patchpoint
-/// intrinsic if present.
-///
-/// This pass can be disabled via the -enable-patchpoint-liveness=false flag.
-/// The pass skips functions that don't have any patchpoint intrinsics. The
-/// information provided by this pass is optional and not required by the
-/// aformentioned intrinsic to function.
-class StackMapLiveness : public MachineFunctionPass {
- MachineFunction *MF;
- const TargetRegisterInfo *TRI;
- LivePhysRegs LiveRegs;
-public:
- static char ID;
-
- /// \brief Default construct and initialize the pass.
- StackMapLiveness();
-
- /// \brief Tell the pass manager which passes we depend on and what
- /// information we preserve.
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// \brief Calculate the liveness information for the given machine function.
- bool runOnMachineFunction(MachineFunction &MF) override;
-
-private:
- /// \brief Performs the actual liveness calculation for the function.
- bool calculateLiveness();
-
- /// \brief Add the current register live set to the instruction.
- void addLiveOutSetToMI(MachineInstr &MI);
-
- /// \brief Create a register mask and initialize it with the registers from
- /// the register live set.
- uint32_t *createRegisterMask() const;
-};
-
-} // llvm namespace
-
-#endif
diff --git a/include/llvm/CodeGen/StackMaps.h b/include/llvm/CodeGen/StackMaps.h
index 4e48afe..caec994 100644
--- a/include/llvm/CodeGen/StackMaps.h
+++ b/include/llvm/CodeGen/StackMaps.h
@@ -14,6 +14,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Support/Debug.h"
#include <map>
#include <vector>
@@ -245,7 +246,10 @@ private:
void emitConstantPoolEntries(MCStreamer &OS);
/// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call.
- void emitCallsiteEntries(MCStreamer &OS, const TargetRegisterInfo *TRI);
+ void emitCallsiteEntries(MCStreamer &OS);
+
+ void print(raw_ostream &OS);
+ void debug() { print(dbgs()); }
};
}
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 348c634..75920a3 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
@@ -88,6 +88,7 @@ public:
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
public:
virtual ~TargetLoweringObjectFileMachO() {}
+ TargetLoweringObjectFileMachO();
/// Extract the dependent library name from a linker option string. Returns
/// StringRef() if the option does not specify a library.
@@ -122,6 +123,12 @@ public:
MCSymbol *getCFIPersonalitySymbol(const GlobalValue *GV, Mangler &Mang,
const TargetMachine &TM,
MachineModuleInfo *MMI) const override;
+
+ /// Get MachO PC relative GOT entry relocation
+ const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
+ const MCValue &MV, int64_t Offset,
+ MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const override;
};
@@ -140,6 +147,14 @@ public:
SectionKind Kind, Mangler &Mang,
const TargetMachine &TM) const override;
+ void getNameWithPrefix(SmallVectorImpl<char> &OutName, const GlobalValue *GV,
+ bool CannotUsePrivateLabel, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
+ const MCSection *
+ getSectionForJumpTable(const Function &F, Mangler &Mang,
+ const TargetMachine &TM) const override;
+
/// Extract the dependent library name from a linker option string. Returns
/// StringRef() if the option does not specify a library.
StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override;
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
index 4e93940..e1a9fd3 100644
--- a/include/llvm/CodeGen/ValueTypes.h
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -34,10 +34,9 @@ namespace llvm {
Type *LLVMTy;
public:
- EVT() : V((MVT::SimpleValueType)(MVT::INVALID_SIMPLE_VALUE_TYPE)),
- LLVMTy(nullptr) {}
- EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) { }
- EVT(MVT S) : V(S), LLVMTy(nullptr) {}
+ LLVM_CONSTEXPR EVT() : V(MVT::INVALID_SIMPLE_VALUE_TYPE), LLVMTy(nullptr) {}
+ LLVM_CONSTEXPR EVT(MVT::SimpleValueType SVT) : V(SVT), LLVMTy(nullptr) {}
+ LLVM_CONSTEXPR EVT(MVT S) : V(S), LLVMTy(nullptr) {}
bool operator==(EVT VT) const {
return !(*this != VT);
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 86ae8bb..bd50d6e 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -33,9 +33,6 @@
/* Define to 1 if you have the `bcopy' function. */
#undef HAVE_BCOPY
-/* Define to 1 if you have the `ceilf' function. */
-#cmakedefine HAVE_CEILF ${HAVE_CEILF}
-
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
@@ -95,33 +92,6 @@
/* Define to 1 if you have the <ffi.h> header file. */
#cmakedefine HAVE_FFI_H ${HAVE_FFI_H}
-/* Set to 1 if the finite function is found in <ieeefp.h> */
-#cmakedefine HAVE_FINITE_IN_IEEEFP_H ${HAVE_FINITE_IN_IEEEFP_H}
-
-/* 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_EXP}
-
-/* Define to 1 if you have the `exp2' function. */
-#cmakedefine HAVE_EXP2 ${HAVE_EXP2}
-
-/* Define to 1 if you have the `exp10' function. */
-#cmakedefine HAVE_EXP10 ${HAVE_EXP10}
-
-/* Define to 1 if you have the `fmodf' function. */
-#cmakedefine HAVE_FMODF ${HAVE_FMODF}
-
/* Define to 1 if you have the `futimes' function. */
#cmakedefine HAVE_FUTIMES ${HAVE_FUTIMES}
@@ -152,18 +122,6 @@
/* Define to 1 if you have the `isatty' function. */
#cmakedefine HAVE_ISATTY 1
-/* Set to 1 if the isinf function is found in <cmath> */
-#cmakedefine HAVE_ISINF_IN_CMATH ${HAVE_ISINF_IN_CMATH}
-
-/* Set to 1 if the isinf function is found in <math.h> */
-#cmakedefine HAVE_ISINF_IN_MATH_H ${HAVE_ISINF_IN_MATH_H}
-
-/* Set to 1 if the isnan function is found in <cmath> */
-#cmakedefine HAVE_ISNAN_IN_CMATH ${HAVE_ISNAN_IN_CMATH}
-
-/* Set to 1 if the isnan function is found in <math.h> */
-#cmakedefine HAVE_ISNAN_IN_MATH_H ${HAVE_ISNAN_IN_MATH_H}
-
/* Define if you have the libdl library or equivalent. */
#cmakedefine HAVE_LIBDL ${HAVE_LIBDL}
@@ -247,18 +205,12 @@
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H}
-/* Define to 1 if you have the `nearbyintf' function. */
-#cmakedefine HAVE_NEARBYINTF ${HAVE_NEARBYINTF}
-
/* Define to 1 if you have the `opendir' function. */
#cmakedefine HAVE_OPENDIR ${HAVE_OPENDIR}
/* Define to 1 if you have the `posix_spawn' function. */
#cmakedefine HAVE_POSIX_SPAWN ${HAVE_POSIX_SPAWN}
-/* Define to 1 if you have the `powf' function. */
-#cmakedefine HAVE_POWF ${HAVE_POWF}
-
/* Define to 1 if you have the `pread' function. */
#cmakedefine HAVE_PREAD ${HAVE_PREAD}
@@ -289,15 +241,6 @@
/* Define to 1 if you have the `realpath' function. */
#cmakedefine HAVE_REALPATH ${HAVE_REALPATH}
-/* Define to 1 if you have the `rintf' function. */
-#undef HAVE_RINTF
-
-/* Define to 1 if you have the `round' function. */
-#cmakedefine HAVE_ROUND ${HAVE_ROUND}
-
-/* Define to 1 if you have the `roundf' function. */
-#undef HAVE_ROUNDF
-
/* Define to 1 if you have the `sbrk' function. */
#cmakedefine HAVE_SBRK ${HAVE_SBRK}
@@ -340,9 +283,6 @@
/* Define to 1 if you have the `strerror_r' function. */
#cmakedefine HAVE_STRERROR_R ${HAVE_STRERROR_R}
-/* Define to 1 if you have the `strtof' function. */
-#cmakedefine HAVE_STRTOF ${HAVE_STRTOF}
-
/* Define to 1 if you have the `strtoll' function. */
#cmakedefine HAVE_STRTOLL ${HAVE_STRTOLL}
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index c317bb1..67d7c84 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -39,9 +39,6 @@
/* Define to 1 if you have the `backtrace' function. */
#undef HAVE_BACKTRACE
-/* Define to 1 if you have the `ceilf' function. */
-#undef HAVE_CEILF
-
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
@@ -67,9 +64,6 @@
don't. */
#undef HAVE_DECL_STRERROR_S
-/* Define to 1 if you have the DIA SDK installed, and to 0 if you don't. */
-#undef HAVE_DIA_SDK
-
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
@@ -89,12 +83,6 @@
/* 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
@@ -110,15 +98,6 @@
/* Define to 1 if you have the <ffi.h> header file. */
#undef HAVE_FFI_H
-/* Set to 1 if the finite function is found in <ieeefp.h> */
-#undef HAVE_FINITE_IN_IEEEFP_H
-
-/* Define to 1 if you have the `floorf' function. */
-#undef HAVE_FLOORF
-
-/* Define to 1 if you have the `fmodf' function. */
-#undef HAVE_FMODF
-
/* Define to 1 if you have the `futimens' function. */
#undef HAVE_FUTIMENS
@@ -149,18 +128,6 @@
/* Define to 1 if you have the `isatty' function. */
#undef HAVE_ISATTY
-/* Set to 1 if the isinf function is found in <cmath> */
-#undef HAVE_ISINF_IN_CMATH
-
-/* Set to 1 if the isinf function is found in <math.h> */
-#undef HAVE_ISINF_IN_MATH_H
-
-/* Set to 1 if the isnan function is found in <cmath> */
-#undef HAVE_ISNAN_IN_CMATH
-
-/* Set to 1 if the isnan function is found in <math.h> */
-#undef HAVE_ISNAN_IN_MATH_H
-
/* Define if libedit is available on this platform. */
#undef HAVE_LIBEDIT
@@ -192,15 +159,6 @@
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
@@ -210,9 +168,6 @@
/* Define if mallinfo() is available on this platform. */
#undef HAVE_MALLINFO
-/* Define if mallctl() is available on this plaform. */
-#undef HAVE_MALLCTL
-
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
@@ -247,15 +202,9 @@
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
-/* Define to 1 if you have the `nearbyintf' function. */
-#undef HAVE_NEARBYINTF
-
/* Define to 1 if you have the `posix_spawn' function. */
#undef HAVE_POSIX_SPAWN
-/* Define to 1 if you have the `powf' function. */
-#undef HAVE_POWF
-
/* Define to 1 if you have the `pread' function. */
#undef HAVE_PREAD
@@ -280,15 +229,6 @@
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
-/* Define to 1 if you have the `rintf' function. */
-#undef HAVE_RINTF
-
-/* Define to 1 if you have the `round' function. */
-#undef HAVE_ROUND
-
-/* Define to 1 if you have the `roundf' function. */
-#undef HAVE_ROUNDF
-
/* Define to 1 if you have the `sbrk' function. */
#undef HAVE_SBRK
@@ -319,12 +259,6 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
-/* Set to 1 if the std::isinf function is found in <cmath> */
-#undef HAVE_STD_ISINF_IN_CMATH
-
-/* Set to 1 if the std::isnan function is found in <cmath> */
-#undef HAVE_STD_ISNAN_IN_CMATH
-
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
@@ -337,9 +271,6 @@
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
-/* Define to 1 if you have the `strtof' function. */
-#undef HAVE_STRTOF
-
/* Define to 1 if you have the `strtoll' function. */
#undef HAVE_STRTOLL
@@ -486,6 +417,9 @@
/* Installation directory for documentation */
#undef LLVM_DOCSDIR
+/* Define to enable checks that alter the LLVM C++ ABI */
+#undef LLVM_ENABLE_ABI_BREAKING_CHECKS
+
/* Define if threads enabled */
#undef LLVM_ENABLE_THREADS
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index d54003d..bb7dc06 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -101,4 +101,8 @@
/* Define if we link Polly to the tools */
#cmakedefine LINK_POLLY_INTO_TOOLS
+/* Define if LLVM is built with asserts and checks that change the layout of
+ client-visible data structures. */
+#cmakedefine LLVM_ENABLE_ABI_BREAKING_CHECKS
+
#endif
diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in
index 25a9295..03e482a 100644
--- a/include/llvm/Config/llvm-config.h.in
+++ b/include/llvm/Config/llvm-config.h.in
@@ -98,4 +98,7 @@
/* LLVM version string */
#undef LLVM_VERSION_STRING
+/* Define to enable checks that alter the LLVM C++ ABI */
+#undef LLVM_ENABLE_ABI_BREAKING_CHECKS
+
#endif
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
index bb05c30..6ab5d5c 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
@@ -18,18 +18,14 @@ namespace llvm {
class raw_ostream;
class DWARFAbbreviationDeclaration {
- uint32_t Code;
- uint32_t Tag;
- bool HasChildren;
-
+public:
struct AttributeSpec {
AttributeSpec(uint16_t Attr, uint16_t Form) : Attr(Attr), Form(Form) {}
uint16_t Attr;
uint16_t Form;
};
typedef SmallVector<AttributeSpec, 8> AttributeSpecVector;
- AttributeSpecVector AttributeSpecs;
-public:
+
DWARFAbbreviationDeclaration();
uint32_t getCode() const { return Code; }
@@ -53,6 +49,12 @@ public:
private:
void clear();
+
+ uint32_t Code;
+ uint32_t Tag;
+ bool HasChildren;
+
+ AttributeSpecVector AttributeSpecs;
};
}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index e34f096..47dbf5f 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -7,6 +7,9 @@
//
//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H
+#define LLVM_LIB_DEBUGINFO_DWARFACCELERATORTABLE_H
+
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
@@ -47,3 +50,5 @@ public:
};
}
+
+#endif
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index 4ee3bda..c930bd6 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -66,6 +66,8 @@ public:
void clear();
void dump(raw_ostream &OS) const;
bool extract(DataExtractor data, uint32_t *offset_ptr);
+ const std::vector<RangeListEntry> &getEntries() { return Entries; }
+
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
/// list. Has to be passed base address of the compile unit referencing this
/// range list.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 5bb6d1b..02f4681 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -63,7 +63,7 @@ public:
/// The passed DWARFUnit is allowed to be nullptr, in which
/// case no relocation processing will be performed and some
/// kind of forms that depend on Unit information are disallowed.
- /// \returns wether the extraction succeeded.
+ /// \returns whether the extraction succeeded.
bool extractValue(DataExtractor data, uint32_t *offset_ptr,
const DWARFUnit *u);
bool isInlinedCStr() const {
@@ -74,6 +74,7 @@ public:
/// DWARFFormValue has form class is suitable for representing Foo.
Optional<uint64_t> getAsReference(const DWARFUnit *U) const;
Optional<uint64_t> getAsUnsignedConstant() const;
+ Optional<int64_t> getAsSignedConstant() const;
Optional<const char *> getAsCString(const DWARFUnit *U) const;
Optional<uint64_t> getAsAddress(const DWARFUnit *U) const;
Optional<uint64_t> getAsSectionOffset() const;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index 628852f..29fa4a3 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -10,6 +10,7 @@
#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H
#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
index c71f35c..9308b8e 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIARawSymbol.h
@@ -24,7 +24,7 @@ public:
CComPtr<IDiaSymbol> getDiaSymbol() const { return Symbol; }
std::unique_ptr<IPDBEnumSymbols>
- DIARawSymbol::findChildren(PDB_SymType Type) const override;
+ findChildren(PDB_SymType Type) const override;
std::unique_ptr<IPDBEnumSymbols>
findChildren(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags) const override;
diff --git a/include/llvm/DebugInfo/PDB/DIA/DIASession.h b/include/llvm/DebugInfo/PDB/DIA/DIASession.h
index 141b9b0..6c72c3e 100644
--- a/include/llvm/DebugInfo/PDB/DIA/DIASession.h
+++ b/include/llvm/DebugInfo/PDB/DIA/DIASession.h
@@ -19,7 +19,8 @@ class DIASession : public IPDBSession {
public:
explicit DIASession(CComPtr<IDiaSession> DiaSession);
- static DIASession *createFromPdb(StringRef Path);
+ static PDB_ErrorCode createFromPdb(StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
uint64_t getLoadAddress() const override;
void setLoadAddress(uint64_t Address) override;
diff --git a/include/llvm/DebugInfo/PDB/PDB.h b/include/llvm/DebugInfo/PDB/PDB.h
index 7193eef..67878e9 100644
--- a/include/llvm/DebugInfo/PDB/PDB.h
+++ b/include/llvm/DebugInfo/PDB/PDB.h
@@ -16,8 +16,8 @@
namespace llvm {
class StringRef;
-std::unique_ptr<IPDBSession> createPDBReader(PDB_ReaderType Type,
- StringRef Path);
+PDB_ErrorCode createPDBReader(PDB_ReaderType Type, StringRef Path,
+ std::unique_ptr<IPDBSession> &Session);
}
#endif
diff --git a/include/llvm/DebugInfo/PDB/PDBExtras.h b/include/llvm/DebugInfo/PDB/PDBExtras.h
index cbbe171..48ce1c1 100644
--- a/include/llvm/DebugInfo/PDB/PDBExtras.h
+++ b/include/llvm/DebugInfo/PDB/PDBExtras.h
@@ -26,7 +26,8 @@ raw_ostream &operator<<(raw_ostream &OS, const PDB_ThunkOrdinal &Thunk);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Lang &Lang);
raw_ostream &operator<<(raw_ostream &OS, const PDB_SymType &Tag);
-raw_ostream &operator<<(raw_ostream &OS, const PDB_BuiltinType &Type);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
+raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
raw_ostream &operator<<(raw_ostream &OS, const PDB_UniqueId &Id);
raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
diff --git a/include/llvm/DebugInfo/PDB/PDBSymDumper.h b/include/llvm/DebugInfo/PDB/PDBSymDumper.h
index dee601c..65110f3 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymDumper.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymDumper.h
@@ -21,61 +21,37 @@ public:
PDBSymDumper(bool ShouldRequireImpl);
virtual ~PDBSymDumper();
- virtual void dump(const PDBSymbolAnnotation &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolBlock &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolCompiland &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolCompilandDetails &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolCompilandEnv &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolCustom &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolData &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolExe &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolFunc &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolFuncDebugEnd &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolFuncDebugStart &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolLabel &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolPublicSymbol &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolThunk &Symbol, raw_ostream &OS, int Indent);
- virtual void dump(const PDBSymbolTypeArray &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeBaseClass &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeBuiltin &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeCustom &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeDimension &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeEnum &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeFriend &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeFunctionArg &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeFunctionSig &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeManaged &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypePointer &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeTypedef &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeUDT &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeVTable &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolTypeVTableShape &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolUnknown &Symbol, raw_ostream &OS,
- int Indent);
- virtual void dump(const PDBSymbolUsingNamespace &Symbol, raw_ostream &OS,
- int Indent);
+ virtual void dump(const PDBSymbolAnnotation &Symbol);
+ virtual void dump(const PDBSymbolBlock &Symbol);
+ virtual void dump(const PDBSymbolCompiland &Symbol);
+ virtual void dump(const PDBSymbolCompilandDetails &Symbol);
+ virtual void dump(const PDBSymbolCompilandEnv &Symbol);
+ virtual void dump(const PDBSymbolCustom &Symbol);
+ virtual void dump(const PDBSymbolData &Symbol);
+ virtual void dump(const PDBSymbolExe &Symbol);
+ virtual void dump(const PDBSymbolFunc &Symbol);
+ virtual void dump(const PDBSymbolFuncDebugEnd &Symbol);
+ virtual void dump(const PDBSymbolFuncDebugStart &Symbol);
+ virtual void dump(const PDBSymbolLabel &Symbol);
+ virtual void dump(const PDBSymbolPublicSymbol &Symbol);
+ virtual void dump(const PDBSymbolThunk &Symbol);
+ virtual void dump(const PDBSymbolTypeArray &Symbol);
+ virtual void dump(const PDBSymbolTypeBaseClass &Symbol);
+ virtual void dump(const PDBSymbolTypeBuiltin &Symbol);
+ virtual void dump(const PDBSymbolTypeCustom &Symbol);
+ virtual void dump(const PDBSymbolTypeDimension &Symbol);
+ virtual void dump(const PDBSymbolTypeEnum &Symbol);
+ virtual void dump(const PDBSymbolTypeFriend &Symbol);
+ virtual void dump(const PDBSymbolTypeFunctionArg &Symbol);
+ virtual void dump(const PDBSymbolTypeFunctionSig &Symbol);
+ virtual void dump(const PDBSymbolTypeManaged &Symbol);
+ virtual void dump(const PDBSymbolTypePointer &Symbol);
+ virtual void dump(const PDBSymbolTypeTypedef &Symbol);
+ virtual void dump(const PDBSymbolTypeUDT &Symbol);
+ virtual void dump(const PDBSymbolTypeVTable &Symbol);
+ virtual void dump(const PDBSymbolTypeVTableShape &Symbol);
+ virtual void dump(const PDBSymbolUnknown &Symbol);
+ virtual void dump(const PDBSymbolUsingNamespace &Symbol);
private:
bool RequireImpl;
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h
index 36005eb..4360c54 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -53,8 +53,7 @@ public:
/// call dump() on the underlying RawSymbol, which allows us to discover
/// unknown properties, but individual implementations of PDBSymbol may
/// override the behavior to only dump known fields.
- virtual void dump(raw_ostream &OS, int Indent,
- PDBSymDumper &Dumper) const = 0;
+ virtual void dump(PDBSymDumper &Dumper) const = 0;
void defaultDump(raw_ostream &OS, int Indent) const;
PDB_SymType getSymTag() const;
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
index 347e30a..c055dd7 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolAnnotation.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Annotation)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
index a0091be..2ca1250 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolBlock.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Block)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
index 055e444..f8c796a 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompiland.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Compiland)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(isEditAndContinueEnabled)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
index 8836828..7f29d6b 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandDetails)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
void getFrontEndVersion(VersionInfo &Version) const {
RawSymbol->getFrontEndVersion(Version);
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
index c3502a0..7e2ea90 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CompilandEnv)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getName)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
index b433dde..86bfd57 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolCustom.h
@@ -28,7 +28,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Custom)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
void getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes);
FORWARD_SYMBOL_METHOD(getSymIndexId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolData.h b/include/llvm/DebugInfo/PDB/PDBSymbolData.h
index 8b9a657..79cbbf0 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolData.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolData.h
@@ -26,7 +26,7 @@ public:
std::unique_ptr<PDBSymbol> getType() const;
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAccess)
FORWARD_SYMBOL_METHOD(getAddressOffset)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
index 33046f3..7c5f302 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolExe.h
@@ -25,7 +25,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Exe)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAge)
FORWARD_SYMBOL_METHOD(getGuid)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
index 22ae6e0..9db41d5 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFunc.h
@@ -22,7 +22,7 @@ public:
PDBSymbolFunc(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> FuncSymbol);
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
std::unique_ptr<PDBSymbolTypeFunctionSig> getSignature() const;
std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
index bd49314..34d551c 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugEnd)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
index a62eada..7671be4 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FuncDebugStart)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
index d006495..9d9903a 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolLabel.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Label)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
index a8de89d..70dfcb5 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::PublicSymbol)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAddressOffset)
FORWARD_SYMBOL_METHOD(getAddressSection)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
index 88588f1..bd5a9b2 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolThunk.h
@@ -25,7 +25,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Thunk)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAccess)
FORWARD_SYMBOL_METHOD(getAddressOffset)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
index ca925f9..513a9ec 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeArray.h
@@ -26,7 +26,7 @@ public:
std::unique_ptr<PDBSymbol> getElementType() const;
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getArrayIndexTypeId)
FORWARD_SYMBOL_METHOD(isConstType)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
index a3dcc02..2a9a8a0 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BaseClass)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getAccess)
FORWARD_SYMBOL_METHOD(getClassParentId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
index 1cede08..69a2028 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::BuiltinType)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getBuiltinType)
FORWARD_SYMBOL_METHOD(isConstType)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
index 90a043f..c41c489 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::CustomType)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getOemId)
FORWARD_SYMBOL_METHOD(getOemSymbolId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
index f871681..3f22ed8 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Dimension)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getLowerBoundId)
FORWARD_SYMBOL_METHOD(getUpperBoundId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
index 2479f46..3188c71 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h
@@ -24,7 +24,10 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Enum)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
+
+ std::unique_ptr<PDBSymbolTypeUDT> getClassParent() const;
+ std::unique_ptr<PDBSymbolTypeBuiltin> getUnderlyingType() const;
FORWARD_SYMBOL_METHOD(getBuiltinType)
FORWARD_SYMBOL_METHOD(getClassParentId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
index 964246f..4d393d7 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Friend)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getName)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
index 22f1455..14f79d9 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::FunctionArg)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getLexicalParentId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
index 82bb1fd..4bb4265 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h
@@ -28,7 +28,7 @@ public:
std::unique_ptr<IPDBEnumSymbols> getArguments() const;
std::unique_ptr<PDBSymbol> getClassParent() const;
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
void dumpArgList(raw_ostream &OS) const;
FORWARD_SYMBOL_METHOD(getCallingConvention)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
index 42f5867..cbfcec8 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::ManagedType)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getName)
FORWARD_SYMBOL_METHOD(getSymIndexId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
index 8b2806f..33578ba 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypePointer.h
@@ -26,7 +26,7 @@ public:
std::unique_ptr<PDBSymbol> getPointeeType() const;
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getLength)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
index d3a9ca2..5ad83bb 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::Typedef)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getBuiltinType)
FORWARD_SYMBOL_METHOD(getClassParentId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
index bf912b8..99cc307 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UDT)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(getUnmodifiedTypeId)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
index 6b6d99b..6efc549 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTable)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getClassParentId)
FORWARD_SYMBOL_METHOD(isConstType)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
index e866106..f407595 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::VTableShape)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(isConstType)
FORWARD_SYMBOL_METHOD(getCount)
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
index 7f8c6f9..94bd2c1 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolUnknown.h
@@ -21,7 +21,7 @@ public:
PDBSymbolUnknown(const IPDBSession &PDBSession,
std::unique_ptr<IPDBRawSymbol> UnknownSymbol);
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
static bool classof(const PDBSymbol *S) {
return (S->getSymTag() == PDB_SymType::None ||
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
index 59ec16b..7072f34 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h
@@ -24,7 +24,7 @@ public:
DECLARE_PDB_SYMBOL_CONCRETE_TYPE(PDB_SymType::UsingNamespace)
- void dump(raw_ostream &OS, int Indent, PDBSymDumper &Dumper) const override;
+ void dump(PDBSymDumper &Dumper) const override;
FORWARD_SYMBOL_METHOD(getLexicalParentId)
FORWARD_SYMBOL_METHOD(getName)
diff --git a/include/llvm/DebugInfo/PDB/PDBTypes.h b/include/llvm/DebugInfo/PDB/PDBTypes.h
index 75b6475..686e08f 100644
--- a/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -418,6 +418,17 @@ enum class PDB_RegisterId {
enum class PDB_MemberAccess { Private = 1, Protected = 2, Public = 3 };
+enum class PDB_ErrorCode {
+ Success,
+ NoPdbImpl,
+ InvalidPath,
+ InvalidFileFormat,
+ InvalidParameter,
+ AlreadyLoaded,
+ UnknownError,
+ NoMemory
+};
+
struct VersionInfo {
uint32_t Major;
uint32_t Minor;
@@ -459,8 +470,31 @@ struct Variant {
uint16_t UInt16;
uint32_t UInt32;
uint64_t UInt64;
- void* Pointer;
};
+#define VARIANT_EQUAL_CASE(Enum) \
+ case PDB_VariantType::Enum: \
+ return Enum == Other.Enum;
+ bool operator==(const Variant &Other) const {
+ if (Type != Other.Type)
+ return false;
+ switch (Type) {
+ VARIANT_EQUAL_CASE(Bool)
+ VARIANT_EQUAL_CASE(Int8)
+ VARIANT_EQUAL_CASE(Int16)
+ VARIANT_EQUAL_CASE(Int32)
+ VARIANT_EQUAL_CASE(Int64)
+ VARIANT_EQUAL_CASE(Single)
+ VARIANT_EQUAL_CASE(Double)
+ VARIANT_EQUAL_CASE(UInt8)
+ VARIANT_EQUAL_CASE(UInt16)
+ VARIANT_EQUAL_CASE(UInt32)
+ VARIANT_EQUAL_CASE(UInt64)
+ default:
+ return true;
+ }
+ }
+#undef VARIANT_EQUAL_CASE
+ bool operator!=(const Variant &Other) const { return !(*this == Other); }
};
} // namespace llvm
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index 17de5c7..abdaa0c 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -510,9 +510,6 @@ private:
bool VerifyModules;
bool UseOrcMCJITReplacement;
- /// InitEngine - Does the common initialization of default options.
- void InitEngine();
-
public:
/// Default constructor for EngineBuilder.
EngineBuilder();
diff --git a/include/llvm/ExecutionEngine/JITSymbolFlags.h b/include/llvm/ExecutionEngine/JITSymbolFlags.h
new file mode 100644
index 0000000..450e948
--- /dev/null
+++ b/include/llvm/ExecutionEngine/JITSymbolFlags.h
@@ -0,0 +1,81 @@
+//===------ JITSymbolFlags.h - Flags for symbols in the JIT -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Symbol flags for symbols in the JIT (e.g. weak, exported).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H
+#define LLVM_EXECUTIONENGINE_JITSYMBOLFLAGS_H
+
+#include "llvm/IR/GlobalValue.h"
+
+namespace llvm {
+
+/// @brief Flags for symbols in the JIT.
+enum class JITSymbolFlags : char {
+ None = 0,
+ Weak = 1U << 0,
+ Exported = 1U << 1
+};
+
+inline JITSymbolFlags operator|(JITSymbolFlags LHS, JITSymbolFlags RHS) {
+ typedef std::underlying_type<JITSymbolFlags>::type UT;
+ return static_cast<JITSymbolFlags>(
+ static_cast<UT>(LHS) | static_cast<UT>(RHS));
+}
+
+inline JITSymbolFlags& operator |=(JITSymbolFlags &LHS, JITSymbolFlags RHS) {
+ LHS = LHS | RHS;
+ return LHS;
+}
+
+inline JITSymbolFlags operator&(JITSymbolFlags LHS, JITSymbolFlags RHS) {
+ typedef std::underlying_type<JITSymbolFlags>::type UT;
+ return static_cast<JITSymbolFlags>(
+ static_cast<UT>(LHS) & static_cast<UT>(RHS));
+}
+
+inline JITSymbolFlags& operator &=(JITSymbolFlags &LHS, JITSymbolFlags RHS) {
+ LHS = LHS & RHS;
+ return LHS;
+}
+
+/// @brief Base class for symbols in the JIT.
+class JITSymbolBase {
+public:
+ JITSymbolBase(JITSymbolFlags Flags) : Flags(Flags) {}
+
+ JITSymbolFlags getFlags() const { return Flags; }
+
+ bool isWeak() const {
+ return (Flags & JITSymbolFlags::Weak) == JITSymbolFlags::Weak;
+ }
+
+ bool isExported() const {
+ return (Flags & JITSymbolFlags::Exported) == JITSymbolFlags::Exported;
+ }
+
+ static JITSymbolFlags flagsFromGlobalValue(const GlobalValue &GV) {
+ JITSymbolFlags Flags = JITSymbolFlags::None;
+ if (GV.hasWeakLinkage())
+ Flags |= JITSymbolFlags::Weak;
+ if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
+ Flags |= JITSymbolFlags::Exported;
+ return Flags;
+
+ }
+
+private:
+ JITSymbolFlags Flags;
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
index 0e218e2..77b0c48 100644
--- a/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
@@ -142,9 +142,8 @@ public:
typedef std::function<uint64_t(const std::string &)> LookupFtor;
/// @brief Construct a compile-on-demand layer instance.
- CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context)
- : BaseLayer(BaseLayer),
- CompileCallbackMgr(BaseLayer, Context, 0, 64) {}
+ CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
+ : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
/// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT>
@@ -194,8 +193,8 @@ public:
/// below this one.
JITSymbol findSymbolIn(ModuleSetHandleT H, const std::string &Name,
bool ExportedSymbolsOnly) {
- BaseLayerModuleSetHandleListT &BaseLayerHandles = H->second;
- for (auto &BH : BaseLayerHandles) {
+
+ for (auto &BH : H->BaseLayerModuleSetHandles) {
if (auto Symbol = BaseLayer.findSymbolIn(BH, Name, ExportedSymbolsOnly))
return Symbol;
}
@@ -274,7 +273,7 @@ private:
// Set the compile actions for this module:
for (auto &KVPair : NewStubInfos) {
std::string BodyName = Mangle(KVPair->first + BodySuffix,
- *M.getDataLayout());
+ M.getDataLayout());
auto &CCInfo = KVPair->second;
CCInfo.setCompileAction(
[=](){
@@ -291,10 +290,10 @@ private:
for (auto &KVPair : StubInfos) {
std::string AddrName = Mangle(KVPair.first + AddrSuffix,
- *M.getDataLayout());
+ M.getDataLayout());
auto &CCInfo = KVPair.second;
CCInfo.setUpdateAction(
- CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName));
+ getLocalFPUpdater(BaseLayer, StubsH, AddrName));
}
}
@@ -345,7 +344,7 @@ private:
}
BaseLayerT &BaseLayer;
- CompileCallbackMgrT CompileCallbackMgr;
+ CompileCallbackMgrT &CompileCallbackMgr;
ModuleSetInfoListT ModuleSetInfos;
};
diff --git a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
index e9d3d34..8ce1d4d 100644
--- a/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
+++ b/include/llvm/ExecutionEngine/Orc/IndirectionUtils.h
@@ -26,10 +26,34 @@ namespace orc {
/// @brief Base class for JITLayer independent aspects of
/// JITCompileCallbackManager.
-template <typename TargetT>
class JITCompileCallbackManagerBase {
public:
+ typedef std::function<TargetAddress()> CompileFtor;
+ typedef std::function<void(TargetAddress)> UpdateFtor;
+
+ /// @brief Handle to a newly created compile callback. Can be used to get an
+ /// IR constant representing the address of the trampoline, and to set
+ /// the compile and update actions for the callback.
+ class CompileCallbackInfo {
+ public:
+ CompileCallbackInfo(Constant *Addr, CompileFtor &Compile,
+ UpdateFtor &Update)
+ : Addr(Addr), Compile(Compile), Update(Update) {}
+
+ Constant* getAddress() const { return Addr; }
+ void setCompileAction(CompileFtor Compile) {
+ this->Compile = std::move(Compile);
+ }
+ void setUpdateAction(UpdateFtor Update) {
+ this->Update = std::move(Update);
+ }
+ private:
+ Constant *Addr;
+ CompileFtor &Compile;
+ UpdateFtor &Update;
+ };
+
/// @brief Construct a JITCompileCallbackManagerBase.
/// @param ErrorHandlerAddress The address of an error handler in the target
/// process to be used if a compile callback fails.
@@ -41,10 +65,12 @@ public:
: ErrorHandlerAddress(ErrorHandlerAddress),
NumTrampolinesPerBlock(NumTrampolinesPerBlock) {}
+ virtual ~JITCompileCallbackManagerBase() {}
+
/// @brief Execute the callback for the given trampoline id. Called by the JIT
/// to compile functions on demand.
TargetAddress executeCompileCallback(TargetAddress TrampolineID) {
- typename TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID);
+ TrampolineMapT::iterator I = ActiveTrampolines.find(TrampolineID);
// FIXME: Also raise an error in the Orc error-handler when we finally have
// one.
if (I == ActiveTrampolines.end())
@@ -56,7 +82,7 @@ public:
// Moving the trampoline ID back to the available list first means there's at
// least one available trampoline if the compile action triggers a request for
// a new one.
- AvailableTrampolines.push_back(I->first - TargetT::CallSize);
+ AvailableTrampolines.push_back(I->first);
auto CallbackHandler = std::move(I->second);
ActiveTrampolines.erase(I);
@@ -67,14 +93,14 @@ public:
return ErrorHandlerAddress;
}
-protected:
+ /// @brief Get/create a compile callback with the given signature.
+ virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0;
- typedef std::function<TargetAddress()> CompileFtorT;
- typedef std::function<void(TargetAddress)> UpdateFtorT;
+protected:
struct CallbackHandler {
- CompileFtorT Compile;
- UpdateFtorT Update;
+ CompileFtor Compile;
+ UpdateFtor Update;
};
TargetAddress ErrorHandlerAddress;
@@ -87,15 +113,9 @@ protected:
/// @brief Manage compile callbacks.
template <typename JITLayerT, typename TargetT>
-class JITCompileCallbackManager :
- public JITCompileCallbackManagerBase<TargetT> {
+class JITCompileCallbackManager : public JITCompileCallbackManagerBase {
public:
- typedef typename JITCompileCallbackManagerBase<TargetT>::CompileFtorT
- CompileFtorT;
- typedef typename JITCompileCallbackManagerBase<TargetT>::UpdateFtorT
- UpdateFtorT;
-
/// @brief Construct a JITCompileCallbackManager.
/// @param JIT JIT layer to emit callback trampolines, etc. into.
/// @param Context LLVMContext to use for trampoline & resolve block modules.
@@ -108,39 +128,17 @@ public:
JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context,
TargetAddress ErrorHandlerAddress,
unsigned NumTrampolinesPerBlock)
- : JITCompileCallbackManagerBase<TargetT>(ErrorHandlerAddress,
- NumTrampolinesPerBlock),
+ : JITCompileCallbackManagerBase(ErrorHandlerAddress,
+ NumTrampolinesPerBlock),
JIT(JIT) {
emitResolverBlock(Context);
}
- /// @brief Handle to a newly created compile callback. Can be used to get an
- /// IR constant representing the address of the trampoline, and to set
- /// the compile and update actions for the callback.
- class CompileCallbackInfo {
- public:
- CompileCallbackInfo(Constant *Addr, CompileFtorT &Compile,
- UpdateFtorT &Update)
- : Addr(Addr), Compile(Compile), Update(Update) {}
-
- Constant* getAddress() const { return Addr; }
- void setCompileAction(CompileFtorT Compile) {
- this->Compile = std::move(Compile);
- }
- void setUpdateAction(UpdateFtorT Update) {
- this->Update = std::move(Update);
- }
- private:
- Constant *Addr;
- CompileFtorT &Compile;
- UpdateFtorT &Update;
- };
-
/// @brief Get/create a compile callback with the given signature.
- CompileCallbackInfo getCompileCallback(FunctionType &FT) {
+ CompileCallbackInfo getCompileCallback(FunctionType &FT) final {
TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext());
auto &CallbackHandler =
- this->ActiveTrampolines[TrampolineAddr + TargetT::CallSize];
+ this->ActiveTrampolines[TrampolineAddr];
Constant *AddrIntVal =
ConstantInt::get(Type::getInt64Ty(FT.getContext()), TrampolineAddr);
Constant *AddrPtrVal =
@@ -151,19 +149,6 @@ public:
CallbackHandler.Update);
}
- /// @brief Get a functor for updating the value of a named function pointer.
- UpdateFtorT getLocalFPUpdater(typename JITLayerT::ModuleSetHandleT H,
- std::string Name) {
- // FIXME: Move-capture Name once we can use C++14.
- return [=](TargetAddress Addr) {
- auto FPSym = JIT.findSymbolIn(H, Name, true);
- assert(FPSym && "Cannot find function pointer to update.");
- void *FPAddr = reinterpret_cast<void*>(
- static_cast<uintptr_t>(FPSym.getAddress()));
- memcpy(FPAddr, &Addr, sizeof(uintptr_t));
- };
- }
-
private:
std::vector<std::unique_ptr<Module>>
@@ -216,6 +201,22 @@ private:
TargetAddress ResolverBlockAddr;
};
+/// @brief Get an update functor for updating the value of a named function
+/// pointer.
+template <typename JITLayerT>
+JITCompileCallbackManagerBase::UpdateFtor
+getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H,
+ std::string Name) {
+ // FIXME: Move-capture Name once we can use C++14.
+ return [=,&JIT](TargetAddress Addr) {
+ auto FPSym = JIT.findSymbolIn(H, Name, true);
+ assert(FPSym && "Cannot find function pointer to update.");
+ void *FPAddr = reinterpret_cast<void*>(
+ static_cast<uintptr_t>(FPSym.getAddress()));
+ memcpy(FPAddr, &Addr, sizeof(uintptr_t));
+ };
+ }
+
GlobalVariable* createImplPointer(Function &F, const Twine &Name,
Constant *Initializer);
diff --git a/include/llvm/ExecutionEngine/Orc/JITSymbol.h b/include/llvm/ExecutionEngine/Orc/JITSymbol.h
index a670222..7c3ad56 100644
--- a/include/llvm/ExecutionEngine/Orc/JITSymbol.h
+++ b/include/llvm/ExecutionEngine/Orc/JITSymbol.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
#define LLVM_EXECUTIONENGINE_ORC_JITSYMBOL_H
+#include "llvm/ExecutionEngine/JITSymbolFlags.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <functional>
@@ -25,17 +26,19 @@ namespace orc {
typedef uint64_t TargetAddress;
/// @brief Represents a symbol in the JIT.
-class JITSymbol {
-public:
+class JITSymbol : public JITSymbolBase {
+public:
+
typedef std::function<TargetAddress()> GetAddressFtor;
/// @brief Create a 'null' symbol that represents failure to find a symbol
/// definition.
- JITSymbol(std::nullptr_t) : CachedAddr(0) {}
+ JITSymbol(std::nullptr_t)
+ : JITSymbolBase(JITSymbolFlags::None), CachedAddr(0) {}
/// @brief Create a symbol for a definition with a known address.
- JITSymbol(TargetAddress Addr)
- : CachedAddr(Addr) {}
+ JITSymbol(TargetAddress Addr, JITSymbolFlags Flags)
+ : JITSymbolBase(Flags), CachedAddr(Addr) {}
/// @brief Create a symbol for a definition that doesn't have a known address
/// yet.
@@ -46,8 +49,8 @@ public:
/// definition without actually materializing the definition up front. The
/// user can materialize the definition at any time by calling the getAddress
/// method.
- JITSymbol(GetAddressFtor GetAddress)
- : CachedAddr(0), GetAddress(std::move(GetAddress)) {}
+ JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
+ : JITSymbolBase(Flags), GetAddress(std::move(GetAddress)), CachedAddr(0) {}
/// @brief Returns true if the symbol exists, false otherwise.
explicit operator bool() const { return CachedAddr || GetAddress; }
@@ -64,8 +67,8 @@ public:
}
private:
- TargetAddress CachedAddr;
GetAddressFtor GetAddress;
+ TargetAddress CachedAddr;
};
} // End namespace orc.
diff --git a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
index 2a94abe..ac5fccf 100644
--- a/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/LazyEmittingLayer.h
@@ -45,23 +45,25 @@ private:
JITSymbol find(StringRef Name, bool ExportedSymbolsOnly, BaseLayerT &B) {
switch (EmitState) {
case NotEmitted:
- if (provides(Name, ExportedSymbolsOnly)) {
+ if (auto GV = searchGVs(Name, ExportedSymbolsOnly)) {
// Create a std::string version of Name to capture here - the argument
// (a StringRef) may go away before the lambda is executed.
- // FIXME: Use capture-init when we move to C++14.
+ // FIXME: Use capture-init when we move to C++14.
std::string PName = Name;
- return JITSymbol(
- [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
- if (this->EmitState == Emitting)
- return 0;
- else if (this->EmitState == NotEmitted) {
- this->EmitState = Emitting;
- Handle = this->emitToBaseLayer(B);
- this->EmitState = Emitted;
- }
- return B.findSymbolIn(Handle, PName, ExportedSymbolsOnly)
- .getAddress();
- });
+ JITSymbolFlags Flags = JITSymbolBase::flagsFromGlobalValue(*GV);
+ auto GetAddress =
+ [this, ExportedSymbolsOnly, PName, &B]() -> TargetAddress {
+ if (this->EmitState == Emitting)
+ return 0;
+ else if (this->EmitState == NotEmitted) {
+ this->EmitState = Emitting;
+ Handle = this->emitToBaseLayer(B);
+ this->EmitState = Emitted;
+ }
+ auto Sym = B.findSymbolIn(Handle, PName, ExportedSymbolsOnly);
+ return Sym.getAddress();
+ };
+ return JITSymbol(std::move(GetAddress), Flags);
} else
return nullptr;
case Emitting:
@@ -98,7 +100,8 @@ private:
std::unique_ptr<RTDyldMemoryManager> MM);
protected:
- virtual bool provides(StringRef Name, bool ExportedSymbolsOnly) const = 0;
+ virtual const GlobalValue* searchGVs(StringRef Name,
+ bool ExportedSymbolsOnly) const = 0;
virtual BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) = 0;
private:
@@ -115,46 +118,48 @@ private:
protected:
- BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
- // We don't need the mangled names set any more: Once we've emitted this
- // to the base layer we'll just look for symbols there.
- MangledNames.reset();
- return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
- }
-
- bool provides(StringRef Name, bool ExportedSymbolsOnly) const override {
+ const GlobalValue* searchGVs(StringRef Name,
+ bool ExportedSymbolsOnly) const override {
// FIXME: We could clean all this up if we had a way to reliably demangle
// names: We could just demangle name and search, rather than
// mangling everything else.
// If we have already built the mangled name set then just search it.
- if (MangledNames) {
- auto VI = MangledNames->find(Name);
- if (VI == MangledNames->end())
- return false;
- return !ExportedSymbolsOnly || VI->second;
+ if (MangledSymbols) {
+ auto VI = MangledSymbols->find(Name);
+ if (VI == MangledSymbols->end())
+ return nullptr;
+ auto GV = VI->second;
+ if (!ExportedSymbolsOnly || GV->hasDefaultVisibility())
+ return GV;
+ return nullptr;
}
// If we haven't built the mangled name set yet, try to build it. As an
// optimization this will leave MangledNames set to nullptr if we find
// Name in the process of building the set.
- buildMangledNames(Name, ExportedSymbolsOnly);
- if (!MangledNames)
- return true;
- return false;
+ return buildMangledSymbols(Name, ExportedSymbolsOnly);
+ }
+
+ BaseLayerHandleT emitToBaseLayer(BaseLayerT &BaseLayer) override {
+ // We don't need the mangled names set any more: Once we've emitted this
+ // to the base layer we'll just look for symbols there.
+ MangledSymbols.reset();
+ return BaseLayer.addModuleSet(std::move(Ms), std::move(MM));
}
private:
// If the mangled name of the given GlobalValue matches the given search
// name (and its visibility conforms to the ExportedSymbolsOnly flag) then
- // just return 'true'. Otherwise, add the mangled name to the Names map and
- // return 'false'.
- bool addGlobalValue(StringMap<bool> &Names, const GlobalValue &GV,
- const Mangler &Mang, StringRef SearchName,
- bool ExportedSymbolsOnly) const {
+ // return the symbol. Otherwise, add the mangled name to the Names map and
+ // return nullptr.
+ const GlobalValue* addGlobalValue(StringMap<const GlobalValue*> &Names,
+ const GlobalValue &GV,
+ const Mangler &Mang, StringRef SearchName,
+ bool ExportedSymbolsOnly) const {
// Modules don't "provide" decls or common symbols.
if (GV.isDeclaration() || GV.hasCommonLinkage())
- return false;
+ return nullptr;
// Mangle the GV name.
std::string MangledName;
@@ -167,39 +172,42 @@ private:
// bail out early.
if (MangledName == SearchName)
if (!ExportedSymbolsOnly || GV.hasDefaultVisibility())
- return true;
+ return &GV;
// Otherwise add this to the map for later.
- Names[MangledName] = GV.hasDefaultVisibility();
- return false;
+ Names[MangledName] = &GV;
+ return nullptr;
}
- // Build the MangledNames map. Bails out early (with MangledNames left set
+ // Build the MangledSymbols map. Bails out early (with MangledSymbols left set
// to nullptr) if the given SearchName is found while building the map.
- void buildMangledNames(StringRef SearchName,
- bool ExportedSymbolsOnly) const {
- assert(!MangledNames && "Mangled names map already exists?");
+ const GlobalValue* buildMangledSymbols(StringRef SearchName,
+ bool ExportedSymbolsOnly) const {
+ assert(!MangledSymbols && "Mangled symbols map already exists?");
- auto Names = llvm::make_unique<StringMap<bool>>();
+ auto Symbols = llvm::make_unique<StringMap<const GlobalValue*>>();
for (const auto &M : Ms) {
- Mangler Mang(M->getDataLayout());
+ Mangler Mang(&M->getDataLayout());
- for (const auto &GV : M->globals())
- if (addGlobalValue(*Names, GV, Mang, SearchName, ExportedSymbolsOnly))
- return;
+ for (const auto &V : M->globals())
+ if (auto GV = addGlobalValue(*Symbols, V, Mang, SearchName,
+ ExportedSymbolsOnly))
+ return GV;
for (const auto &F : *M)
- if (addGlobalValue(*Names, F, Mang, SearchName, ExportedSymbolsOnly))
- return;
+ if (auto GV = addGlobalValue(*Symbols, F, Mang, SearchName,
+ ExportedSymbolsOnly))
+ return GV;
}
- MangledNames = std::move(Names);
+ MangledSymbols = std::move(Symbols);
+ return nullptr;
}
ModuleSetT Ms;
std::unique_ptr<RTDyldMemoryManager> MM;
- mutable std::unique_ptr<StringMap<bool>> MangledNames;
+ mutable std::unique_ptr<StringMap<const GlobalValue*>> MangledSymbols;
};
typedef std::list<std::unique_ptr<EmissionDeferredSet>> ModuleSetListT;
diff --git a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
index 36af0fe..9838991 100644
--- a/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
+++ b/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
@@ -51,10 +51,8 @@ protected:
return RTDyld->loadObject(Obj);
}
- TargetAddress getSymbolAddress(StringRef Name, bool ExportedSymbolsOnly) {
- if (ExportedSymbolsOnly)
- return RTDyld->getExportedSymbolLoadAddress(Name);
- return RTDyld->getSymbolLoadAddress(Name);
+ RuntimeDyld::SymbolInfo getSymbol(StringRef Name) const {
+ return RTDyld->getSymbol(Name);
}
bool NeedsFinalization() const { return (State == Raw); }
@@ -214,28 +212,32 @@ public:
/// given object set.
JITSymbol findSymbolIn(ObjSetHandleT H, StringRef Name,
bool ExportedSymbolsOnly) {
- if (auto Addr = H->getSymbolAddress(Name, ExportedSymbolsOnly)) {
- if (!H->NeedsFinalization()) {
- // If this instance has already been finalized then we can just return
- // the address.
- return JITSymbol(Addr);
- } else {
- // If this instance needs finalization return a functor that will do it.
- // The functor still needs to double-check whether finalization is
- // required, in case someone else finalizes this set before the functor
- // is called.
- return JITSymbol(
- [this, Addr, H]() {
- if (H->NeedsFinalization()) {
- H->Finalize();
- if (NotifyFinalized)
- NotifyFinalized(H);
- }
- return Addr;
- });
+ if (auto Sym = H->getSymbol(Name)) {
+ if (Sym.isExported() || !ExportedSymbolsOnly) {
+ auto Addr = Sym.getAddress();
+ auto Flags = Sym.getFlags();
+ if (!H->NeedsFinalization()) {
+ // If this instance has already been finalized then we can just return
+ // the address.
+ return JITSymbol(Addr, Flags);
+ } else {
+ // If this instance needs finalization return a functor that will do
+ // it. The functor still needs to double-check whether finalization is
+ // required, in case someone else finalizes this set before the
+ // functor is called.
+ auto GetAddress =
+ [this, Addr, H]() {
+ if (H->NeedsFinalization()) {
+ H->Finalize();
+ if (NotifyFinalized)
+ NotifyFinalized(H);
+ }
+ return Addr;
+ };
+ return JITSymbol(std::move(GetAddress), Flags);
+ }
}
}
-
return nullptr;
}
diff --git a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h
index c6f866a..309f5a9 100644
--- a/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h
+++ b/include/llvm/ExecutionEngine/Orc/OrcTargetSupport.h
@@ -25,15 +25,12 @@ public:
/// @brief Insert module-level inline callback asm into module M for the
/// symbols managed by JITResolveCallbackHandler J.
- static void insertResolverBlock(
- Module &M,
- JITCompileCallbackManagerBase<OrcX86_64> &JCBM);
+ static void insertResolverBlock(Module &M,
+ JITCompileCallbackManagerBase &JCBM);
/// @brief Get a label name from the given index.
typedef std::function<std::string(unsigned)> LabelNameFtor;
- static const unsigned CallSize = 6;
-
/// @brief Insert the requested number of trampolines into the given module.
/// @param M Module to insert the call block into.
/// @param NumCalls Number of calls to create in the call block.
diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h
index 08cfa39..fe0ccda 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -14,6 +14,7 @@
#ifndef LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
#define LLVM_EXECUTIONENGINE_RUNTIMEDYLD_H
+#include "JITSymbolFlags.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/Support/Memory.h"
@@ -28,7 +29,7 @@ namespace object {
class RuntimeDyldImpl;
class RuntimeDyldCheckerImpl;
-
+
class RuntimeDyld {
friend class RuntimeDyldCheckerImpl;
@@ -47,6 +48,18 @@ protected:
void reassignSectionAddress(unsigned SectionID, uint64_t Addr);
public:
+ /// \brief Information about a named symbol.
+ class SymbolInfo : public JITSymbolBase {
+ public:
+ SymbolInfo(std::nullptr_t) : JITSymbolBase(JITSymbolFlags::None), Address(0) {}
+ SymbolInfo(uint64_t Address, JITSymbolFlags Flags)
+ : JITSymbolBase(Flags), Address(Address) {}
+ explicit operator bool() const { return Address != 0; }
+ uint64_t getAddress() const { return Address; }
+ private:
+ uint64_t Address;
+ };
+
/// \brief Information about the loaded object.
class LoadedObjectInfo {
friend class RuntimeDyldImpl;
@@ -79,15 +92,11 @@ public:
/// Get the address of our local copy of the symbol. This may or may not
/// be the address used for relocation (clients can copy the data around
/// and resolve relocatons based on where they put it).
- void *getSymbolAddress(StringRef Name) const;
-
- /// Get the address of the target copy of the symbol (works for both exported
- /// and non-exported symbols). This is the address used for relocation.
- uint64_t getSymbolLoadAddress(StringRef Name) const;
+ void *getSymbolLocalAddress(StringRef Name) const;
- /// Get the address of the target copy of the symbol (works for exported
- /// symbols only). This is the address used for relocation.
- uint64_t getExportedSymbolLoadAddress(StringRef Name) const;
+ /// Get the target address and flags for the named symbol.
+ /// This address is the one used for relocation.
+ SymbolInfo getSymbol(StringRef Name) const;
/// Resolve the relocations for all symbols we currently know about.
void resolveRelocations();
diff --git a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index 23936a6..31ce151 100644
--- a/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -86,12 +86,12 @@ public:
/// \brief Returns the address of the requested section (or an error message
/// in the second element of the pair if the address cannot be found).
///
- /// if 'LinkerAddress' is true, this returns the address of the section
- /// within the linker's memory. If 'LinkerAddress' is false it returns the
+ /// if 'LocalAddress' is true, this returns the address of the section
+ /// within the linker's memory. If 'LocalAddress' is false it returns the
/// address within the target process (i.e. the load address).
std::pair<uint64_t, std::string> getSectionAddr(StringRef FileName,
StringRef SectionName,
- bool LinkerAddress);
+ bool LocalAddress);
private:
std::unique_ptr<RuntimeDyldCheckerImpl> Impl;
diff --git a/include/llvm/IR/BasicBlock.h b/include/llvm/IR/BasicBlock.h
index 185fc29..8f5cdeb 100644
--- a/include/llvm/IR/BasicBlock.h
+++ b/include/llvm/IR/BasicBlock.h
@@ -119,7 +119,11 @@ public:
const Function *getParent() const { return Parent; }
Function *getParent() { return Parent; }
- const DataLayout *getDataLayout() const;
+ /// \brief Return the module owning the function this basic block belongs to,
+ /// or nullptr it the function does not have a module.
+ ///
+ /// Note: this is undefined behavior if the block does not have a parent.
+ const Module *getModule() const;
/// \brief Returns the terminator instruction if the block is well formed or
/// null if the block is not well formed.
diff --git a/include/llvm/IR/CFG.h b/include/llvm/IR/CFG.h
index 8476431..f78220a 100644
--- a/include/llvm/IR/CFG.h
+++ b/include/llvm/IR/CFG.h
@@ -121,7 +121,7 @@ public:
typedef typename super::reference reference;
private:
- const Term_ Term;
+ Term_ Term;
unsigned idx;
typedef SuccIterator<Term_, BB_> Self;
@@ -136,6 +136,8 @@ private:
public:
explicit SuccessorProxy(const Self &it) : it(it) {}
+ SuccessorProxy(const SuccessorProxy&) = default;
+
SuccessorProxy &operator=(SuccessorProxy r) {
*this = reference(r);
return *this;
@@ -165,12 +167,6 @@ public:
idx = 0;
}
- inline const Self &operator=(const Self &I) {
- assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
- idx = I.idx;
- return *this;
- }
-
/// getSuccessorIndex - This is used to interface between code that wants to
/// operate on terminator instructions directly.
unsigned getSuccessorIndex() const { return idx; }
diff --git a/include/llvm/IR/CallSite.h b/include/llvm/IR/CallSite.h
index a4ea243..9c87936 100644
--- a/include/llvm/IR/CallSite.h
+++ b/include/llvm/IR/CallSite.h
@@ -151,7 +151,7 @@ public:
IterTy arg_end() const { return (*this)->op_end() - getArgumentEndOffset(); }
bool arg_empty() const { return arg_end() == arg_begin(); }
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
-
+
/// getType - Return the type of the instruction that generated this call site
///
Type *getType() const { return (*this)->getType(); }
diff --git a/include/llvm/IR/ConstantRange.h b/include/llvm/IR/ConstantRange.h
index 5e8cd34..9ded3ca 100644
--- a/include/llvm/IR/ConstantRange.h
+++ b/include/llvm/IR/ConstantRange.h
@@ -33,6 +33,7 @@
#define LLVM_IR_CONSTANTRANGE_H
#include "llvm/ADT/APInt.h"
+#include "llvm/IR/InstrTypes.h"
#include "llvm/Support/DataTypes.h"
namespace llvm {
@@ -59,15 +60,27 @@ public:
/// assert out if the two APInt's are not the same bit width.
ConstantRange(APIntMoveTy Lower, APIntMoveTy Upper);
- /// Produce the smallest range that contains all values that
- /// might satisfy the comparison specified by Pred when compared to any value
- /// contained within Other.
+ /// Produce the smallest range such that all values that may satisfy the given
+ /// predicate with any value contained within Other is contained in the
+ /// returned range. Formally, this returns a superset of
+ /// 'union over all y in Other . { x : icmp op x y is true }'. If the exact
+ /// answer is not representable as a ConstantRange, the return value will be a
+ /// proper superset of the above.
///
- /// Solves for range X in 'for all x in X, there exists a y in Y such that
- /// icmp op x, y is true'. Every value that might make the comparison true
- /// is included in the resulting range.
- static ConstantRange makeICmpRegion(unsigned Pred,
- const ConstantRange &Other);
+ /// Example: Pred = ult and Other = i8 [2, 5) returns Result = [0, 4)
+ static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred,
+ const ConstantRange &Other);
+
+ /// Produce the largest range such that all values in the returned range
+ /// satisfy the given predicate with all values contained within Other.
+ /// Formally, this returns a subset of
+ /// 'intersection over all y in Other . { x : icmp op x y is true }'. If the
+ /// exact answer is not representable as a ConstantRange, the return value
+ /// will be a proper subset of the above.
+ ///
+ /// Example: Pred = ult and Other = i8 [2, 5) returns [0, 2)
+ static ConstantRange makeSatisfyingICmpRegion(CmpInst::Predicate Pred,
+ const ConstantRange &Other);
/// Return the lower value for this range.
///
@@ -208,8 +221,8 @@ public:
ConstantRange sub(const ConstantRange &Other) const;
/// Return a new range representing the possible values resulting
- /// from a multiplication of a value in this range and a value in \p Other.
- /// TODO: This isn't fully implemented yet.
+ /// from a multiplication of a value in this range and a value in \p Other,
+ /// treating both this and \p Other as unsigned ranges.
ConstantRange multiply(const ConstantRange &Other) const;
/// Return a new range representing the possible values resulting
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index 9479ba4..3e1f974 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -108,7 +108,14 @@ private:
unsigned StackNaturalAlign;
- enum ManglingModeT { MM_None, MM_ELF, MM_MachO, MM_WINCOFF, MM_Mips };
+ enum ManglingModeT {
+ MM_None,
+ MM_ELF,
+ MM_MachO,
+ MM_WinCOFF,
+ MM_WinCOFFX86,
+ MM_Mips
+ };
ManglingModeT ManglingMode;
SmallVector<unsigned char, 8> LegalIntWidths;
@@ -116,6 +123,9 @@ private:
/// \brief Primitive type alignment data.
SmallVector<LayoutAlignElem, 16> Alignments;
+ /// \brief The string representation used to create this DataLayout
+ std::string StringRepresentation;
+
typedef SmallVector<PointerAlignElem, 8> PointersTy;
PointersTy Pointers;
@@ -185,6 +195,7 @@ public:
DataLayout &operator=(const DataLayout &DL) {
clear();
+ StringRepresentation = DL.StringRepresentation;
BigEndian = DL.isBigEndian();
StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode;
@@ -209,8 +220,12 @@ public:
/// \brief Returns the string representation of the DataLayout.
///
/// This representation is in the same format accepted by the string
- /// constructor above.
- std::string getStringRepresentation() const;
+ /// constructor above. This should not be used to compare two DataLayout as
+ /// different string can represent the same layout.
+ std::string getStringRepresentation() const { return StringRepresentation; }
+
+ /// \brief Test if the DataLayout was constructed from an empty string.
+ bool isDefault() const { return StringRepresentation.empty(); }
/// \brief Returns true if the specified type is known to be a native integer
/// type supported by the CPU.
@@ -236,7 +251,7 @@ public:
unsigned getStackAlignment() const { return StackNaturalAlign; }
bool hasMicrosoftFastStdCallMangling() const {
- return ManglingMode == MM_WINCOFF;
+ return ManglingMode == MM_WinCOFFX86;
}
bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; }
@@ -244,7 +259,7 @@ public:
const char *getLinkerPrivateGlobalPrefix() const {
if (ManglingMode == MM_MachO)
return "l";
- return getPrivateGlobalPrefix();
+ return "";
}
char getGlobalPrefix() const {
@@ -252,9 +267,10 @@ public:
case MM_None:
case MM_ELF:
case MM_Mips:
+ case MM_WinCOFF:
return '\0';
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFFX86:
return '_';
}
llvm_unreachable("invalid mangling mode");
@@ -269,7 +285,8 @@ public:
case MM_Mips:
return "$";
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFF:
+ case MM_WinCOFFX86:
return "L";
}
llvm_unreachable("invalid mangling mode");
@@ -451,22 +468,6 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) {
return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P));
}
-class DataLayoutPass : public ImmutablePass {
- DataLayout DL;
-
-public:
- /// This has to exist, because this is a pass, but it should never be used.
- DataLayoutPass();
- ~DataLayoutPass();
-
- const DataLayout &getDataLayout() const { return DL; }
-
- static char ID; // Pass identification, replacement for typeid
-
- bool doFinalization(Module &M) override;
- bool doInitialization(Module &M) override;
-};
-
/// Used to lazily calculate structure layout information for a target machine,
/// based on the DataLayout structure.
class StructLayout {
diff --git a/include/llvm/IR/DebugInfo.h b/include/llvm/IR/DebugInfo.h
index d2e5975..0163c05 100644
--- a/include/llvm/IR/DebugInfo.h
+++ b/include/llvm/IR/DebugInfo.h
@@ -165,7 +165,6 @@ protected:
GlobalVariable *getGlobalVariableField(unsigned Elt) const;
Constant *getConstantField(unsigned Elt) const;
Function *getFunctionField(unsigned Elt) const;
- void replaceFunctionField(unsigned Elt, Function *F);
public:
explicit DIDescriptor(const MDNode *N = nullptr) : DbgNode(N) {}
@@ -175,6 +174,10 @@ public:
MDNode *get() const { return const_cast<MDNode *>(DbgNode); }
operator MDNode *() const { return get(); }
MDNode *operator->() const { return get(); }
+ MDNode &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
// An explicit operator bool so that we can do testing of DI values
// easily.
@@ -215,29 +218,49 @@ public:
return getHeaderIterator(Index).getNumber<T>();
}
- uint16_t getTag() const { return getHeaderFieldAs<uint16_t>(0); }
-
- bool isDerivedType() const;
- bool isCompositeType() const;
- bool isSubroutineType() const;
- bool isBasicType() const;
- bool isVariable() const;
- bool isSubprogram() const;
- bool isGlobalVariable() const;
- bool isScope() const;
- bool isFile() const;
- bool isCompileUnit() const;
- bool isNameSpace() const;
- bool isLexicalBlockFile() const;
- bool isLexicalBlock() const;
- bool isSubrange() const;
- bool isEnumerator() const;
- bool isType() const;
- bool isTemplateTypeParameter() const;
- bool isTemplateValueParameter() const;
- bool isObjCProperty() const;
- bool isImportedEntity() const;
- bool isExpression() const;
+ uint16_t getTag() const {
+ if (auto *N = dyn_cast_or_null<DebugNode>(get()))
+ return N->getTag();
+ return 0;
+ }
+
+ bool isDerivedType() const { return get() && isa<MDDerivedTypeBase>(get()); }
+ bool isCompositeType() const {
+ return get() && isa<MDCompositeTypeBase>(get());
+ }
+ bool isSubroutineType() const {
+ return get() && isa<MDSubroutineType>(get());
+ }
+ bool isBasicType() const { return get() && isa<MDBasicType>(get()); }
+ bool isVariable() const { return get() && isa<MDLocalVariable>(get()); }
+ bool isSubprogram() const { return get() && isa<MDSubprogram>(get()); }
+ bool isGlobalVariable() const {
+ return get() && isa<MDGlobalVariable>(get());
+ }
+ bool isScope() const { return get() && isa<MDScope>(get()); }
+ bool isFile() const { return get() && isa<MDFile>(get()); }
+ bool isCompileUnit() const { return get() && isa<MDCompileUnit>(get()); }
+ bool isNameSpace() const{ return get() && isa<MDNamespace>(get()); }
+ bool isLexicalBlockFile() const {
+ return get() && isa<MDLexicalBlockFile>(get());
+ }
+ bool isLexicalBlock() const {
+ return get() && isa<MDLexicalBlockBase>(get());
+ }
+ bool isSubrange() const { return get() && isa<MDSubrange>(get()); }
+ bool isEnumerator() const { return get() && isa<MDEnumerator>(get()); }
+ bool isType() const { return get() && isa<MDType>(get()); }
+ bool isTemplateTypeParameter() const {
+ return get() && isa<MDTemplateTypeParameter>(get());
+ }
+ bool isTemplateValueParameter() const {
+ return get() && isa<MDTemplateValueParameter>(get());
+ }
+ bool isObjCProperty() const { return get() && isa<MDObjCProperty>(get()); }
+ bool isImportedEntity() const {
+ return get() && isa<MDImportedEntity>(get());
+ }
+ bool isExpression() const { return get() && isa<MDExpression>(get()); }
void print(raw_ostream &OS) const;
void dump() const;
@@ -247,29 +270,43 @@ public:
void replaceAllUsesWith(MDNode *D);
};
-#define RETURN_FROM_RAW(VALID, DEFAULT) \
+#define RETURN_FROM_RAW(VALID, UNUSED) \
do { \
- if (auto *N = getRaw()) \
- return VALID; \
- return DEFAULT; \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return VALID; \
} while (false)
#define RETURN_DESCRIPTOR_FROM_RAW(DESC, VALID) \
do { \
- if (auto *N = getRaw()) \
- return DESC(dyn_cast_or_null<MDNode>(VALID)); \
- return DESC(static_cast<const MDNode *>(nullptr)); \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return DESC(dyn_cast_or_null<MDNode>(VALID)); \
+ } while (false)
+#define RETURN_REF_FROM_RAW(REF, VALID) \
+ do { \
+ auto *N = get(); \
+ assert(N && "Expected non-null in accessor"); \
+ return REF::get(VALID); \
} while (false)
/// \brief This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DISubrange(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DISubrange(const MDSubrange *N) : DIDescriptor(N) {}
+
+ MDSubrange *get() const {
+ return cast_or_null<MDSubrange>(DIDescriptor::get());
+ }
+ operator MDSubrange *() const { return get(); }
+ MDSubrange *operator->() const { return get(); }
+ MDSubrange &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- int64_t getLo() const { return getHeaderFieldAs<int64_t>(1); }
- int64_t getCount() const { return getHeaderFieldAs<int64_t>(2); }
+ int64_t getLo() const { RETURN_FROM_RAW(N->getLo(), 0); }
+ int64_t getCount() const { RETURN_FROM_RAW(N->getCount(), 0); }
bool Verify() const;
};
@@ -290,14 +327,22 @@ typedef DITypedArray<DIDescriptor> DIArray;
/// FIXME: it seems strange that this doesn't have either a reference to the
/// type/precision or a file/line pair for location info.
class DIEnumerator : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIEnumerator(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIEnumerator(const MDEnumerator *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
- int64_t getEnumValue() const { return getHeaderFieldAs<int64_t>(2); }
+ MDEnumerator *get() const {
+ return cast_or_null<MDEnumerator>(DIDescriptor::get());
+ }
+ operator MDEnumerator *() const { return get(); }
+ MDEnumerator *operator->() const { return get(); }
+ MDEnumerator &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ int64_t getEnumValue() const { RETURN_FROM_RAW(N->getValue(), 0); }
bool Verify() const;
};
@@ -316,12 +361,17 @@ typedef DITypedArray<DITypeRef> DITypeArray;
/// DIScopes that are scopes in the strict lexical scope sense
/// (DICompileUnit, DISubprogram, etc.), but not for, e.g., a DIType.
class DIScope : public DIDescriptor {
-protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIScope(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIScope(const MDScope *N) : DIDescriptor(N) {}
+
+ MDScope *get() const { return cast_or_null<MDScope>(DIDescriptor::get()); }
+ operator MDScope *() const { return get(); }
+ MDScope *operator->() const { return get(); }
+ MDScope &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
/// \brief Get the parent scope.
///
@@ -362,6 +412,8 @@ public:
T resolve(const DITypeIdentifierMap &Map) const;
StringRef getName() const;
operator Metadata *() const { return const_cast<Metadata *>(Val); }
+
+ static DIRef get(const Metadata *MD) { return DIRef(MD); }
};
template <typename T>
@@ -413,12 +465,18 @@ template <> DIRef<DIType>::DIRef(const Metadata *V);
/// FIXME: Types should be factored much better so that CV qualifiers and
/// others do not require a huge and empty descriptor full of zeros.
class DIType : public DIScope {
-protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIType(const MDNode *N = nullptr) : DIScope(N) {}
+ DIType(const MDType *N) : DIScope(N) {}
+
+ MDType *get() const { return cast_or_null<MDType>(DIDescriptor::get()); }
+ operator MDType *() const { return get(); }
+ MDType *operator->() const { return get(); }
+ MDType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
operator DITypeRef() const {
assert(isType() &&
"constructing DITypeRef from an MDNode that is not a type");
@@ -427,15 +485,17 @@ public:
bool Verify() const;
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- uint64_t getSizeInBits() const { return getHeaderFieldAs<unsigned>(3); }
- uint64_t getAlignInBits() const { return getHeaderFieldAs<unsigned>(4); }
+ DIScopeRef getContext() const {
+ RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
+ }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ uint64_t getSizeInBits() const { RETURN_FROM_RAW(N->getSizeInBits(), 0); }
+ uint64_t getAlignInBits() const { RETURN_FROM_RAW(N->getAlignInBits(), 0); }
// FIXME: Offset is only used for DW_TAG_member nodes. Making every type
// carry this is just plain insane.
- uint64_t getOffsetInBits() const { return getHeaderFieldAs<unsigned>(5); }
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(6); }
+ uint64_t getOffsetInBits() const { RETURN_FROM_RAW(N->getOffsetInBits(), 0); }
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
bool isPrivate() const {
return (getFlags() & FlagAccessibility) == FlagPrivate;
}
@@ -473,8 +533,19 @@ public:
class DIBasicType : public DIType {
public:
explicit DIBasicType(const MDNode *N = nullptr) : DIType(N) {}
+ DIBasicType(const MDBasicType *N) : DIType(N) {}
- unsigned getEncoding() const { return getHeaderFieldAs<unsigned>(7); }
+ MDBasicType *get() const {
+ return cast_or_null<MDBasicType>(DIDescriptor::get());
+ }
+ operator MDBasicType *() const { return get(); }
+ MDBasicType *operator->() const { return get(); }
+ MDBasicType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ unsigned getEncoding() const { RETURN_FROM_RAW(N->getEncoding(), 0); }
bool Verify() const;
};
@@ -484,25 +555,45 @@ public:
/// Like a const qualified type, 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;
-
public:
explicit DIDerivedType(const MDNode *N = nullptr) : DIType(N) {}
+ DIDerivedType(const MDDerivedTypeBase *N) : DIType(N) {}
- DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(3); }
+ MDDerivedTypeBase *get() const {
+ return cast_or_null<MDDerivedTypeBase>(DIDescriptor::get());
+ }
+ operator MDDerivedTypeBase *() const { return get(); }
+ MDDerivedTypeBase *operator->() const { return get(); }
+ MDDerivedTypeBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DITypeRef getTypeDerivedFrom() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getBaseType());
+ }
/// \brief Return property node, if this ivar is associated with one.
- MDNode *getObjCProperty() const;
+ MDNode *getObjCProperty() const {
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ return dyn_cast_or_null<MDNode>(N->getExtraData());
+ return nullptr;
+ }
DITypeRef getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- return getFieldAs<DITypeRef>(4);
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ return DITypeRef::get(N->getExtraData());
+ return DITypeRef::get(nullptr);
}
Constant *getConstant() const {
assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
- return getConstantField(4);
+ if (auto *N = dyn_cast<MDDerivedType>(get()))
+ if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getExtraData()))
+ return C->getValue();
+
+ return nullptr;
}
bool Verify() const;
@@ -519,18 +610,27 @@ public:
// base type in a single DIType field.
class DICompositeType : public DIDerivedType {
friend class DIBuilder;
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
/// \brief Set the array of member DITypes.
void setArraysHelper(MDNode *Elements, MDNode *TParams);
public:
explicit DICompositeType(const MDNode *N = nullptr) : DIDerivedType(N) {}
+ DICompositeType(const MDCompositeTypeBase *N) : DIDerivedType(N) {}
+
+ MDCompositeTypeBase *get() const {
+ return cast_or_null<MDCompositeTypeBase>(DIDescriptor::get());
+ }
+ operator MDCompositeTypeBase *() const { return get(); }
+ MDCompositeTypeBase *operator->() const { return get(); }
+ MDCompositeTypeBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
DIArray getElements() const {
assert(!isSubroutineType() && "no elements for DISubroutineType");
- return getFieldAs<DIArray>(4);
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getElements());
}
private:
@@ -544,16 +644,22 @@ private:
}
public:
- unsigned getRunTimeLang() const { return getHeaderFieldAs<unsigned>(7); }
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(5); }
+ unsigned getRunTimeLang() const { RETURN_FROM_RAW(N->getRuntimeLang(), 0); }
+ DITypeRef getContainingType() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getVTableHolder());
+ }
private:
/// \brief Set the containing type.
void setContainingType(DICompositeType ContainingType);
public:
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); }
- MDString *getIdentifier() const;
+ DIArray getTemplateParams() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
+ }
+ MDString *getIdentifier() const {
+ RETURN_FROM_RAW(N->getRawIdentifier(), nullptr);
+ }
bool Verify() const;
};
@@ -561,100 +667,163 @@ public:
class DISubroutineType : public DICompositeType {
public:
explicit DISubroutineType(const MDNode *N = nullptr) : DICompositeType(N) {}
+ DISubroutineType(const MDSubroutineType *N) : DICompositeType(N) {}
+
+ MDSubroutineType *get() const {
+ return cast_or_null<MDSubroutineType>(DIDescriptor::get());
+ }
+ operator MDSubroutineType *() const { return get(); }
+ MDSubroutineType *operator->() const { return get(); }
+ MDSubroutineType &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
DITypedArray<DITypeRef> getTypeArray() const {
- return getFieldAs<DITypedArray<DITypeRef>>(4);
+ RETURN_DESCRIPTOR_FROM_RAW(DITypedArray<DITypeRef>, N->getTypeArray());
}
};
/// \brief This is a wrapper for a file.
class DIFile : public DIScope {
- friend class DIDescriptor;
-
public:
explicit DIFile(const MDNode *N = nullptr) : DIScope(N) {}
+ DIFile(const MDFile *N) : DIScope(N) {}
+
+ MDFile *get() const { return cast_or_null<MDFile>(DIDescriptor::get()); }
+ operator MDFile *() const { return get(); }
+ MDFile *operator->() const { return get(); }
+ MDFile &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
/// \brief Retrieve the MDNode for the directory/file pair.
- MDNode *getFileNode() const;
+ MDNode *getFileNode() const { return get(); }
bool Verify() const;
};
/// \brief A wrapper for a compile unit.
class DICompileUnit : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DICompileUnit(const MDNode *N = nullptr) : DIScope(N) {}
+ DICompileUnit(const MDCompileUnit *N) : DIScope(N) {}
- dwarf::SourceLanguage getLanguage() const {
- return static_cast<dwarf::SourceLanguage>(getHeaderFieldAs<unsigned>(1));
+ MDCompileUnit *get() const {
+ return cast_or_null<MDCompileUnit>(DIDescriptor::get());
+ }
+ operator MDCompileUnit *() const { return get(); }
+ MDCompileUnit *operator->() const { return get(); }
+ MDCompileUnit &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
}
- StringRef getProducer() const { return getHeaderField(2); }
- bool isOptimized() const { return getHeaderFieldAs<bool>(3) != 0; }
- StringRef getFlags() const { return getHeaderField(4); }
- unsigned getRunTimeVersion() const { return getHeaderFieldAs<unsigned>(5); }
+ dwarf::SourceLanguage getLanguage() const {
+ RETURN_FROM_RAW(static_cast<dwarf::SourceLanguage>(N->getSourceLanguage()),
+ static_cast<dwarf::SourceLanguage>(0));
+ }
+ StringRef getProducer() const { RETURN_FROM_RAW(N->getProducer(), ""); }
+ bool isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), false); }
+ StringRef getFlags() const { RETURN_FROM_RAW(N->getFlags(), ""); }
+ unsigned getRunTimeVersion() const {
+ RETURN_FROM_RAW(N->getRuntimeVersion(), 0);
+ }
- DIArray getEnumTypes() const;
- DIArray getRetainedTypes() const;
- DIArray getSubprograms() const;
- DIArray getGlobalVariables() const;
- DIArray getImportedEntities() const;
+ DIArray getEnumTypes() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getEnumTypes());
+ }
+ DIArray getRetainedTypes() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getRetainedTypes());
+ }
+ DIArray getSubprograms() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getSubprograms());
+ }
+ DIArray getGlobalVariables() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getGlobalVariables());
+ }
+ DIArray getImportedEntities() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getImportedEntities());
+ }
void replaceSubprograms(DIArray Subprograms);
void replaceGlobalVariables(DIArray GlobalVariables);
- StringRef getSplitDebugFilename() const { return getHeaderField(6); }
- unsigned getEmissionKind() const { return getHeaderFieldAs<unsigned>(7); }
+ StringRef getSplitDebugFilename() const {
+ RETURN_FROM_RAW(N->getSplitDebugFilename(), "");
+ }
+ unsigned getEmissionKind() const { RETURN_FROM_RAW(N->getEmissionKind(), 0); }
bool Verify() const;
};
/// \brief This is a wrapper for a subprogram (e.g. a function).
class DISubprogram : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DISubprogram(const MDNode *N = nullptr) : DIScope(N) {}
+ DISubprogram(const MDSubprogram *N) : DIScope(N) {}
- StringRef getName() const { return getHeaderField(1); }
- StringRef getDisplayName() const { return getHeaderField(2); }
- StringRef getLinkageName() const { return getHeaderField(3); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); }
+ MDSubprogram *get() const {
+ return cast_or_null<MDSubprogram>(DIDescriptor::get());
+ }
+ operator MDSubprogram *() const { return get(); }
+ MDSubprogram *operator->() const { return get(); }
+ MDSubprogram &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
+ StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
/// \brief Check if this is local (like 'static' in C).
- unsigned isLocalToUnit() const { return getHeaderFieldAs<unsigned>(5); }
- unsigned isDefinition() const { return getHeaderFieldAs<unsigned>(6); }
+ unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
+ unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
- unsigned getVirtuality() const { return getHeaderFieldAs<unsigned>(7); }
- unsigned getVirtualIndex() const { return getHeaderFieldAs<unsigned>(8); }
+ unsigned getVirtuality() const { RETURN_FROM_RAW(N->getVirtuality(), 0); }
+ unsigned getVirtualIndex() const { RETURN_FROM_RAW(N->getVirtualIndex(), 0); }
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(9); }
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
- unsigned isOptimized() const { return getHeaderFieldAs<bool>(10); }
+ unsigned isOptimized() const { RETURN_FROM_RAW(N->isOptimized(), 0); }
/// \brief Get the beginning of the scope of the function (not the name).
- unsigned getScopeLineNumber() const { return getHeaderFieldAs<unsigned>(11); }
+ unsigned getScopeLineNumber() const { RETURN_FROM_RAW(N->getScopeLine(), 0); }
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- DISubroutineType getType() const { return getFieldAs<DISubroutineType>(3); }
+ DIScopeRef getContext() const {
+ RETURN_REF_FROM_RAW(DIScopeRef, N->getScope());
+ }
+ DISubroutineType getType() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DISubroutineType, N->getType());
+ }
- DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(4); }
+ DITypeRef getContainingType() const {
+ RETURN_REF_FROM_RAW(DITypeRef, N->getContainingType());
+ }
bool Verify() const;
/// \brief Check if this provides debugging information for the function F.
bool describes(const Function *F);
- Function *getFunction() const { return getFunctionField(5); }
- void replaceFunction(Function *F) { replaceFunctionField(5, F); }
- DIArray getTemplateParams() const { return getFieldAs<DIArray>(6); }
+ Function *getFunction() const;
+
+ void replaceFunction(Function *F) {
+ if (auto *N = get())
+ N->replaceFunction(F);
+ }
+ DIArray getTemplateParams() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getTemplateParams());
+ }
DISubprogram getFunctionDeclaration() const {
- return getFieldAs<DISubprogram>(7);
+ RETURN_DESCRIPTOR_FROM_RAW(DISubprogram, N->getDeclaration());
+ }
+ MDNode *getVariablesNodes() const { return getVariables(); }
+ DIArray getVariables() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIArray, N->getVariables());
}
- MDNode *getVariablesNodes() const;
- DIArray getVariables() const;
unsigned isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
/// \brief Check for the "private" access specifier.
@@ -695,9 +864,31 @@ public:
class DILexicalBlock : public DIScope {
public:
explicit DILexicalBlock(const MDNode *N = nullptr) : DIScope(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); }
- unsigned getColumnNumber() const { return getHeaderFieldAs<unsigned>(2); }
+ DILexicalBlock(const MDLexicalBlock *N) : DIScope(N) {}
+
+ MDLexicalBlockBase *get() const {
+ return cast_or_null<MDLexicalBlockBase>(DIDescriptor::get());
+ }
+ operator MDLexicalBlockBase *() const { return get(); }
+ MDLexicalBlockBase *operator->() const { return get(); }
+ MDLexicalBlockBase &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ unsigned getLineNumber() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(get()))
+ return N->getLine();
+ return 0;
+ }
+ unsigned getColumnNumber() const {
+ if (auto *N = dyn_cast<MDLexicalBlock>(get()))
+ return N->getColumn();
+ return 0;
+ }
bool Verify() const;
};
@@ -705,6 +896,18 @@ public:
class DILexicalBlockFile : public DIScope {
public:
explicit DILexicalBlockFile(const MDNode *N = nullptr) : DIScope(N) {}
+ DILexicalBlockFile(const MDLexicalBlockFile *N) : DIScope(N) {}
+
+ MDLexicalBlockFile *get() const {
+ return cast_or_null<MDLexicalBlockFile>(DIDescriptor::get());
+ }
+ operator MDLexicalBlockFile *() const { return get(); }
+ MDLexicalBlockFile *operator->() const { return get(); }
+ MDLexicalBlockFile &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
DIScope getContext() const {
// FIXME: This logic is horrible. getScope() returns a DILexicalBlock, but
// then we check if it's a subprogram? WHAT?!?
@@ -714,21 +917,36 @@ public:
}
unsigned getLineNumber() const { return getScope().getLineNumber(); }
unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
- DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
- unsigned getDiscriminator() const { return getHeaderFieldAs<unsigned>(1); }
+ DILexicalBlock getScope() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DILexicalBlock, N->getScope());
+ }
+ unsigned getDiscriminator() const {
+ RETURN_FROM_RAW(N->getDiscriminator(), 0);
+ }
bool Verify() const;
};
/// \brief A wrapper for a C++ style name space.
class DINameSpace : public DIScope {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DINameSpace(const MDNode *N = nullptr) : DIScope(N) {}
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- DIScope getContext() const { return getFieldAs<DIScope>(2); }
+ DINameSpace(const MDNamespace *N) : DIScope(N) {}
+
+ MDNamespace *get() const {
+ return cast_or_null<MDNamespace>(DIDescriptor::get());
+ }
+ operator MDNamespace *() const { return get(); }
+ MDNamespace *operator->() const { return get(); }
+ MDNamespace &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
bool Verify() const;
};
@@ -737,10 +955,21 @@ class DITemplateTypeParameter : public DIDescriptor {
public:
explicit DITemplateTypeParameter(const MDNode *N = nullptr)
: DIDescriptor(N) {}
+ DITemplateTypeParameter(const MDTemplateTypeParameter *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
+ MDTemplateTypeParameter *get() const {
+ return cast_or_null<MDTemplateTypeParameter>(DIDescriptor::get());
+ }
+ operator MDTemplateTypeParameter *() const { return get(); }
+ MDTemplateTypeParameter *operator->() const { return get(); }
+ MDTemplateTypeParameter &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
bool Verify() const;
};
@@ -749,40 +978,67 @@ class DITemplateValueParameter : public DIDescriptor {
public:
explicit DITemplateValueParameter(const MDNode *N = nullptr)
: DIDescriptor(N) {}
+ DITemplateValueParameter(const MDTemplateValueParameter *N)
+ : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
+ MDTemplateValueParameter *get() const {
+ return cast_or_null<MDTemplateValueParameter>(DIDescriptor::get());
+ }
+ operator MDTemplateValueParameter *() const { return get(); }
+ MDTemplateValueParameter *operator->() const { return get(); }
+ MDTemplateValueParameter &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(2); }
- Metadata *getValue() const;
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
+ Metadata *getValue() const { RETURN_FROM_RAW(N->getValue(), nullptr); }
bool Verify() const;
};
/// \brief This is a wrapper for a global variable.
class DIGlobalVariable : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
public:
explicit DIGlobalVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIGlobalVariable(const MDGlobalVariable *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
- StringRef getDisplayName() const { return getHeaderField(2); }
- StringRef getLinkageName() const { return getHeaderField(3); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(4); }
- unsigned isLocalToUnit() const { return getHeaderFieldAs<bool>(5); }
- unsigned isDefinition() const { return getHeaderFieldAs<bool>(6); }
+ MDGlobalVariable *get() const {
+ return cast_or_null<MDGlobalVariable>(DIDescriptor::get());
+ }
+ operator MDGlobalVariable *() const { return get(); }
+ MDGlobalVariable *operator->() const { return get(); }
+ MDGlobalVariable &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ StringRef getDisplayName() const { RETURN_FROM_RAW(N->getDisplayName(), ""); }
+ StringRef getLinkageName() const { RETURN_FROM_RAW(N->getLinkageName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ unsigned isLocalToUnit() const { RETURN_FROM_RAW(N->isLocalToUnit(), 0); }
+ unsigned isDefinition() const { RETURN_FROM_RAW(N->isDefinition(), 0); }
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- StringRef getFilename() const { return getFieldAs<DIFile>(2).getFilename(); }
- StringRef getDirectory() const {
- return getFieldAs<DIFile>(2).getDirectory();
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
}
- DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
+ StringRef getFilename() const { return getFile().getFilename(); }
+ StringRef getDirectory() const { return getFile().getDirectory(); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
- GlobalVariable *getGlobal() const { return getGlobalVariableField(4); }
- Constant *getConstant() const { return getConstantField(4); }
+ GlobalVariable *getGlobal() const;
+ Constant *getConstant() const {
+ if (auto *N = get())
+ if (auto *C = dyn_cast_or_null<ConstantAsMetadata>(N->getVariable()))
+ return C->getValue();
+ return nullptr;
+ }
DIDerivedType getStaticDataMemberDeclaration() const {
- return getFieldAs<DIDerivedType>(5);
+ RETURN_DESCRIPTOR_FROM_RAW(DIDerivedType,
+ N->getStaticDataMemberDeclaration());
}
bool Verify() const;
@@ -790,34 +1046,45 @@ public:
/// \brief This is a wrapper for a variable (e.g. parameter, local, global etc).
class DIVariable : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
+ unsigned getFlags() const { RETURN_FROM_RAW(N->getFlags(), 0); }
public:
explicit DIVariable(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIVariable(const MDLocalVariable *N) : DIDescriptor(N) {}
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const {
- // FIXME: Line number and arg number shouldn't be merged together like this.
- return (getHeaderFieldAs<unsigned>(2) << 8) >> 8;
+ MDLocalVariable *get() const {
+ return cast_or_null<MDLocalVariable>(DIDescriptor::get());
+ }
+ operator MDLocalVariable *() const { return get(); }
+ MDLocalVariable *operator->() const { return get(); }
+ MDLocalVariable &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
}
- unsigned getArgNumber() const { return getHeaderFieldAs<unsigned>(2) >> 24; }
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIFile getFile() const { return getFieldAs<DIFile>(2); }
- DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ unsigned getArgNumber() const { RETURN_FROM_RAW(N->getArg(), 0); }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
+ DITypeRef getType() const { RETURN_REF_FROM_RAW(DITypeRef, N->getType()); }
/// \brief Return true if this variable is marked as "artificial".
bool isArtificial() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagArtificial) != 0;
+ return (getFlags() & FlagArtificial) != 0;
}
bool isObjectPointer() const {
- return (getHeaderFieldAs<unsigned>(3) & FlagObjectPointer) != 0;
+ return (getFlags() & FlagObjectPointer) != 0;
}
/// \brief If this variable is inlined then return inline location.
- MDNode *getInlinedAt() const;
+ MDNode *getInlinedAt() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIDescriptor, N->getInlinedAt());
+ }
bool Verify() const;
@@ -843,25 +1110,28 @@ public:
/// FIXME: Instead of DW_OP_plus taking an argument, this should use DW_OP_const
/// and have DW_OP_plus consume the topmost elements on the stack.
class DIExpression : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIExpression(const MDNode *N = nullptr) : DIDescriptor(N) {}
+ DIExpression(const MDExpression *N) : DIDescriptor(N) {}
- bool Verify() const;
+ MDExpression *get() const {
+ return cast_or_null<MDExpression>(DIDescriptor::get());
+ }
+ operator MDExpression *() const { return get(); }
+ MDExpression *operator->() const { return get(); }
+ MDExpression &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ // Don't call this. Call isValid() directly.
+ bool Verify() const = delete;
/// \brief Return the number of elements in the complex expression.
- unsigned getNumElements() const {
- if (!DbgNode)
- return 0;
- unsigned N = getNumHeaderFields();
- assert(N > 0 && "missing tag");
- return N - 1;
- }
+ unsigned getNumElements() const { return get()->getNumElements(); }
/// \brief return the Idx'th complex address element.
- uint64_t getElement(unsigned Idx) const;
+ uint64_t getElement(unsigned I) const { return get()->getElement(I); }
/// \brief Return whether this is a piece of an aggregate variable.
bool isBitPiece() const;
@@ -874,34 +1144,33 @@ public:
/// \brief A lightweight wrapper around an element of a DIExpression.
class Operand {
friend class iterator;
- DIHeaderFieldIterator I;
+ MDExpression::element_iterator I;
Operand() {}
- Operand(DIHeaderFieldIterator I) : I(I) {}
+ Operand(MDExpression::element_iterator I) : I(I) {}
public:
/// \brief Operands such as DW_OP_piece have explicit (non-stack) arguments.
/// Argument 0 is the operand itself.
uint64_t getArg(unsigned N) const {
- DIHeaderFieldIterator In = I;
+ MDExpression::element_iterator In = I;
std::advance(In, N);
- return In.getNumber<uint64_t>();
+ return *In;
}
- operator uint64_t () const { return I.getNumber<uint64_t>(); }
- /// \brief Returns underlying DIHeaderFieldIterator.
- const DIHeaderFieldIterator &getBase() const { return I; }
+ operator uint64_t () const { return *I; }
+ /// \brief Returns underlying MDExpression::element_iterator.
+ const MDExpression::element_iterator &getBase() const { return I; }
/// \brief Returns the next operand.
- Operand getNext() const;
+ iterator getNext() const;
};
/// \brief An iterator for DIExpression elements.
class iterator : public std::iterator<std::input_iterator_tag, StringRef,
unsigned, const Operand*, Operand> {
friend class Operand;
- DIHeaderFieldIterator I;
+ MDExpression::element_iterator I;
Operand Tmp;
- iterator(DIHeaderFieldIterator I) : I(I) {}
+
public:
- iterator() {}
- iterator(const DIExpression &Expr) : I(++Expr.header_begin()) {}
+ iterator(MDExpression::element_iterator I) : I(I) {}
const Operand &operator*() { return Tmp = Operand(I); }
const Operand *operator->() { return &(Tmp = Operand(I)); }
iterator &operator++() {
@@ -928,19 +1197,27 @@ public:
}
};
- iterator begin() const;
- iterator end() const;
+ iterator begin() const { return get()->elements_begin(); }
+ iterator end() const { return get()->elements_end(); }
};
/// \brief This object holds location information.
///
/// This object is not associated with any DWARF tag.
class DILocation : public DIDescriptor {
- MDLocation *getRaw() const { return dyn_cast_or_null<MDLocation>(get()); }
-
public:
explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
+ MDLocation *get() const {
+ return cast_or_null<MDLocation>(DIDescriptor::get());
+ }
+ operator MDLocation *() const { return get(); }
+ MDLocation *operator->() const { return get(); }
+ MDLocation &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
unsigned getColumnNumber() const { RETURN_FROM_RAW(N->getColumn(), 0); }
DIScope getScope() const {
@@ -983,19 +1260,31 @@ public:
};
class DIObjCProperty : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
+ DIObjCProperty(const MDObjCProperty *N) : DIDescriptor(N) {}
+
+ MDObjCProperty *get() const {
+ return cast_or_null<MDObjCProperty>(DIDescriptor::get());
+ }
+ operator MDObjCProperty *() const { return get(); }
+ MDObjCProperty *operator->() const { return get(); }
+ MDObjCProperty &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
- StringRef getObjCPropertyName() const { return getHeaderField(1); }
- DIFile getFile() const { return getFieldAs<DIFile>(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
+ StringRef getObjCPropertyName() const { RETURN_FROM_RAW(N->getName(), ""); }
+ DIFile getFile() const { RETURN_DESCRIPTOR_FROM_RAW(DIFile, N->getFile()); }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
- StringRef getObjCPropertyGetterName() const { return getHeaderField(3); }
- StringRef getObjCPropertySetterName() const { return getHeaderField(4); }
- unsigned getAttributes() const { return getHeaderFieldAs<unsigned>(5); }
+ StringRef getObjCPropertyGetterName() const {
+ RETURN_FROM_RAW(N->getGetterName(), "");
+ }
+ StringRef getObjCPropertySetterName() const {
+ RETURN_FROM_RAW(N->getSetterName(), "");
+ }
+ unsigned getAttributes() const { RETURN_FROM_RAW(N->getAttributes(), 0); }
bool isReadOnlyObjCProperty() const {
return (getAttributes() & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
}
@@ -1019,28 +1308,42 @@ public:
///
/// \note Objective-C doesn't have an ODR, so there is no benefit in storing
/// the type as a DITypeRef here.
- DIType getType() const { return getFieldAs<DIType>(2); }
+ DIType getType() const { RETURN_DESCRIPTOR_FROM_RAW(DIType, N->getType()); }
bool Verify() const;
};
/// \brief An imported module (C++ using directive or similar).
class DIImportedEntity : public DIDescriptor {
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
public:
DIImportedEntity() = default;
explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
- DIScope getContext() const { return getFieldAs<DIScope>(1); }
- DIDescriptorRef getEntity() const { return getFieldAs<DIDescriptorRef>(2); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(1); }
- StringRef getName() const { return getHeaderField(2); }
+ DIImportedEntity(const MDImportedEntity *N) : DIDescriptor(N) {}
+
+ MDImportedEntity *get() const {
+ return cast_or_null<MDImportedEntity>(DIDescriptor::get());
+ }
+ operator MDImportedEntity *() const { return get(); }
+ MDImportedEntity *operator->() const { return get(); }
+ MDImportedEntity &operator*() const {
+ assert(get() && "Expected valid pointer");
+ return *get();
+ }
+
+ DIScope getContext() const {
+ RETURN_DESCRIPTOR_FROM_RAW(DIScope, N->getScope());
+ }
+ DIDescriptorRef getEntity() const {
+ RETURN_REF_FROM_RAW(DIDescriptorRef, N->getEntity());
+ }
+ unsigned getLineNumber() const { RETURN_FROM_RAW(N->getLine(), 0); }
+ StringRef getName() const { RETURN_FROM_RAW(N->getName(), ""); }
bool Verify() const;
};
#undef RETURN_FROM_RAW
#undef RETURN_DESCRIPTOR_FROM_RAW
+#undef RETURN_REF_FROM_RAW
/// \brief Find subprogram that is enclosing this scope.
DISubprogram getDISubprogram(const MDNode *Scope);
@@ -1098,9 +1401,6 @@ public:
/// \brief Process DILocation.
void processLocation(const Module &M, DILocation Loc);
- /// \brief Process DIExpression.
- void processExpression(DIExpression Expr);
-
/// \brief Clear all lists.
void reset();
diff --git a/include/llvm/IR/DebugInfoMetadata.h b/include/llvm/IR/DebugInfoMetadata.h
index 4534a14..d7563fc 100644
--- a/include/llvm/IR/DebugInfoMetadata.h
+++ b/include/llvm/IR/DebugInfoMetadata.h
@@ -41,53 +41,6 @@
namespace llvm {
-/// \brief Debug location.
-///
-/// A debug location in source code, used for debug info and otherwise.
-class MDLocation : public MDNode {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
- unsigned Column, ArrayRef<Metadata *> MDs);
- ~MDLocation() { dropAllReferences(); }
-
- static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
- unsigned Column, Metadata *Scope,
- Metadata *InlinedAt, StorageType Storage,
- bool ShouldCreate = true);
-
- TempMDLocation cloneImpl() const {
- return getTemporary(getContext(), getLine(), getColumn(), getScope(),
- getInlinedAt());
- }
-
- // Disallow replacing operands.
- void replaceOperandWith(unsigned I, Metadata *New) = delete;
-
-public:
- DEFINE_MDNODE_GET(MDLocation,
- (unsigned Line, unsigned Column, Metadata *Scope,
- Metadata *InlinedAt = nullptr),
- (Line, Column, Scope, InlinedAt))
-
- /// \brief Return a (temporary) clone of this.
- TempMDLocation clone() const { return cloneImpl(); }
-
- unsigned getLine() const { return SubclassData32; }
- unsigned getColumn() const { return SubclassData16; }
- Metadata *getScope() const { return getOperand(0); }
- Metadata *getInlinedAt() const {
- if (getNumOperands() == 2)
- return getOperand(1);
- return nullptr;
- }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDLocationKind;
- }
-};
-
/// \brief Tagged DWARF-like metadata node.
///
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
@@ -146,7 +99,6 @@ public:
case MDTemplateValueParameterKind:
case MDGlobalVariableKind:
case MDLocalVariableKind:
- case MDExpressionKind:
case MDObjCPropertyKind:
case MDImportedEntityKind:
return true;
@@ -330,7 +282,16 @@ protected:
~MDScope() {}
public:
- Metadata *getFile() const { return getOperand(0); }
+ /// \brief Return the underlying file.
+ ///
+ /// An \a MDFile is an \a MDScope, but it doesn't point at a separate file
+ /// (it\em is the file). If \c this is an \a MDFile, we need to return \c
+ /// this. Otherwise, return the first operand, which is where all other
+ /// subclasses store their file pointer.
+ Metadata *getFile() const {
+ return isa<MDFile>(this) ? const_cast<MDScope *>(this)
+ : static_cast<Metadata *>(getOperand(0));
+ }
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
@@ -351,6 +312,52 @@ public:
}
};
+/// \brief File.
+///
+/// TODO: Merge with directory/file node (including users).
+/// TODO: Canonicalize paths on creation.
+class MDFile : public MDScope {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
+ : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
+ ~MDFile() {}
+
+ static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
+ StringRef Directory, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, getCanonicalMDString(Context, Filename),
+ getCanonicalMDString(Context, Directory), Storage,
+ ShouldCreate);
+ }
+ static MDFile *getImpl(LLVMContext &Context, MDString *Filename,
+ MDString *Directory, StorageType Storage,
+ bool ShouldCreate = true);
+
+ TempMDFile cloneImpl() const {
+ return getTemporary(getContext(), getFilename(), getDirectory());
+ }
+
+public:
+ DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
+ (Filename, Directory))
+ DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
+ (Filename, Directory))
+
+ TempMDFile clone() const { return cloneImpl(); }
+
+ StringRef getFilename() const { return getStringOperand(0); }
+ StringRef getDirectory() const { return getStringOperand(1); }
+
+ MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
+ MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDFileKind;
+ }
+};
+
/// \brief Base class for types.
///
/// TODO: Remove the hardcoded name and context, since many types don't use
@@ -373,6 +380,10 @@ protected:
~MDType() {}
public:
+ TempMDType clone() const {
+ return TempMDType(cast<MDType>(MDNode::clone().release()));
+ }
+
unsigned getLine() const { return Line; }
uint64_t getSizeInBits() const { return SizeInBits; }
uint64_t getAlignInBits() const { return AlignInBits; }
@@ -384,6 +395,11 @@ public:
MDString *getRawName() const { return getOperandAs<MDString>(2); }
+ void setFlags(unsigned NewFlags) {
+ assert(!isUniqued() && "Cannot set flags on uniqued nodes");
+ Flags = NewFlags;
+ }
+
static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
@@ -433,6 +449,8 @@ class MDBasicType : public MDType {
}
public:
+ DEFINE_MDNODE_GET(MDBasicType, (unsigned Tag, StringRef Name),
+ (Tag, Name, 0, 0, 0))
DEFINE_MDNODE_GET(MDBasicType,
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
uint64_t AlignInBits, unsigned Encoding),
@@ -719,52 +737,6 @@ public:
}
};
-/// \brief File.
-///
-/// TODO: Merge with directory/file node (including users).
-/// TODO: Canonicalize paths on creation.
-class MDFile : public MDScope {
- friend class LLVMContextImpl;
- friend class MDNode;
-
- MDFile(LLVMContext &C, StorageType Storage, ArrayRef<Metadata *> Ops)
- : MDScope(C, MDFileKind, Storage, dwarf::DW_TAG_file_type, Ops) {}
- ~MDFile() {}
-
- static MDFile *getImpl(LLVMContext &Context, StringRef Filename,
- StringRef Directory, StorageType Storage,
- bool ShouldCreate = true) {
- return getImpl(Context, getCanonicalMDString(Context, Filename),
- getCanonicalMDString(Context, Directory), Storage,
- ShouldCreate);
- }
- static MDFile *getImpl(LLVMContext &Context, MDString *Filename,
- MDString *Directory, StorageType Storage,
- bool ShouldCreate = true);
-
- TempMDFile cloneImpl() const {
- return getTemporary(getContext(), getFilename(), getDirectory());
- }
-
-public:
- DEFINE_MDNODE_GET(MDFile, (StringRef Filename, StringRef Directory),
- (Filename, Directory))
- DEFINE_MDNODE_GET(MDFile, (MDString * Filename, MDString *Directory),
- (Filename, Directory))
-
- TempMDFile clone() const { return cloneImpl(); }
-
- StringRef getFilename() const { return getStringOperand(0); }
- StringRef getDirectory() const { return getStringOperand(1); }
-
- MDString *getRawFilename() const { return getOperandAs<MDString>(0); }
- MDString *getRawDirectory() const { return getOperandAs<MDString>(1); }
-
- static bool classof(const Metadata *MD) {
- return MD->getMetadataID() == MDFileKind;
- }
-};
-
/// \brief Compile unit.
class MDCompileUnit : public MDScope {
friend class LLVMContextImpl;
@@ -875,11 +847,96 @@ public:
}
};
+/// \brief A scope for locals.
+///
+/// A legal scope for lexical blocks, local variables, and debug info
+/// locations. Subclasses are \a MDSubprogram, \a MDLexicalBlock, and \a
+/// MDLexicalBlockFile.
+class MDLocalScope : public MDScope {
+protected:
+ MDLocalScope(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
+ ArrayRef<Metadata *> Ops)
+ : MDScope(C, ID, Storage, Tag, Ops) {}
+ ~MDLocalScope() {}
+
+public:
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDSubprogramKind ||
+ MD->getMetadataID() == MDLexicalBlockKind ||
+ MD->getMetadataID() == MDLexicalBlockFileKind;
+ }
+};
+
+/// \brief Debug location.
+///
+/// A debug location in source code, used for debug info and otherwise.
+class MDLocation : public MDNode {
+ friend class LLVMContextImpl;
+ friend class MDNode;
+
+ MDLocation(LLVMContext &C, StorageType Storage, unsigned Line,
+ unsigned Column, ArrayRef<Metadata *> MDs);
+ ~MDLocation() { dropAllReferences(); }
+
+ static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true);
+ static MDLocation *getImpl(LLVMContext &Context, unsigned Line,
+ unsigned Column, MDLocalScope *Scope,
+ MDLocation *InlinedAt, StorageType Storage,
+ bool ShouldCreate = true) {
+ return getImpl(Context, Line, Column, static_cast<Metadata *>(Scope),
+ static_cast<Metadata *>(InlinedAt), Storage, ShouldCreate);
+ }
+
+ TempMDLocation cloneImpl() const {
+ return getTemporary(getContext(), getLine(), getColumn(), getScope(),
+ getInlinedAt());
+ }
+
+ // Disallow replacing operands.
+ void replaceOperandWith(unsigned I, Metadata *New) = delete;
+
+public:
+ DEFINE_MDNODE_GET(MDLocation,
+ (unsigned Line, unsigned Column, Metadata *Scope,
+ Metadata *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+ DEFINE_MDNODE_GET(MDLocation,
+ (unsigned Line, unsigned Column, MDLocalScope *Scope,
+ MDLocation *InlinedAt = nullptr),
+ (Line, Column, Scope, InlinedAt))
+
+ /// \brief Return a (temporary) clone of this.
+ TempMDLocation clone() const { return cloneImpl(); }
+
+ unsigned getLine() const { return SubclassData32; }
+ unsigned getColumn() const { return SubclassData16; }
+ MDLocalScope *getScope() const {
+ return cast_or_null<MDLocalScope>(getRawScope());
+ }
+ MDLocation *getInlinedAt() const {
+ return cast_or_null<MDLocation>(getRawInlinedAt());
+ }
+
+ Metadata *getRawScope() const { return getOperand(0); }
+ Metadata *getRawInlinedAt() const {
+ if (getNumOperands() == 2)
+ return getOperand(1);
+ return nullptr;
+ }
+
+ static bool classof(const Metadata *MD) {
+ return MD->getMetadataID() == MDLocationKind;
+ }
+};
+
/// \brief Subprogram description.
///
/// TODO: Remove DisplayName. It's always equal to Name.
/// TODO: Split up flags.
-class MDSubprogram : public MDScope {
+class MDSubprogram : public MDLocalScope {
friend class LLVMContextImpl;
friend class MDNode;
@@ -896,7 +953,8 @@ class MDSubprogram : public MDScope {
unsigned ScopeLine, unsigned Virtuality, unsigned VirtualIndex,
unsigned Flags, bool IsLocalToUnit, bool IsDefinition,
bool IsOptimized, ArrayRef<Metadata *> Ops)
- : MDScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram, Ops),
+ : MDLocalScope(C, MDSubprogramKind, Storage, dwarf::DW_TAG_subprogram,
+ Ops),
Line(Line), ScopeLine(ScopeLine), Virtuality(Virtuality),
VirtualIndex(VirtualIndex), Flags(Flags), IsLocalToUnit(IsLocalToUnit),
IsDefinition(IsDefinition), IsOptimized(IsOptimized) {}
@@ -1004,11 +1062,11 @@ public:
}
};
-class MDLexicalBlockBase : public MDScope {
+class MDLexicalBlockBase : public MDLocalScope {
protected:
MDLexicalBlockBase(LLVMContext &C, unsigned ID, StorageType Storage,
ArrayRef<Metadata *> Ops)
- : MDScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
+ : MDLocalScope(C, ID, Storage, dwarf::DW_TAG_lexical_block, Ops) {}
~MDLexicalBlockBase() {}
public:
@@ -1407,6 +1465,18 @@ public:
unsigned getFlags() const { return Flags; }
Metadata *getInlinedAt() const { return getOperand(4); }
+ /// \brief Get an inlined version of this variable.
+ ///
+ /// Returns a version of this with \a getAlinedAt() set to \c InlinedAt.
+ MDLocalVariable *withInline(MDLocation *InlinedAt) const {
+ if (InlinedAt == getInlinedAt())
+ return const_cast<MDLocalVariable *>(this);
+ auto Temp = clone();
+ Temp->replaceOperandWith(4, InlinedAt);
+ return replaceWithUniqued(std::move(Temp));
+ }
+ MDLocalVariable *withoutInline() const { return withInline(nullptr); }
+
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == MDLocalVariableKind;
}
@@ -1415,17 +1485,16 @@ public:
/// \brief DWARF expression.
///
/// TODO: Co-allocate the expression elements.
-/// TODO: Drop fake DW_TAG_expression and separate from DebugNode.
/// TODO: Separate from MDNode, or otherwise drop Distinct and Temporary
/// storage types.
-class MDExpression : public DebugNode {
+class MDExpression : public MDNode {
friend class LLVMContextImpl;
friend class MDNode;
std::vector<uint64_t> Elements;
MDExpression(LLVMContext &C, StorageType Storage, ArrayRef<uint64_t> Elements)
- : DebugNode(C, MDExpressionKind, Storage, dwarf::DW_TAG_expression, None),
+ : MDNode(C, MDExpressionKind, Storage, None),
Elements(Elements.begin(), Elements.end()) {}
~MDExpression() {}
diff --git a/include/llvm/IR/DebugLoc.h b/include/llvm/IR/DebugLoc.h
index 86e6441..c29d5bf 100644
--- a/include/llvm/IR/DebugLoc.h
+++ b/include/llvm/IR/DebugLoc.h
@@ -103,7 +103,6 @@ namespace llvm {
void dump(const LLVMContext &) const { dump(); }
/// \brief prints source location /path/to/file.exe:line:col @[inlined at]
void print(raw_ostream &OS) const;
- void print(const LLVMContext &, raw_ostream &OS) const { print(OS); }
};
} // end namespace llvm
diff --git a/include/llvm/IR/DiagnosticInfo.h b/include/llvm/IR/DiagnosticInfo.h
index c6a8854..6db5a40 100644
--- a/include/llvm/IR/DiagnosticInfo.h
+++ b/include/llvm/IR/DiagnosticInfo.h
@@ -20,6 +20,7 @@
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
+#include <functional>
namespace llvm {
diff --git a/include/llvm/IR/GVMaterializer.h b/include/llvm/IR/GVMaterializer.h
index 6f57dc2..ae2f2e1 100644
--- a/include/llvm/IR/GVMaterializer.h
+++ b/include/llvm/IR/GVMaterializer.h
@@ -53,6 +53,8 @@ public:
///
virtual std::error_code MaterializeModule(Module *M) = 0;
+ virtual std::error_code materializeMetadata() = 0;
+
virtual std::vector<StructType *> getIdentifiedStructTypes() const = 0;
};
diff --git a/include/llvm/IR/GlobalValue.h b/include/llvm/IR/GlobalValue.h
index aaecc1d..002e5e7 100644
--- a/include/llvm/IR/GlobalValue.h
+++ b/include/llvm/IR/GlobalValue.h
@@ -346,8 +346,6 @@ public:
inline Module *getParent() { return Parent; }
inline const Module *getParent() const { return Parent; }
- const DataLayout *getDataLayout() const;
-
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal ||
diff --git a/include/llvm/IR/IRBuilder.h b/include/llvm/IR/IRBuilder.h
index 33649d7..617e2bc 100644
--- a/include/llvm/IR/IRBuilder.h
+++ b/include/llvm/IR/IRBuilder.h
@@ -351,8 +351,8 @@ public:
}
/// \brief Fetch the type representing a pointer to an integer value.
- IntegerType* getIntPtrTy(const DataLayout *DL, unsigned AddrSpace = 0) {
- return DL->getIntPtrType(Context, AddrSpace);
+ IntegerType *getIntPtrTy(const DataLayout &DL, unsigned AddrSpace = 0) {
+ return DL.getIntPtrType(Context, AddrSpace);
}
//===--------------------------------------------------------------------===//
@@ -1017,6 +1017,10 @@ public:
}
Value *CreateGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
+ return CreateGEP(nullptr, Ptr, IdxList, Name);
+ }
+ Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr)) {
// Every index must be constant.
size_t i, e;
@@ -1026,7 +1030,7 @@ public:
if (i == e)
return Insert(Folder.CreateGetElementPtr(PC, IdxList), Name);
}
- return Insert(GetElementPtrInst::Create(Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name);
}
Value *CreateInBoundsGEP(Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
@@ -1039,19 +1043,19 @@ public:
if (i == e)
return Insert(Folder.CreateInBoundsGetElementPtr(PC, IdxList), Name);
}
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxList), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, IdxList), Name);
}
Value *CreateGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
return Insert(Folder.CreateGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const Twine &Name = "") {
if (Constant *PC = dyn_cast<Constant>(Ptr))
if (Constant *IC = dyn_cast<Constant>(Idx))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, IC), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
@@ -1059,7 +1063,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
const Twine &Name = "") {
@@ -1068,7 +1072,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
const Twine &Name = "") {
@@ -1080,7 +1084,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
const Twine &Name = "") {
@@ -1092,7 +1096,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
@@ -1100,7 +1104,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idx), Name);
}
Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
const Twine &Name = "") {
@@ -1109,7 +1113,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idx), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idx), Name);
}
Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
const Twine &Name = "") {
@@ -1121,7 +1125,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::Create(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::Create(nullptr, Ptr, Idxs), Name);
}
Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
const Twine &Name = "") {
@@ -1133,7 +1137,7 @@ public:
if (Constant *PC = dyn_cast<Constant>(Ptr))
return Insert(Folder.CreateInBoundsGetElementPtr(PC, Idxs), Name);
- return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs), Name);
+ return Insert(GetElementPtrInst::CreateInBounds(nullptr, Ptr, Idxs), Name);
}
Value *CreateStructGEP(Value *Ptr, unsigned Idx, const Twine &Name = "") {
return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
@@ -1486,6 +1490,16 @@ public:
return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
}
+ Value *CreateShuffleVector(Value *V1, Value *V2, ArrayRef<int> IntMask,
+ const Twine &Name = "") {
+ size_t MaskSize = IntMask.size();
+ SmallVector<Constant*, 8> MaskVec(MaskSize);
+ for (size_t i = 0; i != MaskSize; ++i)
+ MaskVec[i] = getInt32(IntMask[i]);
+ Value *Mask = ConstantVector::get(MaskVec);
+ return CreateShuffleVector(V1, V2, Mask, Name);
+ }
+
Value *CreateExtractValue(Value *Agg,
ArrayRef<unsigned> Idxs,
const Twine &Name = "") {
@@ -1595,7 +1609,7 @@ public:
"trying to create an alignment assumption on a non-pointer?");
PointerType *PtrTy = cast<PointerType>(PtrValue->getType());
- Type *IntPtrTy = getIntPtrTy(&DL, PtrTy->getAddressSpace());
+ Type *IntPtrTy = getIntPtrTy(DL, PtrTy->getAddressSpace());
Value *PtrIntValue = CreatePtrToInt(PtrValue, IntPtrTy, "ptrint");
Value *Mask = ConstantInt::get(IntPtrTy,
diff --git a/include/llvm/IR/InlineAsm.h b/include/llvm/IR/InlineAsm.h
index 84ae9df..6ae4122 100644
--- a/include/llvm/IR/InlineAsm.h
+++ b/include/llvm/IR/InlineAsm.h
@@ -189,6 +189,20 @@ public:
// These are helper methods for dealing with flags in the INLINEASM SDNode
// in the backend.
+ //
+ // The encoding of the flag word is currently:
+ // Bits 2-0 - A Kind_* value indicating the kind of the operand.
+ // Bits 15-3 - The number of SDNode operands associated with this inline
+ // assembly operand.
+ // If bit 31 is set:
+ // Bit 30-16 - The operand number that this operand must match.
+ // When bits 2-0 are Kind_Mem, the Constraint_* value must be
+ // obtained from the flags for this operand number.
+ // Else if bits 2-0 are Kind_Mem:
+ // Bit 30-16 - A Constraint_* value indicating the original constraint
+ // code.
+ // Else:
+ // Bit 30-16 - The register class ID to use for the operand.
enum : uint32_t {
// Fixed operands on an INLINEASM SDNode.
@@ -220,6 +234,26 @@ public:
Kind_Imm = 5, // Immediate.
Kind_Mem = 6, // Memory operand, "m".
+ // Memory constraint codes.
+ // These could be tablegenerated but there's little need to do that since
+ // there's plenty of space in the encoding to support the union of all
+ // constraint codes for all targets.
+ Constraint_Unknown = 0,
+ Constraint_es,
+ Constraint_i,
+ Constraint_m,
+ Constraint_o,
+ Constraint_v,
+ Constraint_Q,
+ Constraint_R,
+ Constraint_S,
+ Constraint_T,
+ Constraint_Z,
+ Constraint_ZC,
+ Constraint_Zy,
+ Constraints_Max = Constraint_Zy,
+ Constraints_ShiftAmount = 16,
+
Flag_MatchingOperand = 0x80000000
};
@@ -252,6 +286,20 @@ public:
return InputFlag | (RC << 16);
}
+ /// Augment an existing flag word returned by getFlagWord with the constraint
+ /// code for a memory constraint.
+ static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
+ assert(Constraint <= 0x7fff && "Too large a memory constraint ID");
+ assert(Constraint <= Constraints_Max && "Unknown constraint ID");
+ assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
+ return InputFlag | (Constraint << Constraints_ShiftAmount);
+ }
+
+ static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
+ assert(isMemKind(InputFlag));
+ return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
+ }
+
static unsigned getKind(unsigned Flags) {
return Flags & 7;
}
@@ -266,6 +314,11 @@ public:
return getKind(Flag) == Kind_Clobber;
}
+ static unsigned getMemoryConstraintID(unsigned Flag) {
+ assert(isMemKind(Flag));
+ return (Flag >> Constraints_ShiftAmount) & 0x7fff;
+ }
+
/// getNumOperandRegisters - Extract the number of registers field from the
/// inline asm operand flag.
static unsigned getNumOperandRegisters(unsigned Flag) {
diff --git a/include/llvm/IR/InstIterator.h b/include/llvm/IR/InstIterator.h
index 0bb2854..f3ce649 100644
--- a/include/llvm/IR/InstIterator.h
+++ b/include/llvm/IR/InstIterator.h
@@ -27,15 +27,14 @@ namespace llvm {
// This class implements inst_begin() & inst_end() for
// inst_iterator and const_inst_iterator's.
//
-template <class _BB_t, class _BB_i_t, class _BI_t, class _II_t>
-class InstIterator {
- typedef _BB_t BBty;
- typedef _BB_i_t BBIty;
- typedef _BI_t BIty;
- typedef _II_t IIty;
- _BB_t *BBs; // BasicBlocksType
- _BB_i_t BB; // BasicBlocksType::iterator
- _BI_t BI; // BasicBlock::iterator
+template <class BB_t, class BB_i_t, class BI_t, class II_t> class InstIterator {
+ typedef BB_t BBty;
+ typedef BB_i_t BBIty;
+ typedef BI_t BIty;
+ typedef II_t IIty;
+ BB_t *BBs; // BasicBlocksType
+ BB_i_t BB; // BasicBlocksType::iterator
+ BI_t BI; // BasicBlock::iterator
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef IIty value_type;
diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h
index e086282..3a33f43 100644
--- a/include/llvm/IR/InstrTypes.h
+++ b/include/llvm/IR/InstrTypes.h
@@ -570,10 +570,9 @@ public:
/// This ensures that any pointer<->integer cast has enough bits in the
/// integer and any other cast is a bitcast.
static bool isBitOrNoopPointerCastable(
- Type *SrcTy, ///< The Type from which the value should be cast.
- Type *DestTy, ///< The Type to which the value should be cast.
- const DataLayout *Layout = 0 ///< Optional DataLayout.
- );
+ Type *SrcTy, ///< The Type from which the value should be cast.
+ Type *DestTy, ///< The Type to which the value should be cast.
+ const DataLayout &DL);
/// Returns the opcode necessary to cast Val into Ty using usual casting
/// rules.
@@ -621,9 +620,9 @@ public:
) const;
/// @brief Determine if this cast is a no-op cast.
- bool isNoopCast(
- const DataLayout *DL ///< DataLayout to get the Int Ptr type from.
- ) const;
+ ///
+ /// \param DL is the DataLayout to get the Int Ptr type from.
+ bool isNoopCast(const DataLayout &DL) const;
/// Determine how a pair of casts can be eliminated, if they can be at all.
/// This is a helper function for both CastInst and ConstantExpr.
diff --git a/include/llvm/IR/Instruction.h b/include/llvm/IR/Instruction.h
index dfece3e..dc96b57 100644
--- a/include/llvm/IR/Instruction.h
+++ b/include/llvm/IR/Instruction.h
@@ -54,7 +54,12 @@ public:
inline const BasicBlock *getParent() const { return Parent; }
inline BasicBlock *getParent() { return Parent; }
- const DataLayout *getDataLayout() const;
+ /// \brief Return the module owning the function this instruction belongs to
+ /// or nullptr it the function does not have a module.
+ ///
+ /// Note: this is undefined behavior if the instruction does not have a
+ /// parent, or the parent basic block does not have a parent function.
+ const Module *getModule() const;
/// removeFromParent - This method unlinks 'this' from the containing basic
/// block, but does not delete it.
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h
index 83f9d04..52fa360 100644
--- a/include/llvm/IR/Instructions.h
+++ b/include/llvm/IR/Instructions.h
@@ -794,28 +794,31 @@ class GetElementPtrInst : public Instruction {
/// list of indices. The first ctor can optionally insert before an existing
/// instruction, the second appends the new instruction to the specified
/// BasicBlock.
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- Instruction *InsertBefore);
- inline GetElementPtrInst(Value *Ptr, ArrayRef<Value *> IdxList,
- unsigned Values, const Twine &NameStr,
- BasicBlock *InsertAtEnd);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ inline GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
protected:
GetElementPtrInst *clone_impl() const override;
public:
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertBefore);
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertBefore);
}
- static GetElementPtrInst *Create(Value *Ptr, ArrayRef<Value *> IdxList,
+ static GetElementPtrInst *Create(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
unsigned Values = 1 + unsigned(IdxList.size());
- return new(Values)
- GetElementPtrInst(Ptr, IdxList, Values, NameStr, InsertAtEnd);
+ return new (Values) GetElementPtrInst(PointeeType, Ptr, IdxList, Values,
+ NameStr, InsertAtEnd);
}
/// Create an "inbounds" getelementptr. See the documentation for the
@@ -824,7 +827,14 @@ public:
ArrayRef<Value *> IdxList,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr){
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertBefore);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertBefore);
+ }
+ static GetElementPtrInst *
+ CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef<Value *> IdxList,
+ const Twine &NameStr = "",
+ Instruction *InsertBefore = nullptr) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertBefore);
GEP->setIsInBounds(true);
return GEP;
}
@@ -832,7 +842,14 @@ public:
ArrayRef<Value *> IdxList,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
- GetElementPtrInst *GEP = Create(Ptr, IdxList, NameStr, InsertAtEnd);
+ return CreateInBounds(nullptr, Ptr, IdxList, NameStr, InsertAtEnd);
+ }
+ static GetElementPtrInst *CreateInBounds(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList,
+ const Twine &NameStr,
+ BasicBlock *InsertAtEnd) {
+ GetElementPtrInst *GEP =
+ Create(PointeeType, Ptr, IdxList, NameStr, InsertAtEnd);
GEP->setIsInBounds(true);
return GEP;
}
@@ -846,12 +863,12 @@ public:
}
Type *getSourceElementType() const {
- SequentialType *Ty = cast<SequentialType>(getPointerOperandType());
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- Ty = cast<SequentialType>(VTy->getElementType());
- return Ty->getElementType();
+ return cast<SequentialType>(getPointerOperandType()->getScalarType())
+ ->getElementType();
}
+ Type *getResultElementType() const { return getType()->getElementType(); }
+
/// \brief Returns the address space of this instruction's pointer type.
unsigned getAddressSpace() const {
// Note that this is always the same as the pointer operand's address space
@@ -960,27 +977,25 @@ struct OperandTraits<GetElementPtrInst> :
public VariadicOperandTraits<GetElementPtrInst, 1> {
};
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
Instruction *InsertBefore)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertBefore) {
+ : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertBefore) {
init(Ptr, IdxList, NameStr);
+ assert(!PointeeType || PointeeType == getSourceElementType());
}
-GetElementPtrInst::GetElementPtrInst(Value *Ptr,
- ArrayRef<Value *> IdxList,
- unsigned Values,
+GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr,
+ ArrayRef<Value *> IdxList, unsigned Values,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
- : Instruction(getGEPReturnType(Ptr, IdxList),
- GetElementPtr,
- OperandTraits<GetElementPtrInst>::op_end(this) - Values,
- Values, InsertAtEnd) {
+ : Instruction(getGEPReturnType(Ptr, IdxList), GetElementPtr,
+ OperandTraits<GetElementPtrInst>::op_end(this) - Values,
+ Values, InsertAtEnd) {
init(Ptr, IdxList, NameStr);
+ assert(!PointeeType || PointeeType == getSourceElementType());
}
@@ -1201,11 +1216,15 @@ public:
/// @returns true if the predicate of this instruction is EQ or NE.
/// \brief Determine if this is an equality predicate.
- bool isEquality() const {
- return getPredicate() == FCMP_OEQ || getPredicate() == FCMP_ONE ||
- getPredicate() == FCMP_UEQ || getPredicate() == FCMP_UNE;
+ static bool isEquality(Predicate Pred) {
+ return Pred == FCMP_OEQ || Pred == FCMP_ONE || Pred == FCMP_UEQ ||
+ Pred == FCMP_UNE;
}
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// \brief Determine if this is an equality predicate.
+ bool isEquality() const { return isEquality(getPredicate()); }
+
/// @returns true if the predicate of this instruction is commutative.
/// \brief Determine if this is a commutative predicate.
bool isCommutative() const {
@@ -1908,6 +1927,9 @@ public:
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
@@ -2019,6 +2041,9 @@ public:
typedef const unsigned* idx_iterator;
inline idx_iterator idx_begin() const { return Indices.begin(); }
inline idx_iterator idx_end() const { return Indices.end(); }
+ inline iterator_range<idx_iterator> indices() const {
+ return iterator_range<idx_iterator>(idx_begin(), idx_end());
+ }
Value *getAggregateOperand() {
return getOperand(0);
diff --git a/include/llvm/IR/IntrinsicInst.h b/include/llvm/IR/IntrinsicInst.h
index d434432..bf0adc3 100644
--- a/include/llvm/IR/IntrinsicInst.h
+++ b/include/llvm/IR/IntrinsicInst.h
@@ -82,13 +82,18 @@ namespace llvm {
class DbgDeclareInst : public DbgInfoIntrinsic {
public:
Value *getAddress() const;
- MDNode *getVariable() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(1))->getMetadata());
+ MDLocalVariable *getVariable() const {
+ return cast<MDLocalVariable>(getRawVariable());
}
- MDNode *getExpression() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(2))->getMetadata());
+ MDExpression *getExpression() const {
+ return cast<MDExpression>(getRawExpression());
+ }
+
+ Metadata *getRawVariable() const {
+ return cast<MetadataAsValue>(getArgOperand(1))->getMetadata();
+ }
+ Metadata *getRawExpression() const {
+ return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
@@ -110,13 +115,18 @@ namespace llvm {
return cast<ConstantInt>(
const_cast<Value*>(getArgOperand(1)))->getZExtValue();
}
- MDNode *getVariable() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(2))->getMetadata());
+ MDLocalVariable *getVariable() const {
+ return cast<MDLocalVariable>(getRawVariable());
+ }
+ MDExpression *getExpression() const {
+ return cast<MDExpression>(getRawExpression());
+ }
+
+ Metadata *getRawVariable() const {
+ return cast<MetadataAsValue>(getArgOperand(2))->getMetadata();
}
- MDNode *getExpression() const {
- return cast<MDNode>(
- cast<MetadataAsValue>(getArgOperand(3))->getMetadata());
+ Metadata *getRawExpression() const {
+ return cast<MetadataAsValue>(getArgOperand(3))->getMetadata();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/include/llvm/IR/Intrinsics.td b/include/llvm/IR/Intrinsics.td
index e89e65d..da9d8cb 100644
--- a/include/llvm/IR/Intrinsics.td
+++ b/include/llvm/IR/Intrinsics.td
@@ -261,10 +261,10 @@ def int_gcwrite : Intrinsic<[],
//
def int_returnaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
def int_frameaddress : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty], [IntrNoMem]>;
-def int_frameallocate : Intrinsic<[llvm_ptr_ty], [llvm_i32_ty]>;
+def int_frameescape : Intrinsic<[], [llvm_vararg_ty]>;
def int_framerecover : Intrinsic<[llvm_ptr_ty],
- [llvm_ptr_ty, llvm_ptr_ty],
- [IntrNoMem]>;
+ [llvm_ptr_ty, llvm_ptr_ty, llvm_i32_ty],
+ [IntrNoMem]>;
def int_read_register : Intrinsic<[llvm_anyint_ty], [llvm_metadata_ty],
[IntrNoMem], "llvm.read_register">;
def int_write_register : Intrinsic<[], [llvm_metadata_ty, llvm_anyint_ty],
@@ -412,10 +412,19 @@ def int_eh_return_i32 : Intrinsic<[], [llvm_i32_ty, llvm_ptr_ty]>;
def int_eh_return_i64 : Intrinsic<[], [llvm_i64_ty, llvm_ptr_ty]>;
// eh.begincatch takes a pointer returned by a landingpad instruction and
-// returns the exception object pointer for the exception to be handled.
-def int_eh_begincatch : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty]>;
+// copies the exception object into the memory pointed to by the second
+// parameter. If the second parameter is null, no copy occurs.
+def int_eh_begincatch : Intrinsic<[], [llvm_ptr_ty, llvm_ptr_ty],
+ [NoCapture<0>, NoCapture<1>]>;
def int_eh_endcatch : Intrinsic<[], []>;
+// Represents the list of actions to take when an exception is thrown.
+def int_eh_actions : Intrinsic<[llvm_ptr_ty], [llvm_vararg_ty], []>;
+
+// Designates the provided static alloca as the unwind help object. Required
+// for WinEH.
+def int_eh_unwindhelp : Intrinsic<[], [llvm_ptr_ty], []>;
+
// __builtin_unwind_init is an undocumented GCC intrinsic that causes all
// callee-saved registers to be saved and restored (regardless of whether they
// are used) in the calling function. It is used by libgcc_eh.
diff --git a/include/llvm/IR/IntrinsicsHexagon.td b/include/llvm/IR/IntrinsicsHexagon.td
index b566956..78ee651 100644
--- a/include/llvm/IR/IntrinsicsHexagon.td
+++ b/include/llvm/IR/IntrinsicsHexagon.td
@@ -422,12 +422,42 @@ class Hexagon_di_didisisi_Intrinsic<string GCCIntSuffix>
llvm_i32_ty, llvm_i32_ty],
[IntrNoMem]>;
+class Hexagon_mem_memmemsi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memsisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memdisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty,
+ llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
class Hexagon_mem_memmemsisi_Intrinsic<string GCCIntSuffix>
: Hexagon_Intrinsic<GCCIntSuffix,
[llvm_ptr_ty], [llvm_ptr_ty, llvm_ptr_ty,
llvm_i32_ty, llvm_i32_ty],
[IntrReadWriteArgMem]>;
+class Hexagon_mem_memsisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i32_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
+class Hexagon_mem_memdisisi_Intrinsic<string GCCIntSuffix>
+ : Hexagon_Intrinsic<GCCIntSuffix,
+ [llvm_ptr_ty], [llvm_ptr_ty, llvm_i64_ty,
+ llvm_i32_ty, llvm_i32_ty],
+ [IntrReadWriteArgMem]>;
+
//
// Hexagon_sf_df_Intrinsic<string GCCIntSuffix>
//
@@ -606,20 +636,126 @@ class Hexagon_df_dfdfdfqi_Intrinsic<string GCCIntSuffix>
[IntrNoMem, Throws]>;
-// This one below will not be generated from iset.py.
-// So make sure, you don't overwrite this one.
+// This one below will not be auto-generated,
+// so make sure, you don't overwrite this one.
//
// BUILTIN_INFO(SI_to_SXTHI_asrh,SI_ftype_SI,1)
//
def int_hexagon_SI_to_SXTHI_asrh :
Hexagon_si_si_Intrinsic<"SI_to_SXTHI_asrh">;
//
+// BUILTIN_INFO_NONCONST(brev_ldd,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldd :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldd">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldw,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldw :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldw">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldh,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldh :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldh">;
+//
+// BUILTIN_INFO_NONCONST(brev_lduh,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_lduh :
+Hexagon_mem_memmemsi_Intrinsic<"brev_lduh">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldb,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldb :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldb">;
+//
+// BUILTIN_INFO_NONCONST(brev_ldub,PTR_ftype_PTRPTRSI,3)
+//
+def int_hexagon_brev_ldub :
+Hexagon_mem_memmemsi_Intrinsic<"brev_ldub">;
+//
// BUILTIN_INFO_NONCONST(circ_ldd,PTR_ftype_PTRPTRSISI,4)
//
def int_hexagon_circ_ldd :
Hexagon_mem_memmemsisi_Intrinsic<"circ_ldd">;
-// This one above will not be generated from iset.py.
-// So make sure, you don't overwrite this one.
+//
+// BUILTIN_INFO_NONCONST(circ_ldw,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldw :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldw">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldh,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldh :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldh">;
+//
+// BUILTIN_INFO_NONCONST(circ_lduh,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_lduh :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_lduh">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldb,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldb :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldb">;
+//
+// BUILTIN_INFO_NONCONST(circ_ldub,PTR_ftype_PTRPTRSISI,4)
+//
+def int_hexagon_circ_ldub :
+Hexagon_mem_memmemsisi_Intrinsic<"circ_ldub">;
+
+//
+// BUILTIN_INFO_NONCONST(brev_stb,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_stb :
+Hexagon_mem_memsisi_Intrinsic<"brev_stb">;
+//
+// BUILTIN_INFO_NONCONST(brev_sthhi,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_sthhi :
+Hexagon_mem_memsisi_Intrinsic<"brev_sthhi">;
+//
+// BUILTIN_INFO_NONCONST(brev_sth,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_sth :
+Hexagon_mem_memsisi_Intrinsic<"brev_sth">;
+//
+// BUILTIN_INFO_NONCONST(brev_stw,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_stw :
+Hexagon_mem_memsisi_Intrinsic<"brev_stw">;
+//
+// BUILTIN_INFO_NONCONST(brev_std,PTR_ftype_PTRSISI,3)
+//
+def int_hexagon_brev_std :
+Hexagon_mem_memdisi_Intrinsic<"brev_std">;
+//
+// BUILTIN_INFO_NONCONST(circ_std,PTR_ftype_PTRDISISI,4)
+//
+def int_hexagon_circ_std :
+Hexagon_mem_memdisisi_Intrinsic<"circ_std">;
+//
+// BUILTIN_INFO_NONCONST(circ_stw,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_stw :
+Hexagon_mem_memsisisi_Intrinsic<"circ_stw">;
+//
+// BUILTIN_INFO_NONCONST(circ_sth,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_sth :
+Hexagon_mem_memsisisi_Intrinsic<"circ_sth">;
+//
+// BUILTIN_INFO_NONCONST(circ_sthhi,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_sthhi :
+Hexagon_mem_memsisisi_Intrinsic<"circ_sthhi">;
+//
+// BUILTIN_INFO_NONCONST(circ_stb,PTR_ftype_PTRSISISI,4)
+//
+def int_hexagon_circ_stb :
+Hexagon_mem_memsisisi_Intrinsic<"circ_stb">;
+
+
//
// BUILTIN_INFO(HEXAGON.C2_cmpeq,QI_ftype_SISI,2)
//
diff --git a/include/llvm/IR/IntrinsicsPowerPC.td b/include/llvm/IR/IntrinsicsPowerPC.td
index 110d55d..95fc3e5 100644
--- a/include/llvm/IR/IntrinsicsPowerPC.td
+++ b/include/llvm/IR/IntrinsicsPowerPC.td
@@ -73,7 +73,7 @@ class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
-/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
+/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16i8
/// vectors and returns one. These intrinsics have no side effects.
class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix>
: PowerPC_Vec_Intrinsic<GCCIntSuffix,
@@ -94,6 +94,12 @@ class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
+/// PowerPC_Vec_DDD_Intrinsic - A PowerPC intrinsic that takes two v2i64
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_DDD_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Class Definitions.
@@ -120,7 +126,6 @@ class PowerPC_VSX_Sca_DDD_Intrinsic<string GCCIntSuffix>
[llvm_double_ty], [llvm_double_ty, llvm_double_ty],
[IntrNoMem]>;
-
//===----------------------------------------------------------------------===//
// PowerPC Altivec Intrinsic Definitions.
@@ -198,7 +203,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4f32_ty, llvm_v4f32_ty],
[IntrNoMem]>;
-
+
+ def int_ppc_altivec_vcmpequd : GCCBuiltin<"__builtin_altivec_vcmpequd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsd : GCCBuiltin<"__builtin_altivec_vcmpgtsd">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtud : GCCBuiltin<"__builtin_altivec_vcmpgtud">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty, llvm_v2i64_ty],
+ [IntrNoMem]>;
+
def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
[IntrNoMem]>;
@@ -242,7 +257,17 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vcmpgtfp_p : GCCBuiltin<"__builtin_altivec_vcmpgtfp_p">,
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4f32_ty,llvm_v4f32_ty],
[IntrNoMem]>;
-
+
+ def int_ppc_altivec_vcmpequd_p : GCCBuiltin<"__builtin_altivec_vcmpequd_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsd_p : GCCBuiltin<"__builtin_altivec_vcmpgtsd_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtud_p : GCCBuiltin<"__builtin_altivec_vcmpgtud_p">,
+ Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v2i64_ty,llvm_v2i64_ty],
+ [IntrNoMem]>;
+
def int_ppc_altivec_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_v4i32_ty,llvm_v4i32_ty],
[IntrNoMem]>;
@@ -287,18 +312,22 @@ def int_ppc_altivec_vmaxfp : PowerPC_Vec_FFF_Intrinsic<"vmaxfp">;
def int_ppc_altivec_vmaxsb : PowerPC_Vec_BBB_Intrinsic<"vmaxsb">;
def int_ppc_altivec_vmaxsh : PowerPC_Vec_HHH_Intrinsic<"vmaxsh">;
def int_ppc_altivec_vmaxsw : PowerPC_Vec_WWW_Intrinsic<"vmaxsw">;
+def int_ppc_altivec_vmaxsd : PowerPC_Vec_DDD_Intrinsic<"vmaxsd">;
def int_ppc_altivec_vmaxub : PowerPC_Vec_BBB_Intrinsic<"vmaxub">;
def int_ppc_altivec_vmaxuh : PowerPC_Vec_HHH_Intrinsic<"vmaxuh">;
def int_ppc_altivec_vmaxuw : PowerPC_Vec_WWW_Intrinsic<"vmaxuw">;
+def int_ppc_altivec_vmaxud : PowerPC_Vec_DDD_Intrinsic<"vmaxud">;
// Vector minimum.
def int_ppc_altivec_vminfp : PowerPC_Vec_FFF_Intrinsic<"vminfp">;
def int_ppc_altivec_vminsb : PowerPC_Vec_BBB_Intrinsic<"vminsb">;
def int_ppc_altivec_vminsh : PowerPC_Vec_HHH_Intrinsic<"vminsh">;
def int_ppc_altivec_vminsw : PowerPC_Vec_WWW_Intrinsic<"vminsw">;
+def int_ppc_altivec_vminsd : PowerPC_Vec_DDD_Intrinsic<"vminsd">;
def int_ppc_altivec_vminub : PowerPC_Vec_BBB_Intrinsic<"vminub">;
def int_ppc_altivec_vminuh : PowerPC_Vec_HHH_Intrinsic<"vminuh">;
def int_ppc_altivec_vminuw : PowerPC_Vec_WWW_Intrinsic<"vminuw">;
+def int_ppc_altivec_vminud : PowerPC_Vec_DDD_Intrinsic<"vminud">;
// Saturating adds.
def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">;
@@ -361,12 +390,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulesw : GCCBuiltin<"__builtin_altivec_vmulesw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmuleub : GCCBuiltin<"__builtin_altivec_vmuleub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vmuleuh : GCCBuiltin<"__builtin_altivec_vmuleuh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmuleuw : GCCBuiltin<"__builtin_altivec_vmuleuw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
@@ -374,12 +409,18 @@ let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulosw : GCCBuiltin<"__builtin_altivec_vmulosw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
def int_ppc_altivec_vmuloub : GCCBuiltin<"__builtin_altivec_vmuloub">,
Intrinsic<[llvm_v8i16_ty], [llvm_v16i8_ty, llvm_v16i8_ty],
[IntrNoMem]>;
def int_ppc_altivec_vmulouh : GCCBuiltin<"__builtin_altivec_vmulouh">,
Intrinsic<[llvm_v4i32_ty], [llvm_v8i16_ty, llvm_v8i16_ty],
[IntrNoMem]>;
+ def int_ppc_altivec_vmulouw : GCCBuiltin<"__builtin_altivec_vmulouw">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
// Vector Sum Intructions.
def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
@@ -489,6 +530,7 @@ def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">;
def int_ppc_altivec_vrlb : PowerPC_Vec_BBB_Intrinsic<"vrlb">;
def int_ppc_altivec_vrlh : PowerPC_Vec_HHH_Intrinsic<"vrlh">;
def int_ppc_altivec_vrlw : PowerPC_Vec_WWW_Intrinsic<"vrlw">;
+def int_ppc_altivec_vrld : PowerPC_Vec_DDD_Intrinsic<"vrld">;
let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
// Miscellaneous.
@@ -510,6 +552,41 @@ def int_ppc_altivec_vlogefp : PowerPC_Vec_FF_Intrinsic<"vlogefp">;
def int_ppc_altivec_vrefp : PowerPC_Vec_FF_Intrinsic<"vrefp">;
def int_ppc_altivec_vrsqrtefp : PowerPC_Vec_FF_Intrinsic<"vrsqrtefp">;
+// Power8 Intrinsics
+// Crypto
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ def int_ppc_altivec_crypto_vsbox :
+ GCCBuiltin<"__builtin_altivec_crypto_vsbox">,
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty], [IntrNoMem]>;
+ def int_ppc_altivec_crypto_vpermxor :
+ GCCBuiltin<"__builtin_altivec_crypto_vpermxor">,
+ Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_v16i8_ty], [IntrNoMem]>;
+
+// These need diagnostics for invalid arguments so don't inherit from GCCBuiltin
+def int_ppc_altivec_crypto_vshasigmad :
+ Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_ppc_altivec_crypto_vshasigmaw :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
+}
+def int_ppc_altivec_crypto_vcipher :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vcipher">;
+def int_ppc_altivec_crypto_vcipherlast :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vcipherlast">;
+def int_ppc_altivec_crypto_vncipher :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vncipher">;
+def int_ppc_altivec_crypto_vncipherlast :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vncipherlast">;
+def int_ppc_altivec_crypto_vpmsumb :
+ PowerPC_Vec_BBB_Intrinsic<"crypto_vpmsumb">;
+def int_ppc_altivec_crypto_vpmsumh :
+ PowerPC_Vec_HHH_Intrinsic<"crypto_vpmsumh">;
+def int_ppc_altivec_crypto_vpmsumw :
+ PowerPC_Vec_WWW_Intrinsic<"crypto_vpmsumw">;
+def int_ppc_altivec_crypto_vpmsumd :
+ PowerPC_Vec_DDD_Intrinsic<"crypto_vpmsumd">;
//===----------------------------------------------------------------------===//
// PowerPC VSX Intrinsic Definitions.
@@ -719,3 +796,62 @@ let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
[llvm_v4f64_ty], [llvm_i32_ty], [IntrNoMem]>;
}
+//===----------------------------------------------------------------------===//
+// PowerPC HTM Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+
+def int_ppc_tbegin :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tend :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_tabort : GCCBuiltin<"__builtin_tabort">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_tabortwc :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortwci :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdc :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+def int_ppc_tabortdci :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], []>;
+
+def int_ppc_tcheck : GCCBuiltin<"__builtin_tcheck">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_treclaim : GCCBuiltin<"__builtin_treclaim">,
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+def int_ppc_trechkpt : GCCBuiltin<"__builtin_trechkpt">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsr :
+ Intrinsic<[llvm_i32_ty], [llvm_i32_ty], []>;
+
+def int_ppc_get_texasr : GCCBuiltin<"__builtin_get_texasr">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_texasru : GCCBuiltin<"__builtin_get_texasru">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfhar : GCCBuiltin<"__builtin_get_tfhar">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+def int_ppc_get_tfiar : GCCBuiltin<"__builtin_get_tfiar">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+
+def int_ppc_set_texasr : GCCBuiltin<"__builtin_set_texasr">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_texasru : GCCBuiltin<"__builtin_set_texasru">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfhar : GCCBuiltin<"__builtin_set_tfhar">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+def int_ppc_set_tfiar : GCCBuiltin<"__builtin_set_tfiar">,
+ Intrinsic<[], [llvm_i64_ty], []>;
+
+// Extended mnemonics
+def int_ppc_tendall : GCCBuiltin<"__builtin_tendall">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tresume : GCCBuiltin<"__builtin_tresume">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+def int_ppc_tsuspend : GCCBuiltin<"__builtin_tsuspend">,
+ Intrinsic<[llvm_i32_ty], [], []>;
+
+def int_ppc_ttest : GCCBuiltin<"__builtin_ttest">,
+ Intrinsic<[llvm_i64_ty], [], []>;
+}
diff --git a/include/llvm/IR/IntrinsicsX86.td b/include/llvm/IR/IntrinsicsX86.td
index 60deb32..39b8e3b 100644
--- a/include/llvm/IR/IntrinsicsX86.td
+++ b/include/llvm/IR/IntrinsicsX86.td
@@ -882,15 +882,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_sse41_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb128">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty, llvm_v16i8_ty,llvm_v16i8_ty],
[IntrNoMem]>;
- def int_x86_sse41_pblendw : GCCBuiltin<"__builtin_ia32_pblendw128">,
- Intrinsic<[llvm_v8i16_ty], [llvm_v8i16_ty, llvm_v8i16_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_sse41_blendpd : GCCBuiltin<"__builtin_ia32_blendpd">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty, llvm_i8_ty],
- [IntrNoMem]>;
- def int_x86_sse41_blendps : GCCBuiltin<"__builtin_ia32_blendps">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v4f32_ty, llvm_v4f32_ty, llvm_i8_ty],
- [IntrNoMem]>;
def int_x86_sse41_blendvpd : GCCBuiltin<"__builtin_ia32_blendvpd">,
Intrinsic<[llvm_v2f64_ty], [llvm_v2f64_ty, llvm_v2f64_ty,llvm_v2f64_ty],
[IntrNoMem]>;
@@ -1156,12 +1147,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector blend
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_blend_pd_256 : GCCBuiltin<"__builtin_ia32_blendpd256">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_blend_ps_256 : GCCBuiltin<"__builtin_ia32_blendps256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
def int_x86_avx_blendv_pd_256 : GCCBuiltin<"__builtin_ia32_blendvpd256">,
Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
llvm_v4f64_ty, llvm_v4f64_ty], [IntrNoMem]>;
@@ -1187,32 +1172,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
}
-// Vector extract and insert
-let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx_vextractf128_pd_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_pd256">,
- Intrinsic<[llvm_v2f64_ty], [llvm_v4f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vextractf128_ps_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_ps256">,
- Intrinsic<[llvm_v4f32_ty], [llvm_v8f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vextractf128_si_256 :
- GCCBuiltin<"__builtin_ia32_vextractf128_si256">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v8i32_ty, llvm_i8_ty], [IntrNoMem]>;
-
- def int_x86_avx_vinsertf128_pd_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_pd256">,
- Intrinsic<[llvm_v4f64_ty], [llvm_v4f64_ty,
- llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vinsertf128_ps_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_ps256">,
- Intrinsic<[llvm_v8f32_ty], [llvm_v8f32_ty,
- llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx_vinsertf128_si_256 :
- GCCBuiltin<"__builtin_ia32_vinsertf128_si256">,
- Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty,
- llvm_v4i32_ty, llvm_i8_ty], [IntrNoMem]>;
-}
-
// Vector convert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx_cvtdq2_pd_256 : GCCBuiltin<"__builtin_ia32_cvtdq2pd256">,
@@ -1734,15 +1693,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_pblendvb : GCCBuiltin<"__builtin_ia32_pblendvb256">,
Intrinsic<[llvm_v32i8_ty], [llvm_v32i8_ty, llvm_v32i8_ty,
llvm_v32i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendw : GCCBuiltin<"__builtin_ia32_pblendw256">,
- Intrinsic<[llvm_v16i16_ty], [llvm_v16i16_ty, llvm_v16i16_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendd_128 : GCCBuiltin<"__builtin_ia32_pblendd128">,
- Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty, llvm_v4i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_pblendd_256 : GCCBuiltin<"__builtin_ia32_pblendd256">,
- Intrinsic<[llvm_v8i32_ty], [llvm_v8i32_ty, llvm_v8i32_ty,
- llvm_i8_ty], [IntrNoMem]>;
}
// Vector load with broadcast
@@ -1756,8 +1706,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
def int_x86_avx2_vbroadcast_ss_ps_256 :
GCCBuiltin<"__builtin_ia32_vbroadcastss_ps256">,
Intrinsic<[llvm_v8f32_ty], [llvm_v4f32_ty], [IntrNoMem]>;
- def int_x86_avx2_vbroadcasti128 :
- Intrinsic<[llvm_v4i64_ty], [llvm_ptr_ty], [IntrReadArgMem]>;
def int_x86_avx2_pbroadcastb_128 :
GCCBuiltin<"__builtin_ia32_pbroadcastb128">,
Intrinsic<[llvm_v16i8_ty], [llvm_v16i8_ty], [IntrNoMem]>;
@@ -1811,13 +1759,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
// Vector extract and insert
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
- def int_x86_avx2_vextracti128 : GCCBuiltin<"__builtin_ia32_extract128i256">,
- Intrinsic<[llvm_v2i64_ty], [llvm_v4i64_ty,
- llvm_i8_ty], [IntrNoMem]>;
- def int_x86_avx2_vinserti128 : GCCBuiltin<"__builtin_ia32_insert128i256">,
- Intrinsic<[llvm_v4i64_ty], [llvm_v4i64_ty,
- llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
-
def int_x86_avx512_mask_vextractf32x4_512 :
GCCBuiltin<"__builtin_ia32_extractf32x4_mask">,
Intrinsic<[llvm_v4f32_ty], [llvm_v16f32_ty, llvm_i8_ty,
diff --git a/include/llvm/IR/Metadata.def b/include/llvm/IR/Metadata.def
index 66589e0..0eb29bc 100644
--- a/include/llvm/IR/Metadata.def
+++ b/include/llvm/IR/Metadata.def
@@ -61,6 +61,7 @@ HANDLE_METADATA_LEAF(LocalAsMetadata)
HANDLE_MDNODE_BRANCH(MDNode)
HANDLE_MDNODE_LEAF(MDTuple)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocation)
+HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression)
HANDLE_SPECIALIZED_MDNODE_BRANCH(DebugNode)
HANDLE_SPECIALIZED_MDNODE_LEAF(GenericDebugNode)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubrange)
@@ -75,6 +76,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompositeType)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubroutineType)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDFile)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDCompileUnit)
+HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLocalScope)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDSubprogram)
HANDLE_SPECIALIZED_MDNODE_BRANCH(MDLexicalBlockBase)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLexicalBlock)
@@ -86,7 +88,6 @@ HANDLE_SPECIALIZED_MDNODE_LEAF(MDTemplateValueParameter)
HANDLE_SPECIALIZED_MDNODE_BRANCH(MDVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDGlobalVariable)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDLocalVariable)
-HANDLE_SPECIALIZED_MDNODE_LEAF(MDExpression)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDObjCProperty)
HANDLE_SPECIALIZED_MDNODE_LEAF(MDImportedEntity)
diff --git a/include/llvm/IR/Metadata.h b/include/llvm/IR/Metadata.h
index ff8f837..a31bdbf 100644
--- a/include/llvm/IR/Metadata.h
+++ b/include/llvm/IR/Metadata.h
@@ -32,9 +32,8 @@ class Module;
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
-
enum LLVMConstants : uint32_t {
- DEBUG_METADATA_VERSION = 2 // Current debug info version number.
+ DEBUG_METADATA_VERSION = 3 // Current debug info version number.
};
/// \brief Root of the metadata hierarchy.
@@ -104,15 +103,48 @@ public:
unsigned getMetadataID() const { return SubclassID; }
/// \brief User-friendly dump.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ ///
+ /// Note: this uses an explicit overload instead of default arguments so that
+ /// the nullptr version is easy to call from a debugger.
+ ///
+ /// @{
void dump() const;
- void print(raw_ostream &OS) const;
- void printAsOperand(raw_ostream &OS, bool PrintType = true,
- const Module *M = nullptr) const;
+ void dump(const Module *M) const;
+ /// @}
+
+ /// \brief Print.
+ ///
+ /// Prints definition of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ void print(raw_ostream &OS, const Module *M = nullptr) const;
+
+ /// \brief Print as operand.
+ ///
+ /// Prints reference of \c this.
+ ///
+ /// If \c M is provided, metadata nodes will be numbered canonically;
+ /// otherwise, pointer addresses are substituted.
+ void printAsOperand(raw_ostream &OS, const Module *M = nullptr) const;
};
#define HANDLE_METADATA(CLASS) class CLASS;
#include "llvm/IR/Metadata.def"
+// Provide specializations of isa so that we don't need definitions of
+// subclasses to see if the metadata is a subclass.
+#define HANDLE_METADATA_LEAF(CLASS) \
+ template <> struct isa_impl<CLASS, Metadata> { \
+ static inline bool doit(const Metadata &MD) { \
+ return MD.getMetadataID() == Metadata::CLASS##Kind; \
+ } \
+ };
+#include "llvm/IR/Metadata.def"
+
inline raw_ostream &operator<<(raw_ostream &OS, const Metadata &MD) {
MD.print(OS);
return OS;
diff --git a/include/llvm/IR/Module.h b/include/llvm/IR/Module.h
index 62f4194..ac60c8e 100644
--- a/include/llvm/IR/Module.h
+++ b/include/llvm/IR/Module.h
@@ -219,14 +219,7 @@ private:
std::string TargetTriple; ///< Platform target triple Module compiled on
///< Format: (arch)(sub)-(vendor)-(sys0-(abi)
void *NamedMDSymTab; ///< NamedMDNode names.
-
- // We need to keep the string because the C API expects us to own the string
- // representation.
- // Since we have it, we also use an empty string to represent a module without
- // a DataLayout. If it has a DataLayout, these variables are in sync and the
- // string is just a cache of getDataLayout()->getStringRepresentation().
- std::string DataLayoutStr;
- DataLayout DL;
+ DataLayout DL; ///< DataLayout associated with the module
friend class Constant;
@@ -256,10 +249,12 @@ public:
/// Get the data layout string for the module's target platform. This is
/// equivalent to getDataLayout()->getStringRepresentation().
- const std::string &getDataLayoutStr() const { return DataLayoutStr; }
+ const std::string getDataLayoutStr() const {
+ return DL.getStringRepresentation();
+ }
/// Get the data layout for the module's target platform.
- const DataLayout *getDataLayout() const;
+ const DataLayout &getDataLayout() const;
/// Get the target triple which is a string describing the target host.
/// @returns a string containing the target triple.
@@ -293,12 +288,13 @@ public:
/// Set the data layout
void setDataLayout(StringRef Desc);
- void setDataLayout(const DataLayout *Other);
+ void setDataLayout(const DataLayout &Other);
/// Set the target triple.
void setTargetTriple(StringRef T) { TargetTriple = T; }
/// Set the module-scope inline assembly blocks.
+ /// A trailing newline is added if the input doesn't have one.
void setModuleInlineAsm(StringRef Asm) {
GlobalScopeAsm = Asm;
if (!GlobalScopeAsm.empty() &&
@@ -306,8 +302,8 @@ public:
GlobalScopeAsm += '\n';
}
- /// Append to the module-scope inline assembly blocks, automatically inserting
- /// a separating newline if necessary.
+ /// Append to the module-scope inline assembly blocks.
+ /// A trailing newline is added if the input doesn't have one.
void appendModuleInlineAsm(StringRef Asm) {
GlobalScopeAsm += Asm;
if (!GlobalScopeAsm.empty() &&
@@ -506,6 +502,8 @@ public:
/// Materializer.
std::error_code materializeAllPermanently();
+ std::error_code materializeMetadata();
+
/// @}
/// @name Direct access to the globals list, functions list, and symbol table
/// @{
diff --git a/include/llvm/IR/NoFolder.h b/include/llvm/IR/NoFolder.h
index a9cdfc3..ab7bed6 100644
--- a/include/llvm/IR/NoFolder.h
+++ b/include/llvm/IR/NoFolder.h
@@ -189,7 +189,7 @@ public:
}
Instruction *CreateGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::Create(C, IdxList);
+ return GetElementPtrInst::Create(nullptr, C, IdxList);
}
Constant *CreateInBoundsGetElementPtr(Constant *C,
@@ -204,7 +204,7 @@ public:
}
Instruction *CreateInBoundsGetElementPtr(Constant *C,
ArrayRef<Value *> IdxList) const {
- return GetElementPtrInst::CreateInBounds(C, IdxList);
+ return GetElementPtrInst::CreateInBounds(nullptr, C, IdxList);
}
//===--------------------------------------------------------------------===//
diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h
index 46935ce..c87f89c 100644
--- a/include/llvm/IR/Operator.h
+++ b/include/llvm/IR/Operator.h
@@ -400,6 +400,11 @@ public:
return getPointerOperand()->getType();
}
+ Type *getSourceElementType() const {
+ return cast<SequentialType>(getPointerOperandType()->getScalarType())
+ ->getElementType();
+ }
+
/// Method to return the address space of the pointer operand.
unsigned getPointerAddressSpace() const {
return getPointerOperandType()->getPointerAddressSpace();
diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h
index c92e7c9..3c24e72 100644
--- a/include/llvm/IR/PassManager.h
+++ b/include/llvm/IR/PassManager.h
@@ -46,6 +46,7 @@
#include "llvm/IR/PassManagerInternal.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
#include <list>
#include <memory>
@@ -471,6 +472,12 @@ private:
dbgs() << "Running analysis: " << P.name() << "\n";
AnalysisResultListT &ResultList = AnalysisResultLists[&IR];
ResultList.emplace_back(PassID, P.run(IR, this));
+
+ // P.run may have inserted elements into AnalysisResults and invalidated
+ // RI.
+ RI = AnalysisResults.find(std::make_pair(PassID, &IR));
+ assert(RI != AnalysisResults.end() && "we just inserted it!");
+
RI->second = std::prev(ResultList.end());
}
diff --git a/include/llvm/IR/PassManagerInternal.h b/include/llvm/IR/PassManagerInternal.h
index 297f5f4..92de10b 100644
--- a/include/llvm/IR/PassManagerInternal.h
+++ b/include/llvm/IR/PassManagerInternal.h
@@ -19,6 +19,7 @@
#define LLVM_IR_PASSMANAGERINTERNAL_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
namespace llvm {
diff --git a/include/llvm/IR/Value.h b/include/llvm/IR/Value.h
index b7213a6..8217ef7 100644
--- a/include/llvm/IR/Value.h
+++ b/include/llvm/IR/Value.h
@@ -450,7 +450,7 @@ public:
///
/// Test if this value is always a pointer to allocated and suitably aligned
/// memory for a simple load or store.
- bool isDereferenceablePointer(const DataLayout *DL = nullptr) const;
+ bool isDereferenceablePointer(const DataLayout &DL) const;
/// \brief Translate PHI node to its predecessor from the given basic block.
///
diff --git a/include/llvm/IR/Verifier.h b/include/llvm/IR/Verifier.h
index 43bd123..89039d2 100644
--- a/include/llvm/IR/Verifier.h
+++ b/include/llvm/IR/Verifier.h
@@ -56,20 +56,9 @@ bool verifyModule(const Module &M, raw_ostream *OS = nullptr);
/// printed to stderr, and by default they are fatal. You can override that by
/// passing \c false to \p FatalErrors.
///
-/// Note that this creates a pass suitable for the legacy pass manager. It has nothing to do with \c VerifierPass.
-FunctionPass *createVerifierPass(bool FatalErrors = true);
-
-/// \brief Create a debug-info verifier pass.
-///
-/// Check a module for validity of debug info. This is essentially a pass
-/// wrapped around the debug-info parts of \a verifyModule(). When the pass
-/// detects a verification error it is always printed to stderr, and by default
-/// they are fatal. You can override that by passing \c false to \p
-/// FatalErrors.
-///
/// Note that this creates a pass suitable for the legacy pass manager. It has
/// nothing to do with \c VerifierPass.
-ModulePass *createDebugInfoVerifierPass(bool FatalErrors = true);
+FunctionPass *createVerifierPass(bool FatalErrors = true);
class VerifierPass {
bool FatalErrors;
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index bcf8cf2..1d428b0 100644
--- a/include/llvm/InitializePasses.h
+++ b/include/llvm/InitializePasses.h
@@ -106,7 +106,6 @@ void initializeDAEPass(PassRegistry&);
void initializeDAHPass(PassRegistry&);
void initializeDCEPass(PassRegistry&);
void initializeDSEPass(PassRegistry&);
-void initializeDebugInfoVerifierLegacyPassPass(PassRegistry &);
void initializeDeadInstEliminationPass(PassRegistry&);
void initializeDeadMachineInstructionElimPass(PassRegistry&);
void initializeDelinearizationPass(PassRegistry &);
@@ -150,8 +149,6 @@ void initializeInstCountPass(PassRegistry&);
void initializeInstNamerPass(PassRegistry&);
void initializeInternalizePassPass(PassRegistry&);
void initializeIntervalPartitionPass(PassRegistry&);
-void initializeJumpInstrTableInfoPass(PassRegistry&);
-void initializeJumpInstrTablesPass(PassRegistry&);
void initializeJumpThreadingPass(PassRegistry&);
void initializeLCSSAPass(PassRegistry&);
void initializeLICMPass(PassRegistry&);
@@ -168,6 +165,7 @@ void initializeLocalStackSlotPassPass(PassRegistry&);
void initializeLoopDeletionPass(PassRegistry&);
void initializeLoopExtractorPass(PassRegistry&);
void initializeLoopInfoWrapperPassPass(PassRegistry&);
+void initializeLoopInterchangePass(PassRegistry &);
void initializeLoopInstSimplifyPass(PassRegistry&);
void initializeLoopRotatePass(PassRegistry&);
void initializeLoopSimplifyPass(PassRegistry&);
diff --git a/include/llvm/LTO/LTOCodeGenerator.h b/include/llvm/LTO/LTOCodeGenerator.h
index 56d27ca..820d6d5 100644
--- a/include/llvm/LTO/LTOCodeGenerator.h
+++ b/include/llvm/LTO/LTOCodeGenerator.h
@@ -76,6 +76,7 @@ struct LTOCodeGenerator {
void setCpu(const char *mCpu) { MCpu = mCpu; }
void setAttr(const char *mAttr) { MAttr = mAttr; }
+ void setOptLevel(unsigned optLevel) { OptLevel = optLevel; }
void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
@@ -102,7 +103,6 @@ struct LTOCodeGenerator {
// Do not try to remove the object file in LTOCodeGenerator's destructor
// as we don't who (LTOCodeGenerator or the obj file) will last longer.
bool compile_to_file(const char **name,
- bool disableOpt,
bool disableInline,
bool disableGVNLoadPRE,
bool disableVectorization,
@@ -114,15 +114,13 @@ struct LTOCodeGenerator {
// caller. This function should delete intermediate object file once its content
// is brought to memory. Return NULL if the compilation was not successful.
const void *compile(size_t *length,
- bool disableOpt,
bool disableInline,
bool disableGVNLoadPRE,
bool disableVectorization,
std::string &errMsg);
// Optimizes the merged module. Returns true on success.
- bool optimize(bool disableOpt,
- bool disableInline,
+ bool optimize(bool disableInline,
bool disableGVNLoadPRE,
bool disableVectorization,
std::string &errMsg);
@@ -171,6 +169,7 @@ private:
std::string MAttr;
std::string NativeObjectPath;
TargetOptions Options;
+ unsigned OptLevel;
lto_diagnostic_handler_t DiagHandler;
void *DiagContext;
LTOModule *OwnedModule;
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
index 18343e2..391267c 100644
--- a/include/llvm/LinkAllPasses.h
+++ b/include/llvm/LinkAllPasses.h
@@ -91,12 +91,11 @@ namespace {
(void) llvm::createIndVarSimplifyPass();
(void) llvm::createInstructionCombiningPass();
(void) llvm::createInternalizePass();
- (void) llvm::createJumpInstrTableInfoPass();
- (void) llvm::createJumpInstrTablesPass();
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass();
(void) llvm::createLoopExtractorPass();
+ (void)llvm::createLoopInterchangePass();
(void) llvm::createLoopSimplifyPass();
(void) llvm::createLoopStrengthReducePass();
(void) llvm::createLoopRerollPass();
diff --git a/include/llvm/Linker/Linker.h b/include/llvm/Linker/Linker.h
index aac9dcd..5ca815c 100644
--- a/include/llvm/Linker/Linker.h
+++ b/include/llvm/Linker/Linker.h
@@ -54,6 +54,7 @@ public:
NonOpaqueStructTypeSet NonOpaqueStructTypes;
void addNonOpaque(StructType *Ty);
+ void switchToNonOpaque(StructType *Ty);
void addOpaque(StructType *Ty);
StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
bool hasType(StructType *Ty);
diff --git a/include/llvm/MC/MCAsmInfo.h b/include/llvm/MC/MCAsmInfo.h
index ee245e9..658d77c 100644
--- a/include/llvm/MC/MCAsmInfo.h
+++ b/include/llvm/MC/MCAsmInfo.h
@@ -118,6 +118,9 @@ protected:
// Print the EH begin symbol with an assignment. Defaults to false.
bool UseAssignmentForEHBegin;
+ // Do we need to create a local symbol for .size?
+ bool NeedsLocalForSize;
+
/// This prefix is used for globals like constant pool entries that are
/// completely private to the .s file and should not have names in the .o
/// file. Defaults to "L"
@@ -253,6 +256,10 @@ protected:
/// argument and how it is interpreted. Defaults to NoAlignment.
LCOMM::LCOMMType LCOMMDirectiveAlignmentType;
+ // True if the target allows .align directives on funtions. This is true for
+ // most targets, so defaults to true.
+ bool HasFunctionAlignment;
+
/// True if the target has .type and .size directives, this is true for most
/// ELF targets. Defaults to true.
bool HasDotTypeDotSizeDirective;
@@ -427,6 +434,7 @@ public:
const char *getLabelSuffix() const { return LabelSuffix; }
bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }
+ bool needsLocalForSize() const { return NeedsLocalForSize; }
const char *getPrivateGlobalPrefix() const { return PrivateGlobalPrefix; }
const char *getPrivateLabelPrefix() const { return PrivateLabelPrefix; }
bool hasLinkerPrivateGlobalPrefix() const {
@@ -463,6 +471,7 @@ public:
LCOMM::LCOMMType getLCOMMDirectiveAlignmentType() const {
return LCOMMDirectiveAlignmentType;
}
+ bool hasFunctionAlignment() const { return HasFunctionAlignment; }
bool hasDotTypeDotSizeDirective() const { return HasDotTypeDotSizeDirective; }
bool hasSingleParameterDotFile() const { return HasSingleParameterDotFile; }
bool hasIdentDirective() const { return HasIdentDirective; }
diff --git a/include/llvm/MC/MCAsmLayout.h b/include/llvm/MC/MCAsmLayout.h
index f048e34..4d1590a 100644
--- a/include/llvm/MC/MCAsmLayout.h
+++ b/include/llvm/MC/MCAsmLayout.h
@@ -56,7 +56,7 @@ private:
uint64_t FOffset, uint64_t FSize);
public:
- MCAsmLayout(MCAssembler &_Assembler);
+ MCAsmLayout(MCAssembler &Assembler);
/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 8c56f88..9a85293 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -88,7 +88,7 @@ private:
/// @}
protected:
- MCFragment(FragmentType _Kind, MCSectionData *_Parent = nullptr);
+ MCFragment(FragmentType Kind, MCSectionData *Parent = nullptr);
public:
// Only for sentinel.
@@ -307,11 +307,9 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
SmallVector<MCFixup, 1> Fixups;
public:
- MCRelaxableFragment(const MCInst &_Inst,
- const MCSubtargetInfo &_STI,
+ MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
MCSectionData *SD = nullptr)
- : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(_Inst), STI(_STI) {
- }
+ : MCEncodedFragmentWithFixups(FT_Relaxable, SD), Inst(Inst), STI(STI) {}
SmallVectorImpl<char> &getContents() override { return Contents; }
const SmallVectorImpl<char> &getContents() const override { return Contents; }
@@ -364,11 +362,10 @@ class MCAlignFragment : public MCFragment {
bool EmitNops : 1;
public:
- MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize,
- unsigned _MaxBytesToEmit, MCSectionData *SD = nullptr)
- : MCFragment(FT_Align, SD), Alignment(_Alignment),
- Value(_Value),ValueSize(_ValueSize),
- MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
+ MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
+ unsigned MaxBytesToEmit, MCSectionData *SD = nullptr)
+ : MCFragment(FT_Align, SD), Alignment(Alignment), Value(Value),
+ ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {}
/// @name Accessors
/// @{
@@ -405,10 +402,10 @@ class MCFillFragment : public MCFragment {
uint64_t Size;
public:
- MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size,
+ MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size,
MCSectionData *SD = nullptr)
- : MCFragment(FT_Fill, SD),
- Value(_Value), ValueSize(_ValueSize), Size(_Size) {
+ : MCFragment(FT_Fill, SD), Value(Value), ValueSize(ValueSize),
+ Size(Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
"Fill size must be a multiple of the value size!");
}
@@ -439,10 +436,8 @@ class MCOrgFragment : public MCFragment {
int8_t Value;
public:
- MCOrgFragment(const MCExpr &_Offset, int8_t _Value,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_Org, SD),
- Offset(&_Offset), Value(_Value) {}
+ MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSectionData *SD = nullptr)
+ : MCFragment(FT_Org, SD), Offset(&Offset), Value(Value) {}
/// @name Accessors
/// @{
@@ -505,10 +500,11 @@ class MCDwarfLineAddrFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_Dwarf, SD),
- LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+ MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
+ MCSectionData *SD = nullptr)
+ : MCFragment(FT_Dwarf, SD), LineDelta(LineDelta), AddrDelta(&AddrDelta) {
+ Contents.push_back(0);
+ }
/// @name Accessors
/// @{
@@ -537,10 +533,10 @@ class MCDwarfCallFrameFragment : public MCFragment {
SmallString<8> Contents;
public:
- MCDwarfCallFrameFragment(const MCExpr &_AddrDelta,
- MCSectionData *SD = nullptr)
- : MCFragment(FT_DwarfFrame, SD),
- AddrDelta(&_AddrDelta) { Contents.push_back(0); }
+ MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSectionData *SD = nullptr)
+ : MCFragment(FT_DwarfFrame, SD), AddrDelta(&AddrDelta) {
+ Contents.push_back(0);
+ }
/// @name Accessors
/// @{
@@ -722,7 +718,7 @@ class MCSymbolData : public ilist_node<MCSymbolData> {
public:
// Only for use as sentinel.
MCSymbolData();
- MCSymbolData(const MCSymbol &_Symbol, MCFragment *_Fragment, uint64_t _Offset,
+ MCSymbolData(const MCSymbol &Symbol, MCFragment *Fragment, uint64_t Offset,
MCAssembler *A = nullptr);
/// @name Accessors
diff --git a/include/llvm/MC/MCContext.h b/include/llvm/MC/MCContext.h
index cd96dfd..064f471 100644
--- a/include/llvm/MC/MCContext.h
+++ b/include/llvm/MC/MCContext.h
@@ -15,8 +15,8 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCDwarf.h"
-#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
@@ -37,14 +37,12 @@ namespace llvm {
class MCRegisterInfo;
class MCLineSection;
class SMLoc;
- class StringRef;
- class Twine;
class MCSectionMachO;
class MCSectionELF;
class MCSectionCOFF;
- /// MCContext - Context object for machine code objects. This class owns all
- /// of the sections that it creates.
+ /// Context object for machine code objects. This class owns all of the
+ /// sections that it creates.
///
class MCContext {
MCContext(const MCContext&) = delete;
@@ -64,13 +62,13 @@ namespace llvm {
/// The MCObjectFileInfo for this target.
const MCObjectFileInfo *MOFI;
- /// Allocator - Allocator object used for creating machine code objects.
+ /// Allocator object used for creating machine code objects.
///
/// We use a bump pointer allocator to avoid the need to track all allocated
/// objects.
BumpPtrAllocator Allocator;
- /// Symbols - Bindings of names to symbols.
+ /// Bindings of names to symbols.
SymbolTable Symbols;
/// ELF sections can have a corresponding symbol. This maps one to the
@@ -85,13 +83,13 @@ namespace llvm {
/// We have three labels represented by the pairs (1, 0), (2, 0) and (1, 1)
DenseMap<std::pair<unsigned, unsigned>, MCSymbol*> LocalSymbols;
- /// UsedNames - Keeps tracks of names that were used both for used declared
- /// and artificial symbols.
+ /// Keeps tracks of names that were used both for used declared and
+ /// artificial symbols.
StringMap<bool, BumpPtrAllocator&> UsedNames;
- /// NextUniqueID - The next ID to dole out to an unnamed assembler temporary
- /// symbol.
- unsigned NextUniqueID;
+ /// The next ID to dole out to an unnamed assembler temporary symbol with
+ /// a given prefix.
+ StringMap<unsigned> NextID;
/// Instances of directional local labels.
DenseMap<unsigned, MCLabel *> Instances;
@@ -174,7 +172,7 @@ namespace llvm {
/// Do automatic reset in destructor
bool AutoReset;
- MCSymbol *CreateSymbol(StringRef Name);
+ MCSymbol *CreateSymbol(StringRef Name, bool AlwaysAddSuffix);
MCSymbol *getOrCreateDirectionalLocalSymbol(unsigned LocalLabelVal,
unsigned Instance);
@@ -207,17 +205,15 @@ namespace llvm {
/// @name Symbol Management
/// @{
- /// CreateLinkerPrivateTempSymbol - Create and return a new linker temporary
- /// symbol with a unique but unspecified name.
+ /// Create and return a new linker temporary symbol with a unique but
+ /// unspecified name.
MCSymbol *CreateLinkerPrivateTempSymbol();
- /// CreateTempSymbol - Create and return a new assembler temporary symbol
- /// with a unique but unspecified name.
+ /// Create and return a new assembler temporary symbol with a unique but
+ /// unspecified name.
MCSymbol *CreateTempSymbol();
- /// getUniqueSymbolID() - Return a unique identifier for use in constructing
- /// symbol names.
- unsigned getUniqueSymbolID() { return NextUniqueID++; }
+ MCSymbol *createTempSymbol(const Twine &Name, bool AlwaysAddSuffix);
/// Create the definition of a directional local symbol for numbered label
/// (used for "1:" definitions).
@@ -227,20 +223,17 @@ namespace llvm {
/// for "1b" or 1f" references).
MCSymbol *GetDirectionalLocalSymbol(unsigned LocalLabelVal, bool Before);
- /// GetOrCreateSymbol - Lookup the symbol inside with the specified
- /// @p Name. If it exists, return it. If not, create a forward
- /// reference and return it.
+ /// Lookup the symbol inside with the specified @p Name. If it exists,
+ /// return it. If not, create a forward reference and return it.
///
/// @param Name - The symbol name, which must be unique across all symbols.
- MCSymbol *GetOrCreateSymbol(StringRef Name);
MCSymbol *GetOrCreateSymbol(const Twine &Name);
MCSymbol *getOrCreateSectionSymbol(const MCSectionELF &Section);
- MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName);
+ MCSymbol *getOrCreateFrameAllocSymbol(StringRef FuncName, unsigned Idx);
- /// LookupSymbol - Get the symbol for \p Name, or null.
- MCSymbol *LookupSymbol(StringRef Name) const;
+ /// Get the symbol for \p Name, or null.
MCSymbol *LookupSymbol(const Twine &Name) const;
/// getSymbols - Get a reference for the symbol table for clients that
@@ -256,30 +249,34 @@ namespace llvm {
/// @name Section Management
/// @{
- /// getMachOSection - Return the MCSection for the specified mach-o section.
- /// This requires the operands to be valid.
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
+ /// Return the MCSection for the specified mach-o section. This requires
+ /// the operands to be valid.
+ const MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
unsigned TypeAndAttributes,
- unsigned Reserved2,
- SectionKind K);
- const MCSectionMachO *getMachOSection(StringRef Segment,
- StringRef Section,
+ unsigned Reserved2, SectionKind K,
+ const char *BeginSymName = nullptr);
+
+ const MCSectionMachO *getMachOSection(StringRef Segment, StringRef Section,
unsigned TypeAndAttributes,
- SectionKind K) {
- return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
+ SectionKind K,
+ const char *BeginSymName = nullptr) {
+ return getMachOSection(Segment, Section, TypeAndAttributes, 0, K,
+ BeginSymName);
}
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
- unsigned Flags);
+ unsigned Flags,
+ const char *BeginSymName = nullptr);
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- StringRef Group);
+ StringRef Group,
+ const char *BeginSymName = nullptr);
const MCSectionELF *getELFSection(StringRef Section, unsigned Type,
unsigned Flags, unsigned EntrySize,
- StringRef Group, bool Unique);
+ StringRef Group, bool Unique,
+ const char *BeginSymName = nullptr);
void renameELFSection(const MCSectionELF *Section, StringRef Name);
@@ -288,11 +285,13 @@ namespace llvm {
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
SectionKind Kind,
- StringRef COMDATSymName, int Selection);
+ StringRef COMDATSymName, int Selection,
+ const char *BeginSymName = nullptr);
const MCSectionCOFF *getCOFFSection(StringRef Section,
unsigned Characteristics,
- SectionKind Kind);
+ SectionKind Kind,
+ const char *BeginSymName = nullptr);
const MCSectionCOFF *getCOFFSection(StringRef Section);
@@ -327,7 +326,7 @@ namespace llvm {
/// \brief Set the main file name and override the default.
void setMainFileName(StringRef S) { MainFileName = S; }
- /// GetDwarfFile - creates an entry in the dwarf file and directory tables.
+ /// Creates an entry in the dwarf file and directory tables.
unsigned GetDwarfFile(StringRef Directory, StringRef FileName,
unsigned FileNumber, unsigned CUID);
@@ -370,10 +369,10 @@ namespace llvm {
getMCDwarfLineTable(CUID).setCompilationDir(CompilationDir);
}
- /// setCurrentDwarfLoc - saves the information from the currently parsed
- /// dwarf .loc directive and sets DwarfLocSeen. When the next instruction
- /// is assembled an entry in the line number table with this information and
- /// the address of the instruction will be created.
+ /// Saves the information from the currently parsed dwarf .loc directive
+ /// and sets DwarfLocSeen. When the next instruction is assembled an entry
+ /// in the line number table with this information and the address of the
+ /// instruction will be created.
void setCurrentDwarfLoc(unsigned FileNum, unsigned Line, unsigned Column,
unsigned Flags, unsigned Isa,
unsigned Discriminator) {
diff --git a/include/llvm/MC/MCELFObjectWriter.h b/include/llvm/MC/MCELFObjectWriter.h
index 9763635..7493507 100644
--- a/include/llvm/MC/MCELFObjectWriter.h
+++ b/include/llvm/MC/MCELFObjectWriter.h
@@ -41,6 +41,8 @@ protected:
public:
static uint8_t getOSABI(Triple::OSType OSType) {
switch (OSType) {
+ case Triple::CloudABI:
+ return ELF::ELFOSABI_CLOUDABI;
case Triple::PS4:
case Triple::FreeBSD:
return ELF::ELFOSABI_FREEBSD;
diff --git a/include/llvm/MC/MCExpr.h b/include/llvm/MC/MCExpr.h
index 5e2ef3f..d5a68be 100644
--- a/include/llvm/MC/MCExpr.h
+++ b/include/llvm/MC/MCExpr.h
@@ -56,13 +56,12 @@ private:
const SectionAddrMap *Addrs, bool InSet) const;
protected:
- explicit MCExpr(ExprKind _Kind) : Kind(_Kind) {}
+ explicit MCExpr(ExprKind Kind) : Kind(Kind) {}
bool EvaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
- const SectionAddrMap *Addrs, bool InSet,
- bool ForceVarExpansion) const;
+ const SectionAddrMap *Addrs, bool InSet) const;
public:
/// @name Accessors
@@ -94,7 +93,7 @@ public:
bool EvaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
bool EvaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
- int64_t evaluateKnownAbsolute(const MCAsmLayout &Layout) const;
+ bool evaluateKnownAbsolute(int64_t &Res, const MCAsmLayout &Layout) const;
/// EvaluateAsRelocatable - Try to evaluate the expression to a relocatable
/// value, i.e. an expression of the fixed form (a - b + constant).
@@ -110,10 +109,8 @@ public:
/// neither a nor b are variables.
///
/// This is a more aggressive variant of EvaluateAsRelocatable. The intended
- /// use is for when relocations are not available, like the symbol value in
- /// the symbol table.
- bool EvaluateAsValue(MCValue &Res, const MCAsmLayout *Layout,
- const MCFixup *Fixup) const;
+ /// use is for when relocations are not available, like the .size directive.
+ bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
/// FindAssociatedSection - Find the "associated section" for this expression,
/// which is currently defined as the absolute section for constants, or
@@ -133,8 +130,8 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
class MCConstantExpr : public MCExpr {
int64_t Value;
- explicit MCConstantExpr(int64_t _Value)
- : MCExpr(MCExpr::Constant), Value(_Value) {}
+ explicit MCConstantExpr(int64_t Value)
+ : MCExpr(MCExpr::Constant), Value(Value) {}
public:
/// @name Construction
@@ -188,6 +185,7 @@ public:
VK_GOTPAGE,
VK_GOTPAGEOFF,
VK_SECREL,
+ VK_SIZE, // symbol@SIZE
VK_WEAKREF, // The link between the symbols in .weakref foo, bar
VK_ARM_NONE,
@@ -353,8 +351,8 @@ private:
Opcode Op;
const MCExpr *Expr;
- MCUnaryExpr(Opcode _Op, const MCExpr *_Expr)
- : MCExpr(MCExpr::Unary), Op(_Op), Expr(_Expr) {}
+ MCUnaryExpr(Opcode Op, const MCExpr *Expr)
+ : MCExpr(MCExpr::Unary), Op(Op), Expr(Expr) {}
public:
/// @name Construction
@@ -424,8 +422,8 @@ private:
Opcode Op;
const MCExpr *LHS, *RHS;
- MCBinaryExpr(Opcode _Op, const MCExpr *_LHS, const MCExpr *_RHS)
- : MCExpr(MCExpr::Binary), Op(_Op), LHS(_LHS), RHS(_RHS) {}
+ MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS)
+ : MCExpr(MCExpr::Binary), Op(Op), LHS(LHS), RHS(RHS) {}
public:
/// @name Construction
diff --git a/include/llvm/MC/MCMachObjectWriter.h b/include/llvm/MC/MCMachObjectWriter.h
index e4681c0..514700b 100644
--- a/include/llvm/MC/MCMachObjectWriter.h
+++ b/include/llvm/MC/MCMachObjectWriter.h
@@ -119,10 +119,9 @@ class MachObjectWriter : public MCObjectWriter {
MachSymbolData *findSymbolData(const MCSymbol &Sym);
public:
- MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &_OS,
- bool _IsLittleEndian)
- : MCObjectWriter(_OS, _IsLittleEndian), TargetObjectWriter(MOTW) {
- }
+ MachObjectWriter(MCMachObjectTargetWriter *MOTW, raw_ostream &OS,
+ bool IsLittleEndian)
+ : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
/// @name Lifetime management Methods
/// @{
diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h
index 321043c..025a76a 100644
--- a/include/llvm/MC/MCObjectFileInfo.h
+++ b/include/llvm/MC/MCObjectFileInfo.h
@@ -99,7 +99,6 @@ protected:
const MCSection *DwarfLocSection;
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;
@@ -241,9 +240,6 @@ public:
const MCSection *getDwarfLocSection() const { return DwarfLocSection; }
const MCSection *getDwarfARangesSection() const { return DwarfARangesSection;}
const MCSection *getDwarfRangesSection() const { return DwarfRangesSection; }
- const MCSection *getDwarfMacroInfoSection() const {
- return DwarfMacroInfoSection;
- }
// DWARF5 Experimental Debug Info Sections
const MCSection *getDwarfAccelNamesSection() const {
diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h
index 0866ff5..2420072 100644
--- a/include/llvm/MC/MCObjectStreamer.h
+++ b/include/llvm/MC/MCObjectStreamer.h
@@ -49,10 +49,10 @@ class MCObjectStreamer : public MCStreamer {
void flushPendingLabels(MCFragment *F);
protected:
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter);
- MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter, MCAssembler *_Assembler);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter);
+ MCObjectStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, MCAssembler *Assembler);
~MCObjectStreamer();
public:
@@ -85,6 +85,8 @@ protected:
/// fragment is not a data fragment.
MCDataFragment *getOrCreateDataFragment();
+ bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection);
+
public:
void visitUsedSymbol(const MCSymbol &Sym) override;
diff --git a/include/llvm/MC/MCObjectWriter.h b/include/llvm/MC/MCObjectWriter.h
index 430075c..fcfa968 100644
--- a/include/llvm/MC/MCObjectWriter.h
+++ b/include/llvm/MC/MCObjectWriter.h
@@ -46,8 +46,8 @@ protected:
unsigned IsLittleEndian : 1;
protected: // Can only create subclasses.
- MCObjectWriter(raw_ostream &_OS, bool _IsLittleEndian)
- : OS(_OS), IsLittleEndian(_IsLittleEndian) {}
+ MCObjectWriter(raw_ostream &OS, bool IsLittleEndian)
+ : OS(OS), IsLittleEndian(IsLittleEndian) {}
public:
virtual ~MCObjectWriter();
@@ -86,11 +86,10 @@ public:
///
/// Clients are not required to answer precisely and may conservatively return
/// false, even when a difference is fully resolved.
- bool
- IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
- const MCSymbolRefExpr *A,
- const MCSymbolRefExpr *B,
- bool InSet) const;
+ bool IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm,
+ const MCSymbolRefExpr *A,
+ const MCSymbolRefExpr *B,
+ bool InSet) const;
virtual bool
IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
@@ -99,6 +98,11 @@ public:
bool InSet,
bool IsPCRel) const;
+ /// \brief True if this symbol (which is a variable) is weak. This is not
+ /// just STB_WEAK, but more generally whether or not we can evaluate
+ /// past it.
+ virtual bool isWeak(const MCSymbolData &SD) const;
+
/// \brief Write the object file.
///
/// This routine is called by the assembler after layout and relaxation is
diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h
index 14f8ade..71f15b3 100644
--- a/include/llvm/MC/MCParser/MCAsmLexer.h
+++ b/include/llvm/MC/MCParser/MCAsmLexer.h
@@ -63,10 +63,10 @@ private:
public:
AsmToken() {}
- AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
- : Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
- AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
- : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {}
+ AsmToken(TokenKind Kind, StringRef Str, APInt IntVal)
+ : Kind(Kind), Str(Str), IntVal(IntVal) {}
+ AsmToken(TokenKind Kind, StringRef Str, int64_t IntVal = 0)
+ : Kind(Kind), Str(Str), IntVal(64, IntVal, true) {}
TokenKind getKind() const { return Kind; }
bool is(TokenKind K) const { return Kind == K; }
diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h
index 8aec9c8..ab8968e 100644
--- a/include/llvm/MC/MCSection.h
+++ b/include/llvm/MC/MCSection.h
@@ -19,60 +19,53 @@
#include "llvm/Support/Compiler.h"
namespace llvm {
- class MCAsmInfo;
- class MCExpr;
- class raw_ostream;
-
- /// MCSection - Instances of this class represent a uniqued identifier for a
- /// section in the current translation unit. The MCContext class uniques and
- /// creates these.
- class MCSection {
- public:
- enum SectionVariant {
- SV_COFF = 0,
- SV_ELF,
- SV_MachO
- };
-
- private:
- MCSection(const MCSection&) = delete;
- void operator=(const MCSection&) = delete;
- protected:
- MCSection(SectionVariant V, SectionKind K) : Variant(V), Kind(K) {}
- SectionVariant Variant;
- SectionKind Kind;
- public:
- virtual ~MCSection();
-
- SectionKind getKind() const { return Kind; }
-
- SectionVariant getVariant() const { return Variant; }
-
- virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
- raw_ostream &OS,
- const MCExpr *Subsection) const = 0;
-
- // Convenience routines to get label names for the beginning/end of a
- // section.
- virtual std::string getLabelBeginName() const = 0;
- virtual std::string getLabelEndName() const = 0;
-
- /// isBaseAddressKnownZero - Return true if we know that this section will
- /// get a base address of zero. In cases where we know that this is true we
- /// can emit section offsets as direct references to avoid a subtraction
- /// from the base of the section, saving a relocation.
- virtual bool isBaseAddressKnownZero() const {
- return false;
- }
-
- // UseCodeAlign - Return true if a .align directive should use
- // "optimized nops" to fill instead of 0s.
- virtual bool UseCodeAlign() const = 0;
-
- /// isVirtualSection - Check whether this section is "virtual", that is
- /// has no actual object file contents.
- virtual bool isVirtualSection() const = 0;
- };
+class MCAsmInfo;
+class MCContext;
+class MCExpr;
+class MCSymbol;
+class raw_ostream;
+
+/// Instances of this class represent a uniqued identifier for a section in the
+/// current translation unit. The MCContext class uniques and creates these.
+class MCSection {
+public:
+ enum SectionVariant { SV_COFF = 0, SV_ELF, SV_MachO };
+
+private:
+ MCSection(const MCSection &) = delete;
+ void operator=(const MCSection &) = delete;
+
+ MCSymbol *Begin;
+ mutable MCSymbol *End;
+
+protected:
+ MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin)
+ : Begin(Begin), End(nullptr), Variant(V), Kind(K) {}
+ SectionVariant Variant;
+ SectionKind Kind;
+
+public:
+ virtual ~MCSection();
+
+ SectionKind getKind() const { return Kind; }
+
+ SectionVariant getVariant() const { return Variant; }
+
+ MCSymbol *getBeginSymbol() const { return Begin; }
+ MCSymbol *getEndSymbol(MCContext &Ctx) const;
+ bool hasEnded() const;
+
+ virtual void PrintSwitchToSection(const MCAsmInfo &MAI, raw_ostream &OS,
+ const MCExpr *Subsection) const = 0;
+
+ /// Return true if a .align directive should use "optimized nops" to fill
+ /// instead of 0s.
+ virtual bool UseCodeAlign() const = 0;
+
+ /// Check whether this section is "virtual", that is has no actual object
+ /// file contents.
+ virtual bool isVirtualSection() const = 0;
+};
} // end namespace llvm
diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h
index 0bbf369..b6ec1d8 100644
--- a/include/llvm/MC/MCSectionCOFF.h
+++ b/include/llvm/MC/MCSectionCOFF.h
@@ -45,8 +45,9 @@ class MCSymbol;
private:
friend class MCContext;
MCSectionCOFF(StringRef Section, unsigned Characteristics,
- MCSymbol *COMDATSymbol, int Selection, SectionKind K)
- : MCSection(SV_COFF, K), SectionName(Section),
+ MCSymbol *COMDATSymbol, int Selection, SectionKind K,
+ MCSymbol *Begin)
+ : MCSection(SV_COFF, K, Begin), SectionName(Section),
Characteristics(Characteristics), COMDATSymbol(COMDATSymbol),
Selection(Selection) {
assert ((Characteristics & 0x00F00000) == 0 &&
@@ -60,12 +61,6 @@ class MCSymbol;
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- std::string getLabelBeginName() const override {
- return SectionName.str() + "_begin";
- }
- std::string getLabelEndName() const override {
- return SectionName.str() + "_end";
- }
unsigned getCharacteristics() const { return Characteristics; }
MCSymbol *getCOMDATSymbol() const { return COMDATSymbol; }
int getSelection() const { return Selection; }
diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h
index 6d864b4..434a5b6 100644
--- a/include/llvm/MC/MCSectionELF.h
+++ b/include/llvm/MC/MCSectionELF.h
@@ -51,9 +51,10 @@ class MCSectionELF : public MCSection {
private:
friend class MCContext;
MCSectionELF(StringRef Section, unsigned type, unsigned flags, SectionKind K,
- unsigned entrySize, const MCSymbol *group, bool Unique)
- : MCSection(SV_ELF, K), SectionName(Section), Type(type), Flags(flags),
- Unique(Unique), EntrySize(entrySize), Group(group) {}
+ unsigned entrySize, const MCSymbol *group, bool Unique,
+ MCSymbol *Begin)
+ : MCSection(SV_ELF, K, Begin), SectionName(Section), Type(type),
+ Flags(flags), Unique(Unique), EntrySize(entrySize), Group(group) {}
~MCSectionELF();
void setSectionName(StringRef Name) { SectionName = Name; }
@@ -65,16 +66,6 @@ public:
bool ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const;
StringRef getSectionName() const { return SectionName; }
- std::string getLabelBeginName() const override {
- if (Group)
- return (SectionName.str() + '_' + Group->getName() + "_begin").str();
- return SectionName.str() + "_begin";
- }
- std::string getLabelEndName() const override {
- if (Group)
- return (SectionName.str() + '_' + Group->getName() + "_end").str();
- return SectionName.str() + "_end";
- }
unsigned getType() const { return Type; }
unsigned getFlags() const { return Flags; }
unsigned getEntrySize() const { return EntrySize; }
@@ -85,12 +76,6 @@ public:
bool UseCodeAlign() const override;
bool isVirtualSection() const override;
- /// isBaseAddressKnownZero - We know that non-allocatable sections (like
- /// debug info) have a base of zero.
- bool isBaseAddressKnownZero() const override {
- return (getFlags() & ELF::SHF_ALLOC) == 0;
- }
-
static bool classof(const MCSection *S) {
return S->getVariant() == SV_ELF;
}
diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h
index a5a2089..9722751 100644
--- a/include/llvm/MC/MCSectionMachO.h
+++ b/include/llvm/MC/MCSectionMachO.h
@@ -35,8 +35,8 @@ class MCSectionMachO : public MCSection {
/// size of stubs, for example.
unsigned Reserved2;
- MCSectionMachO(StringRef Segment, StringRef Section,
- unsigned TAA, unsigned reserved2, SectionKind K);
+ MCSectionMachO(StringRef Segment, StringRef Section, unsigned TAA,
+ unsigned reserved2, SectionKind K, MCSymbol *Begin);
friend class MCContext;
public:
@@ -53,14 +53,6 @@ public:
return StringRef(SectionName);
}
- std::string getLabelBeginName() const override {
- return StringRef(getSegmentName().str() + getSectionName().str() + "_begin");
- }
-
- std::string getLabelEndName() const override {
- return StringRef(getSegmentName().str() + getSectionName().str() + "_end");
- }
-
unsigned getTypeAndAttributes() const { return TypeAndAttributes; }
unsigned getStubSize() const { return Reserved2; }
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index f0be77f..df7610b 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -344,20 +344,12 @@ public:
return true;
}
- /// SwitchSection - Set the current section where code is being emitted to
- /// @p Section. This is required to update CurSection.
+ /// Set the current section where code is being emitted to @p Section. This
+ /// is required to update CurSection.
///
/// This corresponds to assembler directives like .section, .text, etc.
virtual void SwitchSection(const MCSection *Section,
- const MCExpr *Subsection = nullptr) {
- assert(Section && "Cannot switch to a null section!");
- MCSectionSubPair curSection = SectionStack.back().first;
- SectionStack.back().second = curSection;
- if (MCSectionSubPair(Section, Subsection) != curSection) {
- SectionStack.back().first = MCSectionSubPair(Section, Subsection);
- ChangeSection(Section, Subsection);
- }
- }
+ const MCExpr *Subsection = nullptr);
/// SwitchSectionNoChange - Set the current section where code is being
/// emitted to @p Section. This is required to update CurSection. This
@@ -374,6 +366,8 @@ public:
/// Create the default sections and set the initial one.
virtual void InitSections(bool NoExecStack);
+ MCSymbol *endSection(const MCSection *Section);
+
/// AssignSection - Sets the symbol's section.
///
/// Each emitted symbol will be tracked in the ordering table,
@@ -732,13 +726,12 @@ public:
virtual bool mayHaveInstructions() const { return true; }
};
-/// createNullStreamer - Create a dummy machine code streamer, which does
-/// nothing. This is useful for timing the assembler front end.
+/// Create a dummy machine code streamer, which does nothing. This is useful for
+/// timing the assembler front end.
MCStreamer *createNullStreamer(MCContext &Ctx);
-/// createAsmStreamer - Create a machine code streamer which will print out
-/// assembly for the native target, suitable for compiling with a native
-/// assembler.
+/// Create a machine code streamer which will print out assembly for the native
+/// target, suitable for compiling with a native assembler.
///
/// \param InstPrint - If given, the instruction printer to use. If not given
/// the MCInst representation will be printed. This method takes ownership of
@@ -757,22 +750,6 @@ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
bool isVerboseAsm, bool useDwarfDirectory,
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
-
-/// createMachOStreamer - Create a machine code streamer which will generate
-/// Mach-O format object files.
-///
-/// Takes ownership of \p TAB and \p CE.
-MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll = false,
- bool LabelSections = false);
-
-/// createELFStreamer - Create a machine code streamer which will generate
-/// ELF format object files.
-MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll);
-
} // end namespace llvm
#endif
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h
index 4f8e281..d40dc9d 100644
--- a/include/llvm/Object/Archive.h
+++ b/include/llvm/Object/Archive.h
@@ -155,9 +155,8 @@ public:
Symbol symbol;
public:
symbol_iterator(const Symbol &s) : symbol(s) {}
- const Symbol *operator->() const {
- return &symbol;
- }
+ const Symbol *operator->() const { return &symbol; }
+ const Symbol &operator*() const { return symbol; }
bool operator==(const symbol_iterator &other) const {
return symbol == other.symbol;
@@ -194,6 +193,9 @@ public:
symbol_iterator symbol_begin() const;
symbol_iterator symbol_end() const;
+ iterator_range<symbol_iterator> symbols() const {
+ return iterator_range<symbol_iterator>(symbol_begin(), symbol_end());
+ }
// Cast methods.
static inline bool classof(Binary const *v) {
diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h
index 7c10bbf..ddabf59 100644
--- a/include/llvm/Object/ELF.h
+++ b/include/llvm/Object/ELF.h
@@ -94,18 +94,24 @@ public:
return *this;
}
+ ELFEntityIterator &operator+(difference_type n) {
+ assert(Current && "Attempted to increment an invalid iterator!");
+ Current += (n * EntitySize);
+ return *this;
+ }
+
+ ELFEntityIterator &operator-(difference_type n) {
+ assert(Current && "Attempted to subtract an invalid iterator!");
+ Current -= (n * EntitySize);
+ return *this;
+ }
+
ELFEntityIterator operator ++(int) {
ELFEntityIterator Tmp = *this;
++*this;
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 EntitySize!");
@@ -203,12 +209,6 @@ public:
return *this;
}
- Elf_Sym_Iter &operator=(const Elf_Sym_Iter &Other) {
- EntitySize = Other.EntitySize;
- Current = Other.Current;
- return *this;
- }
-
difference_type operator-(const Elf_Sym_Iter &Other) const {
assert(EntitySize == Other.EntitySize &&
"Subtracting iterators of different EntitySize!");
diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h
index 9a97f7b..5a4e03e 100644
--- a/include/llvm/Object/ELFTypes.h
+++ b/include/llvm/Object/ELFTypes.h
@@ -189,7 +189,15 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> {
}
/// Access to the STV_xxx flag stored in the first two bits of st_other.
+ /// STV_DEFAULT: 0
+ /// STV_INTERNAL: 1
+ /// STV_HIDDEN: 2
+ /// STV_PROTECTED: 3
unsigned char getVisibility() const { return st_other & 0x3; }
+ void setVisibility(unsigned char v) {
+ assert(v < 4 && "Invalid value for visibility");
+ st_other = (st_other & ~0x3) | v;
+ }
};
/// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section
diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h
index 93f6654..05119b2 100644
--- a/include/llvm/Object/MachOUniversal.h
+++ b/include/llvm/Object/MachOUniversal.h
@@ -16,6 +16,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
@@ -69,9 +70,8 @@ public:
ObjectForArch Obj;
public:
object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
- const ObjectForArch* operator->() const {
- return &Obj;
- }
+ const ObjectForArch *operator->() const { return &Obj; }
+ const ObjectForArch &operator*() const { return Obj; }
bool operator==(const object_iterator &Other) const {
return Obj == Other.Obj;
@@ -97,6 +97,10 @@ public:
return ObjectForArch(nullptr, 0);
}
+ iterator_range<object_iterator> objects() const {
+ return make_range(begin_objects(), end_objects());
+ }
+
uint32_t getNumberOfObjects() const { return NumberOfObjects; }
// Cast methods.
diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h
index f7b7cb4..b6a8b4d 100644
--- a/include/llvm/Object/SymbolicFile.h
+++ b/include/llvm/Object/SymbolicFile.h
@@ -45,7 +45,9 @@ inline bool operator<(const DataRefImpl &a, const DataRefImpl &b) {
return std::memcmp(&a, &b, sizeof(DataRefImpl)) < 0;
}
-template <class content_type> class content_iterator {
+template <class content_type>
+class content_iterator
+ : public std::iterator<std::forward_iterator_tag, content_type> {
content_type Current;
public:
diff --git a/include/llvm/Option/Arg.h b/include/llvm/Option/Arg.h
index 9459a3d..5f6941a 100644
--- a/include/llvm/Option/Arg.h
+++ b/include/llvm/Option/Arg.h
@@ -78,9 +78,7 @@ public:
const Arg &getBaseArg() const {
return BaseArg ? *BaseArg : *this;
}
- void setBaseArg(const Arg *_BaseArg) {
- BaseArg = _BaseArg;
- }
+ void setBaseArg(const Arg *BaseArg) { this->BaseArg = BaseArg; }
bool getOwnsValues() const { return OwnsValues; }
void setOwnsValues(bool Value) const { OwnsValues = Value; }
diff --git a/include/llvm/Option/ArgList.h b/include/llvm/Option/ArgList.h
index f5ded94..9a09309 100644
--- a/include/llvm/Option/ArgList.h
+++ b/include/llvm/Option/ArgList.h
@@ -11,7 +11,9 @@
#define LLVM_OPTION_ARGLIST_H
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Option/OptSpecifier.h"
#include "llvm/Option/Option.h"
#include <list>
@@ -52,10 +54,10 @@ public:
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- arg_iterator(SmallVectorImpl<Arg*>::const_iterator it,
- const ArgList &_Args, OptSpecifier _Id0 = 0U,
- OptSpecifier _Id1 = 0U, OptSpecifier _Id2 = 0U)
- : Current(it), Args(_Args), Id0(_Id0), Id1(_Id1), Id2(_Id2) {
+ arg_iterator(SmallVectorImpl<Arg *>::const_iterator it, const ArgList &Args,
+ OptSpecifier Id0 = 0U, OptSpecifier Id1 = 0U,
+ OptSpecifier Id2 = 0U)
+ : Current(it), Args(Args), Id0(Id0), Id1(Id1), Id2(Id2) {
SkipToNextArg();
}
@@ -188,6 +190,10 @@ public:
/// \p Claim Whether the argument should be claimed, if it exists.
Arg *getLastArgNoClaim(OptSpecifier Id) const;
Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1) const;
+ Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1,
+ OptSpecifier Id2) const;
+ Arg *getLastArgNoClaim(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2,
+ OptSpecifier Id3) const;
Arg *getLastArg(OptSpecifier Id) const;
Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1) const;
Arg *getLastArg(OptSpecifier Id0, OptSpecifier Id1, OptSpecifier Id2) const;
@@ -277,16 +283,13 @@ public:
/// @name Arg Synthesis
/// @{
- /// MakeArgString - Construct a constant string pointer whose
+ /// Construct a constant string pointer whose
/// lifetime will match that of the ArgList.
- virtual const char *MakeArgString(StringRef Str) const = 0;
- const char *MakeArgString(const char *Str) const {
- return MakeArgString(StringRef(Str));
+ virtual const char *MakeArgStringRef(StringRef Str) const = 0;
+ const char *MakeArgString(const Twine &Str) const {
+ SmallString<256> Buf;
+ return MakeArgStringRef(Str.toStringRef(Buf));
}
- const char *MakeArgString(std::string Str) const {
- return MakeArgString(StringRef(Str));
- }
- const char *MakeArgString(const Twine &Str) const;
/// \brief Create an arg string for (\p LHS + \p RHS), reusing the
/// string at \p Index if possible.
@@ -336,7 +339,7 @@ public:
unsigned MakeIndex(StringRef String0, StringRef String1) const;
using ArgList::MakeArgString;
- const char *MakeArgString(StringRef Str) const override;
+ const char *MakeArgStringRef(StringRef Str) const override;
/// @}
};
@@ -374,7 +377,7 @@ public:
void AddSynthesizedArg(Arg *A);
using ArgList::MakeArgString;
- const char *MakeArgString(StringRef Str) const override;
+ const char *MakeArgStringRef(StringRef Str) const override;
/// AddFlagArg - Construct a new FlagArg for the given option \p Id and
/// append it to the argument list.
diff --git a/include/llvm/Option/OptSpecifier.h b/include/llvm/Option/OptSpecifier.h
index 7206bf2..0b2aaae 100644
--- a/include/llvm/Option/OptSpecifier.h
+++ b/include/llvm/Option/OptSpecifier.h
@@ -25,7 +25,7 @@ namespace opt {
public:
OptSpecifier() : ID(0) {}
- /*implicit*/ OptSpecifier(unsigned _ID) : ID(_ID) {}
+ /*implicit*/ OptSpecifier(unsigned ID) : ID(ID) {}
/*implicit*/ OptSpecifier(const Option *Opt);
bool isValid() const { return ID != 0; }
diff --git a/include/llvm/Option/OptTable.h b/include/llvm/Option/OptTable.h
index 5035940..a7ff469 100644
--- a/include/llvm/Option/OptTable.h
+++ b/include/llvm/Option/OptTable.h
@@ -73,8 +73,9 @@ private:
}
protected:
- OptTable(const Info *_OptionInfos, unsigned _NumOptionInfos,
- bool _IgnoreCase = false);
+ OptTable(const Info *OptionInfos, unsigned NumOptionInfos,
+ bool IgnoreCase = false);
+
public:
~OptTable();
diff --git a/include/llvm/Option/Option.h b/include/llvm/Option/Option.h
index b2cfacb..09be26c 100644
--- a/include/llvm/Option/Option.h
+++ b/include/llvm/Option/Option.h
@@ -70,7 +70,6 @@ protected:
public:
Option(const OptTable::Info *Info, const OptTable *Owner);
- ~Option();
bool isValid() const {
return Info != nullptr;
diff --git a/include/llvm/Passes/PassBuilder.h b/include/llvm/Passes/PassBuilder.h
new file mode 100644
index 0000000..1e605e3
--- /dev/null
+++ b/include/llvm/Passes/PassBuilder.h
@@ -0,0 +1,105 @@
+//===- Parsing, selection, and construction of pass pipelines --*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Interfaces for registering analysis passes, producing common pass manager
+/// configurations, and parsing of pass pipelines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_PASSBUILDER_H
+#define LLVM_PASSES_PASSBUILDER_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+class TargetMachine;
+
+/// \brief This class provides access to building LLVM's passes.
+///
+/// It's members provide the baseline state available to passes during their
+/// construction. The \c PassRegistry.def file specifies how to construct all
+/// of the built-in passes, and those may reference these members during
+/// construction.
+class PassBuilder {
+ TargetMachine *TM;
+
+public:
+ explicit PassBuilder(TargetMachine *TM = nullptr) : TM(TM) {}
+
+ /// \brief Registers all available module analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c
+ /// ModuleAnalysisManager with all registered module analyses. Callers can
+ /// still manually register any additional analyses.
+ void registerModuleAnalyses(ModuleAnalysisManager &MAM);
+
+ /// \brief Registers all available CGSCC analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
+ /// with all registered CGSCC analyses. Callers can still manually register any
+ /// additional analyses.
+ void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
+
+ /// \brief Registers all available function analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c
+ /// FunctionAnalysisManager with all registered function analyses. Callers can
+ /// still manually register any additional analyses.
+ void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
+
+ /// \brief Parse a textual pass pipeline description into a \c ModulePassManager.
+ ///
+ /// The format of the textual pass pipeline description looks something like:
+ ///
+ /// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
+ ///
+ /// Pass managers have ()s describing the nest structure of passes. All passes
+ /// are comma separated. As a special shortcut, if the very first pass is not
+ /// a module pass (as a module pass manager is), this will automatically form
+ /// the shortest stack of pass managers that allow inserting that first pass.
+ /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop passes
+ /// 'lpassN', all of these are valid:
+ ///
+ /// fpass1,fpass2,fpass3
+ /// cgpass1,cgpass2,cgpass3
+ /// lpass1,lpass2,lpass3
+ ///
+ /// And they are equivalent to the following (resp.):
+ ///
+ /// module(function(fpass1,fpass2,fpass3))
+ /// module(cgscc(cgpass1,cgpass2,cgpass3))
+ /// module(function(loop(lpass1,lpass2,lpass3)))
+ ///
+ /// This shortcut is especially useful for debugging and testing small pass
+ /// combinations. Note that these shortcuts don't introduce any other magic. If
+ /// the sequence of passes aren't all the exact same kind of pass, it will be
+ /// an error. You cannot mix different levels implicitly, you must explicitly
+ /// form a pass manager in which to nest passes.
+ bool parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
+ bool VerifyEachPass = true, bool DebugLogging = false);
+
+private:
+ bool parseModulePassName(ModulePassManager &MPM, StringRef Name);
+ bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name);
+ bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name);
+ bool parseFunctionPassPipeline(FunctionPassManager &FPM,
+ StringRef &PipelineText, bool VerifyEachPass,
+ bool DebugLogging);
+ bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM, StringRef &PipelineText,
+ bool VerifyEachPass, bool DebugLogging);
+ bool parseModulePassPipeline(ModulePassManager &MPM, StringRef &PipelineText,
+ bool VerifyEachPass, bool DebugLogging);
+};
+
+}
+
+#endif
diff --git a/include/llvm/ProfileData/CoverageMapping.h b/include/llvm/ProfileData/CoverageMapping.h
index 4d393b3..e9d6ea5 100644
--- a/include/llvm/ProfileData/CoverageMapping.h
+++ b/include/llvm/ProfileData/CoverageMapping.h
@@ -18,11 +18,13 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/ADT/iterator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
+#include <tuple>
namespace llvm {
class IndexedInstrProfReader;
@@ -407,7 +409,8 @@ public:
/// \brief Load the coverage mapping from the given files.
static ErrorOr<std::unique_ptr<CoverageMapping>>
- load(StringRef ObjectFilename, StringRef ProfileFilename);
+ load(StringRef ObjectFilename, StringRef ProfileFilename,
+ Triple::ArchType Arch = Triple::ArchType::UnknownArch);
/// \brief The number of functions that couldn't have their profiles mapped.
///
diff --git a/include/llvm/ProfileData/CoverageMappingReader.h b/include/llvm/ProfileData/CoverageMappingReader.h
index 6714366..bc68f0b 100644
--- a/include/llvm/ProfileData/CoverageMappingReader.h
+++ b/include/llvm/ProfileData/CoverageMappingReader.h
@@ -17,6 +17,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/InstrProf.h"
@@ -175,7 +176,8 @@ private:
public:
static ErrorOr<std::unique_ptr<BinaryCoverageReader>>
- create(std::unique_ptr<MemoryBuffer> &ObjectBuffer);
+ create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
+ Triple::ArchType Arch = Triple::ArchType::UnknownArch);
std::error_code readNextRecord(CoverageMappingRecord &Record) override;
};
diff --git a/include/llvm/Support/ARMBuildAttributes.h b/include/llvm/Support/ARMBuildAttributes.h
index 96a8219..fc14cb2 100644
--- a/include/llvm/Support/ARMBuildAttributes.h
+++ b/include/llvm/Support/ARMBuildAttributes.h
@@ -100,13 +100,13 @@ enum CPUArch {
v5TEJ = 5, // e.g. ARM926EJ_S
v6 = 6, // e.g. ARM1136J_S
v6KZ = 7, // e.g. ARM1176JZ_S
- v6T2 = 8, // e.g. ARM1156T2F_S
- v6K = 9, // e.g. ARM1136J_S
+ v6T2 = 8, // e.g. ARM1156T2_S
+ v6K = 9, // e.g. ARM1176JZ_S
v7 = 10, // e.g. Cortex A8, Cortex M3
v6_M = 11, // e.g. Cortex M1
v6S_M = 12, // v6_M with the System extensions
v7E_M = 13, // v7_M with DSP extensions
- v8 = 14 // v8, AArch32
+ v8 = 14, // v8,v8.1a AArch32
};
enum CPUArchProfile { // (=7), uleb128
@@ -145,6 +145,7 @@ enum {
AllowNeon = 1, // SIMDv1 was permitted
AllowNeon2 = 2, // SIMDv2 was permitted (Half-precision FP, MAC operations)
AllowNeonARMv8 = 3, // ARM v8-A SIMD was permitted
+ AllowNeonARMv8_1a = 4,// ARM v8.1-A SIMD was permitted (RDMA)
// Tag_ABI_PCS_R9_use, (=14), uleb128
R9IsGPR = 0, // R9 used as v6 (just another callee-saved register)
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 64c5d96..bd1d1cb 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -352,9 +352,14 @@ struct cat {
// Support value comparison outside the template.
struct GenericOptionValue {
- virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+protected:
+ ~GenericOptionValue() = default;
+ GenericOptionValue() = default;
+ GenericOptionValue(const GenericOptionValue&) = default;
+ GenericOptionValue &operator=(const GenericOptionValue &) = default;
+
private:
virtual void anchor();
};
@@ -380,6 +385,9 @@ struct OptionValueBase : public GenericOptionValue {
bool compare(const GenericOptionValue & /*V*/) const override {
return false;
}
+
+protected:
+ ~OptionValueBase() = default;
};
// Simple copy of the option value.
@@ -387,6 +395,11 @@ template <class DataType> class OptionValueCopy : public GenericOptionValue {
DataType Value;
bool Valid;
+protected:
+ ~OptionValueCopy() = default;
+ OptionValueCopy(const OptionValueCopy&) = default;
+ OptionValueCopy &operator=(const OptionValueCopy&) = default;
+
public:
OptionValueCopy() : Valid(false) {}
@@ -417,12 +430,19 @@ public:
template <class DataType>
struct OptionValueBase<DataType, false> : OptionValueCopy<DataType> {
typedef DataType WrapperType;
+
+protected:
+ ~OptionValueBase() = default;
+ OptionValueBase() = default;
+ OptionValueBase(const OptionValueBase&) = default;
+ OptionValueBase &operator=(const OptionValueBase&) = default;
};
// Top-level option class.
template <class DataType>
-struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
- OptionValue() {}
+struct OptionValue final
+ : OptionValueBase<DataType, std::is_class<DataType>::value> {
+ OptionValue() = default;
OptionValue(const DataType &V) { this->setValue(V); }
// Some options may take their value from a different data type.
@@ -435,7 +455,8 @@ struct OptionValue : OptionValueBase<DataType, std::is_class<DataType>::value> {
// Other safe-to-copy-by-value common option types.
enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
template <>
-struct OptionValue<cl::boolOrDefault> : OptionValueCopy<cl::boolOrDefault> {
+struct OptionValue<cl::boolOrDefault> final
+ : OptionValueCopy<cl::boolOrDefault> {
typedef cl::boolOrDefault WrapperType;
OptionValue() {}
@@ -450,7 +471,8 @@ private:
void anchor() override;
};
-template <> struct OptionValue<std::string> : OptionValueCopy<std::string> {
+template <>
+struct OptionValue<std::string> final : OptionValueCopy<std::string> {
typedef StringRef WrapperType;
OptionValue() {}
@@ -692,7 +714,6 @@ class basic_parser_impl { // non-template implementation of basic_parser<t>
public:
basic_parser_impl(Option &O) {}
- virtual ~basic_parser_impl() {}
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueRequired;
@@ -721,6 +742,7 @@ public:
virtual void anchor();
protected:
+ ~basic_parser_impl() = default;
// A helper for basic_parser::printOptionDiff.
void printOptionName(const Option &O, size_t GlobalWidth) const;
};
@@ -733,12 +755,16 @@ public:
basic_parser(Option &O) : basic_parser_impl(O) {}
typedef DataType parser_data_type;
typedef OptionValue<DataType> OptVal;
+
+protected:
+ // Workaround Clang PR22793
+ ~basic_parser() {}
};
//--------------------------------------------------
// parser<bool>
//
-template <> class parser<bool> : public basic_parser<bool> {
+template <> class parser<bool> final : public basic_parser<bool> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -765,7 +791,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
//--------------------------------------------------
// parser<boolOrDefault>
-template <> class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+template <>
+class parser<boolOrDefault> final : public basic_parser<boolOrDefault> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -791,7 +818,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
//--------------------------------------------------
// parser<int>
//
-template <> class parser<int> : public basic_parser<int> {
+template <> class parser<int> final : public basic_parser<int> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -813,7 +840,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
//--------------------------------------------------
// parser<unsigned>
//
-template <> class parser<unsigned> : public basic_parser<unsigned> {
+template <> class parser<unsigned> final : public basic_parser<unsigned> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -836,7 +863,8 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
// parser<unsigned long long>
//
template <>
-class parser<unsigned long long> : public basic_parser<unsigned long long> {
+class parser<unsigned long long> final
+ : public basic_parser<unsigned long long> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -859,7 +887,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
//--------------------------------------------------
// parser<double>
//
-template <> class parser<double> : public basic_parser<double> {
+template <> class parser<double> final : public basic_parser<double> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -881,7 +909,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
//--------------------------------------------------
// parser<float>
//
-template <> class parser<float> : public basic_parser<float> {
+template <> class parser<float> final : public basic_parser<float> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -903,7 +931,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
//--------------------------------------------------
// parser<std::string>
//
-template <> class parser<std::string> : public basic_parser<std::string> {
+template <> class parser<std::string> final : public basic_parser<std::string> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -928,7 +956,7 @@ EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
//--------------------------------------------------
// parser<char>
//
-template <> class parser<char> : public basic_parser<char> {
+template <> class parser<char> final : public basic_parser<char> {
public:
parser(Option &O) : basic_parser(O) {}
@@ -967,7 +995,7 @@ void printOptionDiff(const Option &O, const generic_parser_base &P, const DT &V,
// This is instantiated for basic parsers when the parsed value has a different
// type than the option value. e.g. HelpPrinter.
template <class ParserDT, class ValDT> struct OptionDiffPrinter {
- void print(const Option &O, const parser<ParserDT> P, const ValDT & /*V*/,
+ void print(const Option &O, const parser<ParserDT> &P, const ValDT & /*V*/,
const OptionValue<ValDT> & /*Default*/, size_t GlobalWidth) {
P.printOptionNoValue(O, GlobalWidth);
}
@@ -976,7 +1004,7 @@ template <class ParserDT, class ValDT> struct OptionDiffPrinter {
// This is instantiated for basic parsers when the parsed value has the same
// type as the option value.
template <class DT> struct OptionDiffPrinter<DT, DT> {
- void print(const Option &O, const parser<DT> P, const DT &V,
+ void print(const Option &O, const parser<DT> &P, const DT &V,
const OptionValue<DT> &Default, size_t GlobalWidth) {
P.printOptionDiff(O, V, Default, GlobalWidth);
}
diff --git a/include/llvm/Support/Compression.h b/include/llvm/Support/Compression.h
index 88727fa..28274d6 100644
--- a/include/llvm/Support/Compression.h
+++ b/include/llvm/Support/Compression.h
@@ -14,12 +14,10 @@
#ifndef LLVM_SUPPORT_COMPRESSION_H
#define LLVM_SUPPORT_COMPRESSION_H
-#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/DataTypes.h"
-#include <memory>
namespace llvm {
-
+template <typename T> class SmallVectorImpl;
class StringRef;
namespace zlib {
diff --git a/include/llvm/Support/CrashRecoveryContext.h b/include/llvm/Support/CrashRecoveryContext.h
index 1f3965c..c08c3c1 100644
--- a/include/llvm/Support/CrashRecoveryContext.h
+++ b/include/llvm/Support/CrashRecoveryContext.h
@@ -14,8 +14,6 @@
#include <string>
namespace llvm {
-class StringRef;
-
class CrashRecoveryContextCleanup;
/// \brief Crash recovery helper object.
diff --git a/include/llvm/Support/DataExtractor.h b/include/llvm/Support/DataExtractor.h
index 48235d4..3ffa9bc 100644
--- a/include/llvm/Support/DataExtractor.h
+++ b/include/llvm/Support/DataExtractor.h
@@ -10,7 +10,6 @@
#ifndef LLVM_SUPPORT_DATAEXTRACTOR_H
#define LLVM_SUPPORT_DATAEXTRACTOR_H
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/DataTypes.h"
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
index e93e6ca..fff4f98 100644
--- a/include/llvm/Support/Debug.h
+++ b/include/llvm/Support/Debug.h
@@ -28,9 +28,8 @@
#ifndef LLVM_SUPPORT_DEBUG_H
#define LLVM_SUPPORT_DEBUG_H
-#include "llvm/Support/raw_ostream.h"
-
namespace llvm {
+class raw_ostream;
#ifndef NDEBUG
/// DebugFlag - This boolean is set to true if the '-debug' command line option
diff --git a/include/llvm/Support/Dwarf.def b/include/llvm/Support/Dwarf.def
index c663af9..4b923b8 100644
--- a/include/llvm/Support/Dwarf.def
+++ b/include/llvm/Support/Dwarf.def
@@ -102,7 +102,6 @@ HANDLE_DW_TAG(0x0043, template_alias)
// Mock tags we use as discriminators.
HANDLE_DW_TAG(0x0100, auto_variable) // Tag for local (auto) variables.
HANDLE_DW_TAG(0x0101, arg_variable) // Tag for argument variables.
-HANDLE_DW_TAG(0x0102, expression) // Tag for complex address expressions.
// New in DWARF v5.
HANDLE_DW_TAG(0x0044, coarray_type)
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
index fc6f314..d7f1533 100644
--- a/include/llvm/Support/ELF.h
+++ b/include/llvm/Support/ELF.h
@@ -344,6 +344,7 @@ enum {
ELFOSABI_NSK = 14, // Hewlett-Packard Non-Stop Kernel
ELFOSABI_AROS = 15, // AROS
ELFOSABI_FENIXOS = 16, // FenixOS
+ ELFOSABI_CLOUDABI = 17, // Nuxi CloudABI
ELFOSABI_C6000_ELFABI = 64, // Bare-metal TMS320C6000
ELFOSABI_C6000_LINUX = 65, // Linux TMS320C6000
ELFOSABI_ARM = 97, // ARM
diff --git a/include/llvm/Support/Endian.h b/include/llvm/Support/Endian.h
index 47b82fd..e9fe22e 100644
--- a/include/llvm/Support/Endian.h
+++ b/include/llvm/Support/Endian.h
@@ -58,8 +58,9 @@ inline value_type read(const void *memory) {
/// Read a value of a particular endianness from a buffer, and increment the
/// buffer past that value.
-template<typename value_type, endianness endian, std::size_t alignment>
-inline value_type readNext(const unsigned char *&memory) {
+template<typename value_type, endianness endian, std::size_t alignment,
+ typename CharT>
+inline value_type readNext(const CharT *&memory) {
value_type ret = read<value_type, endian, alignment>(memory);
memory += sizeof(value_type);
return ret;
@@ -195,7 +196,23 @@ typedef detail::packed_endian_specific_integral
<int32_t, native, unaligned> unaligned_int32_t;
typedef detail::packed_endian_specific_integral
<int64_t, native, unaligned> unaligned_int64_t;
-} // end namespace llvm
+
+namespace endian {
+inline uint16_t read16le(const void *p) { return *(const ulittle16_t *)p; }
+inline uint32_t read32le(const void *p) { return *(const ulittle32_t *)p; }
+inline uint64_t read64le(const void *p) { return *(const ulittle64_t *)p; }
+inline uint16_t read16be(const void *p) { return *(const ubig16_t *)p; }
+inline uint32_t read32be(const void *p) { return *(const ubig32_t *)p; }
+inline uint64_t read64be(const void *p) { return *(const ubig64_t *)p; }
+
+inline void write16le(void *p, uint16_t v) { *(ulittle16_t *)p = v; }
+inline void write32le(void *p, uint32_t v) { *(ulittle32_t *)p = v; }
+inline void write64le(void *p, uint64_t v) { *(ulittle64_t *)p = v; }
+inline void write16be(void *p, uint16_t v) { *(ubig16_t *)p = v; }
+inline void write32be(void *p, uint32_t v) { *(ubig32_t *)p = v; }
+inline void write64be(void *p, uint64_t v) { *(ubig64_t *)p = v; }
+} // end namespace endian
} // end namespace support
+} // end namespace llvm
#endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
index 3f2f176..2ee2c60 100644
--- a/include/llvm/Support/FileUtilities.h
+++ b/include/llvm/Support/FileUtilities.h
@@ -51,7 +51,7 @@ namespace llvm {
~FileRemover() {
if (DeleteIt) {
// Ignore problems deleting the file.
- sys::fs::remove(Filename.str());
+ sys::fs::remove(Filename);
}
}
@@ -61,7 +61,7 @@ namespace llvm {
void setFile(const Twine& filename, bool deleteIt = true) {
if (DeleteIt) {
// Ignore problems deleting the file.
- sys::fs::remove(Filename.str());
+ sys::fs::remove(Filename);
}
Filename.clear();
diff --git a/include/llvm/Support/Format.h b/include/llvm/Support/Format.h
index 682c5a9..4319a3b 100644
--- a/include/llvm/Support/Format.h
+++ b/include/llvm/Support/Format.h
@@ -37,7 +37,8 @@ namespace llvm {
class format_object_base {
protected:
const char *Fmt;
- ~format_object_base() {} // Disallow polymorphic deletion.
+ ~format_object_base() = default; // Disallow polymorphic deletion.
+ format_object_base(const format_object_base &) = default;
virtual void home(); // Out of line virtual method.
/// Call snprintf() for this object, on the given buffer and size.
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
index 2f02aa7..7d1c273 100644
--- a/include/llvm/Support/GraphWriter.h
+++ b/include/llvm/Support/GraphWriter.h
@@ -24,10 +24,9 @@
#define LLVM_SUPPORT_GRAPHWRITER_H
#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Support/DOTGraphTraits.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include <cassert>
#include <vector>
namespace llvm {
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
index acffb46..388d82c 100644
--- a/include/llvm/Support/MathExtras.h
+++ b/include/llvm/Support/MathExtras.h
@@ -534,14 +534,6 @@ inline uint32_t FloatToBits(float Float) {
return T.I;
}
-/// Platform-independent wrappers for the C99 isnan() function.
-int IsNAN(float f);
-int IsNAN(double d);
-
-/// Platform-independent wrappers for the C99 isinf() function.
-int IsInf(float f);
-int IsInf(double d);
-
/// MinAlign - A and B are either alignments or offsets. Return the minimum
/// alignment that may be assumed after adding the two together.
inline uint64_t MinAlign(uint64_t A, uint64_t B) {
@@ -612,13 +604,6 @@ inline uint64_t OffsetToAlignment(uint64_t Value, uint64_t Align) {
return RoundUpToAlignment(Value, Align) - Value;
}
-/// abs64 - absolute value of a 64-bit int. Not all environments support
-/// "abs" on whatever their name for the 64-bit int type is. The absolute
-/// value of the largest negative number is undefined, as with "abs".
-inline int64_t abs64(int64_t x) {
- return (x < 0) ? -x : x;
-}
-
/// SignExtend32 - Sign extend B-bit number x to 32-bit int.
/// Usage int32_t r = SignExtend32<5>(x);
template <unsigned B> inline int32_t SignExtend32(uint32_t x) {
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
index cc65ca5..35a7bdb 100644
--- a/include/llvm/Support/MemoryBuffer.h
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -17,11 +17,9 @@
#include "llvm-c/Support.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/CBindingWrapping.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorOr.h"
#include <memory>
-#include <system_error>
namespace llvm {
class MemoryBufferRef;
diff --git a/include/llvm/Support/Program.h b/include/llvm/Support/Program.h
index 40dc60f..b89a0f7 100644
--- a/include/llvm/Support/Program.h
+++ b/include/llvm/Support/Program.h
@@ -16,10 +16,11 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/Path.h"
#include <system_error>
namespace llvm {
+class StringRef;
+
namespace sys {
/// This is the OS-specific separator for PATH like environment variables:
diff --git a/include/llvm/Support/Regex.h b/include/llvm/Support/Regex.h
index 5e5a5a3..31b35ed 100644
--- a/include/llvm/Support/Regex.h
+++ b/include/llvm/Support/Regex.h
@@ -17,7 +17,6 @@
#ifndef LLVM_SUPPORT_REGEX_H
#define LLVM_SUPPORT_REGEX_H
-#include "llvm/Support/Compiler.h"
#include <string>
struct llvm_regex;
diff --git a/include/llvm/Support/Signals.h b/include/llvm/Support/Signals.h
index 6b1da2a..a067b13 100644
--- a/include/llvm/Support/Signals.h
+++ b/include/llvm/Support/Signals.h
@@ -15,10 +15,12 @@
#ifndef LLVM_SUPPORT_SIGNALS_H
#define LLVM_SUPPORT_SIGNALS_H
-#include "llvm/Support/Path.h"
-#include <cstdio>
+#include <string>
namespace llvm {
+class StringRef;
+class raw_ostream;
+
namespace sys {
/// This function runs all the registered interrupt handlers, including the
@@ -42,8 +44,8 @@ namespace sys {
/// Disable all system dialog boxes that appear when the process crashes.
void DisableSystemDialogsOnCrash();
- /// \brief Print the stack trace using the given \c FILE object.
- void PrintStackTrace(FILE *);
+ /// \brief Print the stack trace using the given \c raw_ostream object.
+ void PrintStackTrace(raw_ostream &OS);
/// 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
diff --git a/include/llvm/Support/StreamingMemoryObject.h b/include/llvm/Support/StreamingMemoryObject.h
index f914817..fb63da7 100644
--- a/include/llvm/Support/StreamingMemoryObject.h
+++ b/include/llvm/Support/StreamingMemoryObject.h
@@ -14,7 +14,6 @@
#include "llvm/Support/DataStream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryObject.h"
-#include <cassert>
#include <memory>
#include <vector>
diff --git a/include/llvm/Support/StringPool.h b/include/llvm/Support/StringPool.h
index 675adde..2ec0c3b 100644
--- a/include/llvm/Support/StringPool.h
+++ b/include/llvm/Support/StringPool.h
@@ -30,9 +30,7 @@
#define LLVM_SUPPORT_STRINGPOOL_H
#include "llvm/ADT/StringMap.h"
-#include "llvm/Support/Compiler.h"
#include <cassert>
-#include <new>
namespace llvm {
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
index d2d08b2..2997b1b 100644
--- a/include/llvm/Support/SystemUtils.h
+++ b/include/llvm/Support/SystemUtils.h
@@ -15,8 +15,6 @@
#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
#define LLVM_SUPPORT_SYSTEMUTILS_H
-#include <string>
-
namespace llvm {
class raw_ostream;
diff --git a/include/llvm/Support/TargetRegistry.h b/include/llvm/Support/TargetRegistry.h
index 7a71f6d..ba6bbde 100644
--- a/include/llvm/Support/TargetRegistry.h
+++ b/include/llvm/Support/TargetRegistry.h
@@ -28,8 +28,6 @@
namespace llvm {
class AsmPrinter;
- class Module;
- class MCAssembler;
class MCAsmBackend;
class MCAsmInfo;
class MCAsmParser;
@@ -59,6 +57,15 @@ namespace llvm {
MCInstPrinter *InstPrint, MCCodeEmitter *CE,
MCAsmBackend *TAB, bool ShowInst);
+ /// Takes ownership of \p TAB and \p CE.
+ MCStreamer *createELFStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll);
+ MCStreamer *createMachOStreamer(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool DWARFMustBeAtTheEnd,
+ bool LabelSections = false);
+
MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx);
MCSymbolizer *createMCSymbolizer(StringRef TT, LLVMOpInfoCallback GetOpInfo,
@@ -125,21 +132,24 @@ namespace llvm {
const MCSubtargetInfo &STI);
typedef MCCodeEmitter *(*MCCodeEmitterCtorTy)(const MCInstrInfo &II,
const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI,
MCContext &Ctx);
- typedef MCStreamer *(*MCObjectStreamerCtorTy)(
- const Target &T, StringRef TT, MCContext &Ctx, MCAsmBackend &TAB,
- raw_ostream &_OS, MCCodeEmitter *_Emitter, const MCSubtargetInfo &STI,
- bool RelaxAll);
- typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
- formatted_raw_ostream &OS,
- bool isVerboseAsm,
- bool useDwarfDirectory,
- MCInstPrinter *InstPrint,
- MCCodeEmitter *CE,
- MCAsmBackend *TAB,
- bool ShowInst);
+ typedef MCStreamer *(*ELFStreamerCtorTy)(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
+ typedef MCStreamer *(*MachOStreamerCtorTy)(
+ MCContext &Ctx, MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter, bool RelaxAll, bool DWARFMustBeAtTheEnd);
+ typedef MCStreamer *(*COFFStreamerCtorTy)(MCContext &Ctx, MCAsmBackend &TAB,
+ raw_ostream &OS,
+ MCCodeEmitter *Emitter,
+ bool RelaxAll);
typedef MCTargetStreamer *(*NullTargetStreamerCtorTy)(MCStreamer &S);
+ typedef MCTargetStreamer *(*AsmTargetStreamerCtorTy)(
+ MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint,
+ bool IsVerboseAsm);
+ typedef MCTargetStreamer *(*ObjectTargetStreamerCtorTy)(
+ MCStreamer &S, const MCSubtargetInfo &STI);
typedef MCRelocationInfo *(*MCRelocationInfoCtorTy)(StringRef TT,
MCContext &Ctx);
typedef MCSymbolizer *(*MCSymbolizerCtorTy)(
@@ -216,18 +226,23 @@ namespace llvm {
/// CodeEmitter, if registered.
MCCodeEmitterCtorTy MCCodeEmitterCtorFn;
- /// MCObjectStreamerCtorFn - Construction function for this target's
- /// MCObjectStreamer, if registered.
- MCObjectStreamerCtorTy MCObjectStreamerCtorFn;
-
- /// AsmStreamerCtorFn - Construction function for this target's
- /// AsmStreamer, if registered (default = llvm::createAsmStreamer).
- AsmStreamerCtorTy AsmStreamerCtorFn;
+ // Construction functions for the various object formats, if registered.
+ COFFStreamerCtorTy COFFStreamerCtorFn;
+ MachOStreamerCtorTy MachOStreamerCtorFn;
+ ELFStreamerCtorTy ELFStreamerCtorFn;
/// Construction function for this target's null TargetStreamer, if
/// registered (default = nullptr).
NullTargetStreamerCtorTy NullTargetStreamerCtorFn;
+ /// Construction function for this target's asm TargetStreamer, if
+ /// registered (default = nullptr).
+ AsmTargetStreamerCtorTy AsmTargetStreamerCtorFn;
+
+ /// Construction function for this target's obj TargetStreamer, if
+ /// registered (default = nullptr).
+ ObjectTargetStreamerCtorTy ObjectTargetStreamerCtorFn;
+
/// MCRelocationInfoCtorFn - Construction function for this target's
/// MCRelocationInfo, if registered (default = llvm::createMCRelocationInfo)
MCRelocationInfoCtorTy MCRelocationInfoCtorFn;
@@ -238,8 +253,10 @@ namespace llvm {
public:
Target()
- : AsmStreamerCtorFn(nullptr), MCRelocationInfoCtorFn(nullptr),
- MCSymbolizerCtorFn(nullptr) {}
+ : COFFStreamerCtorFn(nullptr), MachOStreamerCtorFn(nullptr),
+ ELFStreamerCtorFn(nullptr), NullTargetStreamerCtorFn(nullptr),
+ AsmTargetStreamerCtorFn(nullptr), ObjectTargetStreamerCtorFn(nullptr),
+ MCRelocationInfoCtorFn(nullptr), MCSymbolizerCtorFn(nullptr) {}
/// @name Target Information
/// @{
@@ -406,46 +423,72 @@ namespace llvm {
/// createMCCodeEmitter - Create a target specific code emitter.
MCCodeEmitter *createMCCodeEmitter(const MCInstrInfo &II,
const MCRegisterInfo &MRI,
- const MCSubtargetInfo &STI,
MCContext &Ctx) const {
if (!MCCodeEmitterCtorFn)
return nullptr;
- return MCCodeEmitterCtorFn(II, MRI, STI, Ctx);
+ return MCCodeEmitterCtorFn(II, MRI, Ctx);
}
- /// createMCObjectStreamer - Create a target specific MCStreamer.
+ /// Create a target specific MCStreamer.
///
- /// \param TT The target triple.
+ /// \param T The target triple.
/// \param Ctx The target context.
/// \param TAB The target assembler backend object. Takes ownership.
- /// \param _OS The stream object.
- /// \param _Emitter The target independent assembler object.Takes ownership.
+ /// \param OS The stream object.
+ /// \param Emitter The target independent assembler object.Takes ownership.
/// \param RelaxAll Relax all fixups?
- MCStreamer *createMCObjectStreamer(StringRef TT, MCContext &Ctx,
- MCAsmBackend &TAB, raw_ostream &_OS,
- MCCodeEmitter *_Emitter,
+ MCStreamer *createMCObjectStreamer(const Triple &T, MCContext &Ctx,
+ MCAsmBackend &TAB, raw_ostream &OS,
+ MCCodeEmitter *Emitter,
const MCSubtargetInfo &STI,
- bool RelaxAll) const {
- if (!MCObjectStreamerCtorFn)
- return nullptr;
- return MCObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, STI,
- RelaxAll);
- }
-
- /// createAsmStreamer - Create a target specific MCStreamer.
- MCStreamer *createAsmStreamer(MCContext &Ctx,
- formatted_raw_ostream &OS,
- bool isVerboseAsm,
- bool useDwarfDirectory,
- MCInstPrinter *InstPrint,
- MCCodeEmitter *CE,
- MCAsmBackend *TAB,
- bool ShowInst) const {
- if (AsmStreamerCtorFn)
- return AsmStreamerCtorFn(Ctx, OS, isVerboseAsm, useDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
- return llvm::createAsmStreamer(Ctx, OS, isVerboseAsm, useDwarfDirectory,
- InstPrint, CE, TAB, ShowInst);
+ bool RelaxAll,
+ bool DWARFMustBeAtTheEnd) const {
+ MCStreamer *S;
+ switch (T.getObjectFormat()) {
+ default:
+ llvm_unreachable("Unknown object format");
+ case Triple::COFF:
+ assert(T.isOSWindows() && "only Windows COFF is supported");
+ S = COFFStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll);
+ break;
+ case Triple::MachO:
+ if (MachOStreamerCtorFn)
+ S = MachOStreamerCtorFn(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
+ else
+ S = createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll,
+ DWARFMustBeAtTheEnd);
+ break;
+ case Triple::ELF:
+ if (ELFStreamerCtorFn)
+ S = ELFStreamerCtorFn(T, Ctx, TAB, OS, Emitter, RelaxAll);
+ else
+ S = createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ break;
+ }
+ if (ObjectTargetStreamerCtorFn)
+ ObjectTargetStreamerCtorFn(*S, STI);
+ return S;
+ }
+
+ MCStreamer *createAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS,
+ bool IsVerboseAsm, bool UseDwarfDirectory,
+ MCInstPrinter *InstPrint, MCCodeEmitter *CE,
+ MCAsmBackend *TAB, bool ShowInst) const {
+ MCStreamer *S =
+ llvm::createAsmStreamer(Ctx, OS, IsVerboseAsm, UseDwarfDirectory,
+ InstPrint, CE, TAB, ShowInst);
+ createAsmTargetStreamer(*S, OS, InstPrint, IsVerboseAsm);
+ return S;
+ }
+
+ MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
+ formatted_raw_ostream &OS,
+ MCInstPrinter *InstPrint,
+ bool IsVerboseAsm) const {
+ if (AsmTargetStreamerCtorFn)
+ return AsmTargetStreamerCtorFn(S, OS, InstPrint, IsVerboseAsm);
+ return nullptr;
}
MCStreamer *createNullStreamer(MCContext &Ctx) const {
@@ -759,31 +802,17 @@ namespace llvm {
T.MCCodeEmitterCtorFn = Fn;
}
- /// RegisterMCObjectStreamer - Register a object code MCStreamer
- /// implementation for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCStreamer for the target.
- static void RegisterMCObjectStreamer(Target &T,
- Target::MCObjectStreamerCtorTy Fn) {
- T.MCObjectStreamerCtorFn = Fn;
+ static void RegisterCOFFStreamer(Target &T, Target::COFFStreamerCtorTy Fn) {
+ T.COFFStreamerCtorFn = Fn;
}
- /// RegisterAsmStreamer - Register an assembly MCStreamer implementation
- /// for the given target.
- ///
- /// Clients are responsible for ensuring that registration doesn't occur
- /// while another thread is attempting to access the registry. Typically
- /// this is done by initializing all targets at program startup.
- ///
- /// @param T - The target being registered.
- /// @param Fn - A function to construct an MCStreamer for the target.
- static void RegisterAsmStreamer(Target &T, Target::AsmStreamerCtorTy Fn) {
- T.AsmStreamerCtorFn = Fn;
+ static void RegisterMachOStreamer(Target &T,
+ Target::MachOStreamerCtorTy Fn) {
+ T.MachOStreamerCtorFn = Fn;
+ }
+
+ static void RegisterELFStreamer(Target &T, Target::ELFStreamerCtorTy Fn) {
+ T.ELFStreamerCtorFn = Fn;
}
static void
@@ -791,6 +820,17 @@ namespace llvm {
T.NullTargetStreamerCtorFn = Fn;
}
+ static void RegisterAsmTargetStreamer(Target &T,
+ Target::AsmTargetStreamerCtorTy Fn) {
+ T.AsmTargetStreamerCtorFn = Fn;
+ }
+
+ static void
+ RegisterObjectTargetStreamer(Target &T,
+ Target::ObjectTargetStreamerCtorTy Fn) {
+ T.ObjectTargetStreamerCtorFn = Fn;
+ }
+
/// RegisterMCRelocationInfo - Register an MCRelocationInfo
/// implementation for the given target.
///
@@ -1152,10 +1192,9 @@ namespace llvm {
}
private:
- static MCCodeEmitter *Allocator(const MCInstrInfo &/*II*/,
- const MCRegisterInfo &/*MRI*/,
- const MCSubtargetInfo &/*STI*/,
- MCContext &/*Ctx*/) {
+ static MCCodeEmitter *Allocator(const MCInstrInfo & /*II*/,
+ const MCRegisterInfo & /*MRI*/,
+ MCContext & /*Ctx*/) {
return new MCCodeEmitterImpl();
}
};
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
index 442b361..2cd30e2 100644
--- a/include/llvm/Support/Timer.h
+++ b/include/llvm/Support/Timer.h
@@ -11,7 +11,6 @@
#define LLVM_SUPPORT_TIMER_H
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <cassert>
#include <string>
diff --git a/include/llvm/Support/UnicodeCharRanges.h b/include/llvm/Support/UnicodeCharRanges.h
index 79137bf..9f738df 100644
--- a/include/llvm/Support/UnicodeCharRanges.h
+++ b/include/llvm/Support/UnicodeCharRanges.h
@@ -50,9 +50,13 @@ public:
/// the UnicodeCharSet instance, and should not change. Array is validated by
/// the constructor, so it makes sense to create as few UnicodeCharSet
/// instances per each array of ranges, as possible.
+#ifdef NDEBUG
+ LLVM_CONSTEXPR UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {}
+#else
UnicodeCharSet(CharRanges Ranges) : Ranges(Ranges) {
assert(rangesAreValid());
}
+#endif
/// \brief Returns true if the character set contains the Unicode code point
/// \p C.
diff --git a/include/llvm/Support/YAMLParser.h b/include/llvm/Support/YAMLParser.h
index de6e654..3d42329 100644
--- a/include/llvm/Support/YAMLParser.h
+++ b/include/llvm/Support/YAMLParser.h
@@ -38,19 +38,18 @@
#ifndef LLVM_SUPPORT_YAMLPARSER_H
#define LLVM_SUPPORT_YAMLPARSER_H
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
-#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h"
#include <limits>
#include <map>
#include <utility>
namespace llvm {
+class MemoryBufferRef;
class SourceMgr;
-class raw_ostream;
class Twine;
+class raw_ostream;
namespace yaml {
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 94686d9..12783c7 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -14,8 +14,8 @@
#ifndef LLVM_SUPPORT_RAW_OSTREAM_H
#define LLVM_SUPPORT_RAW_OSTREAM_H
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include <system_error>
@@ -185,6 +185,10 @@ public:
return write(Str.data(), Str.length());
}
+ raw_ostream &operator<<(const llvm::SmallVectorImpl<char> &Str) {
+ return write(Str.data(), Str.size());
+ }
+
raw_ostream &operator<<(unsigned long N);
raw_ostream &operator<<(long N);
raw_ostream &operator<<(unsigned long long N);
diff --git a/include/llvm/TableGen/Record.h b/include/llvm/TableGen/Record.h
index e8d22d9..5233493 100644
--- a/include/llvm/TableGen/Record.h
+++ b/include/llvm/TableGen/Record.h
@@ -1477,7 +1477,7 @@ public:
return false;
}
bool isTemplateArg(StringRef Name) const {
- return isTemplateArg(StringInit::get(Name.str()));
+ return isTemplateArg(StringInit::get(Name));
}
const RecordVal *getValue(const Init *Name) const {
@@ -1502,7 +1502,7 @@ public:
TemplateArgs.push_back(Name);
}
void addTemplateArg(StringRef Name) {
- addTemplateArg(StringInit::get(Name.str()));
+ addTemplateArg(StringInit::get(Name));
}
void addValue(const RecordVal &RV) {
@@ -1527,7 +1527,7 @@ public:
}
void removeValue(StringRef Name) {
- removeValue(StringInit::get(Name.str()));
+ removeValue(StringInit::get(Name));
}
bool isSubClassOf(const Record *R) const {
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 3e65a5d..6c970d0 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -397,8 +397,7 @@ class Instruction {
// captured by any operands of the instruction or other flags.
//
bit hasSideEffects = ?;
- bit hasTwoExplicitDefs = 0; // Does this instruction have 2 explicit
- // destinations?
+
// Is this instruction a "real" instruction (with a distinct machine
// encoding), or is it a pseudo instruction used for codegen modeling
// purposes.
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
index 247f9d8..110976a 100644
--- a/include/llvm/Target/TargetInstrInfo.h
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -207,7 +207,7 @@ public:
/// this, particularly to support spilled vector registers.
virtual bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
unsigned &Size, unsigned &Offset,
- const TargetMachine *TM) const;
+ const MachineFunction &MF) const;
/// isAsCheapAsAMove - Return true if the instruction is as cheap as a move
/// instruction.
@@ -672,16 +672,15 @@ public:
/// operand folded, otherwise NULL is returned.
/// The new instruction is inserted before MI, and the client is responsible
/// for removing the old instruction.
- MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
- const SmallVectorImpl<unsigned> &Ops,
- int FrameIndex) const;
+ MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI,
+ ArrayRef<unsigned> Ops, int FrameIndex) const;
/// foldMemoryOperand - Same as the previous version except it allows folding
/// of any load and store from / to any address, not just from a specific
/// stack slot.
- MachineInstr* foldMemoryOperand(MachineBasicBlock::iterator MI,
- const SmallVectorImpl<unsigned> &Ops,
- MachineInstr* LoadMI) const;
+ MachineInstr *foldMemoryOperand(MachineBasicBlock::iterator MI,
+ ArrayRef<unsigned> Ops,
+ MachineInstr *LoadMI) const;
/// hasPattern - return true when there is potentially a faster code sequence
/// for an instruction chain ending in \p Root. All potential pattern are
@@ -723,20 +722,20 @@ protected:
/// foldMemoryOperandImpl - Target-dependent implementation for
/// foldMemoryOperand. Target-independent code in foldMemoryOperand will
/// take care of adding a MachineMemOperand to the newly created instruction.
- virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
- MachineInstr* MI,
- const SmallVectorImpl<unsigned> &Ops,
- int FrameIndex) const {
+ virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr *MI,
+ ArrayRef<unsigned> Ops,
+ int FrameIndex) const {
return nullptr;
}
/// foldMemoryOperandImpl - Target-dependent implementation for
/// foldMemoryOperand. Target-independent code in foldMemoryOperand will
/// take care of adding a MachineMemOperand to the newly created instruction.
- virtual MachineInstr* foldMemoryOperandImpl(MachineFunction &MF,
- MachineInstr* MI,
- const SmallVectorImpl<unsigned> &Ops,
- MachineInstr* LoadMI) const {
+ virtual MachineInstr *foldMemoryOperandImpl(MachineFunction &MF,
+ MachineInstr *MI,
+ ArrayRef<unsigned> Ops,
+ MachineInstr *LoadMI) const {
return nullptr;
}
@@ -786,9 +785,8 @@ protected:
public:
/// canFoldMemoryOperand - Returns true for the specified load / store if
/// folding is possible.
- virtual
- bool canFoldMemoryOperand(const MachineInstr *MI,
- const SmallVectorImpl<unsigned> &Ops) const;
+ virtual bool canFoldMemoryOperand(const MachineInstr *MI,
+ ArrayRef<unsigned> Ops) const;
/// unfoldMemoryOperand - Separate a single instruction which folded a load or
/// a store or a load and a store into two or more instruction. If this is
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
index 4118917..29ecedc 100644
--- a/include/llvm/Target/TargetLowering.h
+++ b/include/llvm/Target/TargetLowering.h
@@ -123,6 +123,18 @@ public:
// mask (ex: x86 blends).
};
+ /// Enum that specifies what a AtomicRMWInst is expanded to, if at all. Exists
+ /// because different targets have different levels of support for these
+ /// atomic RMW instructions, and also have different options w.r.t. what they should
+ /// expand to.
+ enum class AtomicRMWExpansionKind {
+ None, // Don't expand the instruction.
+ LLSC, // Expand the instruction into loadlinked/storeconditional; used
+ // by ARM/AArch64. Implies `hasLoadLinkedStoreConditional`
+ // returns true.
+ CmpXChg, // Expand the instruction into cmpxchg; used by at least X86.
+ };
+
static ISD::NodeType getExtendForContent(BooleanContent Content) {
switch (Content) {
case UndefinedBooleanContent:
@@ -148,7 +160,7 @@ protected:
public:
const TargetMachine &getTargetMachine() const { return TM; }
- const DataLayout *getDataLayout() const { return DL; }
+ const DataLayout *getDataLayout() const { return TM.getDataLayout(); }
bool isBigEndian() const { return !IsLittleEndian; }
bool isLittleEndian() const { return IsLittleEndian; }
@@ -964,6 +976,15 @@ public:
return false;
}
+ /// Return true if the pointer arguments to CI should be aligned by aligning
+ /// the object whose address is being passed. If so then MinSize is set to the
+ /// minimum size the object must be to be aligned and PrefAlign is set to the
+ /// preferred alignment.
+ virtual bool shouldAlignPointerArgs(CallInst * /*CI*/, unsigned & /*MinSize*/,
+ unsigned & /*PrefAlign*/) const {
+ return false;
+ }
+
//===--------------------------------------------------------------------===//
/// \name Helpers for TargetTransformInfo implementations
/// @{
@@ -1059,15 +1080,21 @@ public:
return false;
}
+ /// Returns true if arguments should be sign-extended in lib calls.
+ virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
+ return IsSigned;
+ }
+
/// Returns true if the given (atomic) load should be expanded by the
/// IR-level AtomicExpand pass into a load-linked instruction
/// (through emitLoadLinked()).
virtual bool shouldExpandAtomicLoadInIR(LoadInst *LI) const { return false; }
- /// Returns true if the given AtomicRMW should be expanded by the
- /// IR-level AtomicExpand pass into a loop using LoadLinked/StoreConditional.
- virtual bool shouldExpandAtomicRMWInIR(AtomicRMWInst *RMWI) const {
- return false;
+ /// Returns how the IR-level AtomicExpand pass should expand the given
+ /// AtomicRMW, if at all. Default is to never expand.
+ virtual AtomicRMWExpansionKind
+ shouldExpandAtomicRMWInIR(AtomicRMWInst *) const {
+ return AtomicRMWExpansionKind::None;
}
/// On some platforms, an AtomicRMW that never actually modifies the value
@@ -1084,6 +1111,25 @@ public:
virtual LoadInst *lowerIdempotentRMWIntoFencedLoad(AtomicRMWInst *RMWI) const {
return nullptr;
}
+
+ /// Returns true if we should normalize
+ /// select(N0&N1, X, Y) => select(N0, select(N1, X, Y), Y) and
+ /// select(N0|N1, X, Y) => select(N0, select(N1, X, Y, Y)) if it is likely
+ /// that it saves us from materializing N0 and N1 in an integer register.
+ /// Targets that are able to perform and/or on flags should return false here.
+ virtual bool shouldNormalizeToSelectSequence(LLVMContext &Context,
+ EVT VT) const {
+ // If a target has multiple condition registers, then it likely has logical
+ // operations on those registers.
+ if (hasMultipleConditionRegisters())
+ return false;
+ // Only do the transform if the value won't be split into multiple
+ // registers.
+ LegalizeTypeAction Action = getTypeAction(Context, VT);
+ return Action != TypeExpandInteger && Action != TypeExpandFloat &&
+ Action != TypeSplitVector;
+ }
+
//===--------------------------------------------------------------------===//
// TargetLowering Configuration Methods - These methods should be invoked by
// the derived class constructor to configure this object for the target.
@@ -1452,6 +1498,33 @@ public:
virtual bool isProfitableToHoist(Instruction *I) const { return true; }
+ /// Return true if the extension represented by \p I is free.
+ /// Unlikely the is[Z|FP]ExtFree family which is based on types,
+ /// this method can use the context provided by \p I to decide
+ /// whether or not \p I is free.
+ /// This method extends the behavior of the is[Z|FP]ExtFree family.
+ /// In other words, if is[Z|FP]Free returns true, then this method
+ /// returns true as well. The converse is not true.
+ /// The target can perform the adequate checks by overriding isExtFreeImpl.
+ /// \pre \p I must be a sign, zero, or fp extension.
+ bool isExtFree(const Instruction *I) const {
+ switch (I->getOpcode()) {
+ case Instruction::FPExt:
+ if (isFPExtFree(EVT::getEVT(I->getType())))
+ return true;
+ break;
+ case Instruction::ZExt:
+ if (isZExtFree(I->getOperand(0)->getType(), I->getType()))
+ return true;
+ break;
+ case Instruction::SExt:
+ break;
+ default:
+ llvm_unreachable("Instruction is not an extension");
+ }
+ return isExtFreeImpl(I);
+ }
+
/// Return true if any actual instruction that defines a value of type Ty1
/// implicitly zero-extends the value to Ty2 in the result register.
///
@@ -1607,7 +1680,6 @@ public:
private:
const TargetMachine &TM;
- const DataLayout *DL;
/// True if this is a little endian target.
bool IsLittleEndian;
@@ -1816,6 +1888,11 @@ private:
CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL];
protected:
+ /// Return true if the extension represented by \p I is free.
+ /// \pre \p I is a sign, zero, or fp extension and
+ /// is[Z|FP]ExtFree of the related types is not true.
+ virtual bool isExtFreeImpl(const Instruction *I) const { return false; }
+
/// \brief Specify maximum number of store instructions per memset call.
///
/// When lowering \@llvm.memset this field specifies the maximum number of
@@ -1953,6 +2030,7 @@ public:
ISD::CondCode &CCCode, SDLoc DL) const;
/// Returns a pair of (return value, chain).
+ /// It is an error to pass RTLIB::UNKNOWN_LIBCALL as \p LC.
std::pair<SDValue, SDValue> makeLibCall(SelectionDAG &DAG, RTLIB::Libcall LC,
EVT RetVT, const SDValue *Ops,
unsigned NumOps, bool isSigned,
@@ -2562,6 +2640,15 @@ public:
getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
const std::string &Constraint, MVT VT) const;
+ virtual unsigned
+ getInlineAsmMemConstraint(const std::string &ConstraintCode) const {
+ if (ConstraintCode == "i")
+ return InlineAsm::Constraint_i;
+ else if (ConstraintCode == "m")
+ return InlineAsm::Constraint_m;
+ return InlineAsm::Constraint_Unknown;
+ }
+
/// 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.
@@ -2664,6 +2751,8 @@ public:
/// 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.
+ /// As long as the returned basic block is different (i.e., we created a new
+ /// one), the custom inserter is free to modify the rest of \p MBB.
virtual MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB) const;
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 57c2606..62ae237 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/include/llvm/Target/TargetLoweringObjectFile.h
@@ -29,26 +29,29 @@ namespace llvm {
class MCSymbol;
class MCSymbolRefExpr;
class MCStreamer;
+ class MCValue;
class ConstantExpr;
class GlobalValue;
class TargetMachine;
class TargetLoweringObjectFile : public MCObjectFileInfo {
MCContext *Ctx;
- const DataLayout *DL;
TargetLoweringObjectFile(
const TargetLoweringObjectFile&) = delete;
void operator=(const TargetLoweringObjectFile&) = delete;
protected:
+ const DataLayout *DL;
bool SupportIndirectSymViaGOTPCRel;
+ bool SupportGOTPCRelWithOffset;
public:
MCContext &getContext() const { return *Ctx; }
TargetLoweringObjectFile() : MCObjectFileInfo(), Ctx(nullptr), DL(nullptr),
- SupportIndirectSymViaGOTPCRel(false) {}
+ SupportIndirectSymViaGOTPCRel(false),
+ SupportGOTPCRelWithOffset(true) {}
virtual ~TargetLoweringObjectFile();
@@ -98,6 +101,11 @@ public:
return SectionForGlobal(GV, getKindForGlobal(GV, TM), Mang, TM);
}
+ virtual void getNameWithPrefix(SmallVectorImpl<char> &OutName,
+ const GlobalValue *GV,
+ bool CannotUsePrivateLabel, Mangler &Mang,
+ const TargetMachine &TM) const;
+
virtual const MCSection *
getSectionForJumpTable(const Function &F, Mangler &Mang,
const TargetMachine &TM) const;
@@ -168,9 +176,18 @@ public:
return SupportIndirectSymViaGOTPCRel;
}
+ /// \brief Target GOT "PC"-relative relocation supports encoding an additional
+ /// binary expression with an offset?
+ bool supportGOTPCRelWithOffset() const {
+ return SupportGOTPCRelWithOffset;
+ }
+
/// \brief Get the target specific PC relative GOT entry relocation
virtual const MCExpr *getIndirectSymViaGOTPCRel(const MCSymbol *Sym,
- int64_t Offset) const {
+ const MCValue &MV,
+ int64_t Offset,
+ MachineModuleInfo *MMI,
+ MCStreamer &Streamer) const {
return nullptr;
}
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index cdf643d..87aba9f 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -15,6 +15,7 @@
#define LLVM_TARGET_TARGETMACHINE_H
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/Pass.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Target/TargetOptions.h"
@@ -29,6 +30,9 @@ class Mangler;
class MCAsmInfo;
class MCCodeGenInfo;
class MCContext;
+class MCInstrInfo;
+class MCRegisterInfo;
+class MCSubtargetInfo;
class MCSymbol;
class Target;
class DataLayout;
@@ -62,12 +66,16 @@ class TargetMachine {
TargetMachine(const TargetMachine &) = delete;
void operator=(const TargetMachine &) = delete;
protected: // Can only create subclasses.
- TargetMachine(const Target &T, StringRef TargetTriple,
- StringRef CPU, StringRef FS, const TargetOptions &Options);
+ TargetMachine(const Target &T, StringRef DataLayoutString,
+ StringRef TargetTriple, StringRef CPU, StringRef FS,
+ const TargetOptions &Options);
/// TheTarget - The Target that this machine was created for.
const Target &TheTarget;
+ /// DataLayout - For ABI type size and alignment.
+ const DataLayout DL;
+
/// TargetTriple, TargetCPU, TargetFS - Triple string, CPU name, and target
/// feature strings the TargetMachine instance is created with.
std::string TargetTriple;
@@ -81,6 +89,9 @@ protected: // Can only create subclasses.
/// AsmInfo - Contains target specific asm information.
///
const MCAsmInfo *AsmInfo;
+ const MCRegisterInfo *MRI;
+ const MCInstrInfo *MII;
+ const MCSubtargetInfo *STI;
unsigned RequireStructuredCFG : 1;
@@ -97,11 +108,8 @@ public:
/// getSubtargetImpl - virtual method implemented by subclasses that returns
/// a reference to that target's TargetSubtargetInfo-derived member variable.
- virtual const TargetSubtargetInfo *getSubtargetImpl() const {
- return nullptr;
- }
virtual const TargetSubtargetInfo *getSubtargetImpl(const Function &) const {
- return getSubtargetImpl();
+ return nullptr;
}
virtual TargetLoweringObjectFile *getObjFileLowering() const {
return nullptr;
@@ -110,18 +118,13 @@ public:
/// getSubtarget - This method returns a pointer to the specified type of
/// TargetSubtargetInfo. In debug builds, it verifies that the object being
/// returned is of the correct type.
- template<typename STC> const STC &getSubtarget() const {
- return *static_cast<const STC*>(getSubtargetImpl());
- }
- template <typename STC> const STC &getSubtarget(const Function &) const {
- return *static_cast<const STC*>(getSubtargetImpl());
+ template <typename STC> const STC &getSubtarget(const Function &F) const {
+ return *static_cast<const STC*>(getSubtargetImpl(F));
}
/// getDataLayout - This method returns a pointer to the DataLayout for
/// the target. It should be unchanging for every subtarget.
- virtual const DataLayout *getDataLayout() const {
- return nullptr;
- }
+ const DataLayout *getDataLayout() const { return &DL; }
/// \brief Reset the target options based on the function's attributes.
// FIXME: Remove TargetOptions that affect per-function code generation
@@ -131,6 +134,9 @@ public:
/// getMCAsmInfo - Return target specific asm information.
///
const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; }
+ const MCRegisterInfo *getMCRegisterInfo() const { return MRI; }
+ const MCInstrInfo *getMCInstrInfo() const { return MII; }
+ const MCSubtargetInfo *getMCSubtargetInfo() const { return STI; }
/// getIntrinsicInfo - If intrinsic information is available, return it. If
/// not, return null.
@@ -236,9 +242,9 @@ public:
///
class LLVMTargetMachine : public TargetMachine {
protected: // Can only create subclasses.
- LLVMTargetMachine(const Target &T, StringRef TargetTriple,
- StringRef CPU, StringRef FS, TargetOptions Options,
- Reloc::Model RM, CodeModel::Model CM,
+ LLVMTargetMachine(const Target &T, StringRef DataLayoutString,
+ StringRef TargetTriple, StringRef CPU, StringRef FS,
+ TargetOptions Options, Reloc::Model RM, CodeModel::Model CM,
CodeGenOpt::Level OL);
void initAsmInfo();
diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h
index fc94a84..4184052 100644
--- a/include/llvm/Target/TargetRegisterInfo.h
+++ b/include/llvm/Target/TargetRegisterInfo.h
@@ -46,6 +46,8 @@ public:
const uint32_t *SubClassMask;
const uint16_t *SuperRegIndices;
const unsigned LaneMask;
+ /// Whether the class supports two (or more) disjunct subregister indices.
+ const bool HasDisjunctSubRegs;
const sc_iterator SuperClasses;
ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
@@ -357,13 +359,13 @@ public:
///
/// then:
///
- /// getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B) != 0
+ /// (getSubRegIndexLaneMask(A) & getSubRegIndexLaneMask(B)) != 0
///
/// The converse is not necessarily true. If two lane masks have a common
/// bit, the corresponding sub-registers may not overlap, but it can be
/// assumed that they usually will.
+ /// SubIdx == 0 is allowed, it has the lane mask ~0u.
unsigned getSubRegIndexLaneMask(unsigned SubIdx) const {
- // SubIdx == 0 is allowed, it has the lane mask ~0u.
assert(SubIdx < getNumSubRegIndices() && "This is not a subregister index");
return SubRegIndexLaneMasks[SubIdx];
}
@@ -425,10 +427,10 @@ public:
/// closest to the incoming stack pointer if stack grows down, and vice versa.
///
virtual const MCPhysReg*
- getCalleeSavedRegs(const MachineFunction *MF = nullptr) const = 0;
+ getCalleeSavedRegs(const MachineFunction *MF) const = 0;
/// getCallPreservedMask - Return a mask of call-preserved registers for the
- /// given calling convention on the current sub-target. The mask should
+ /// given calling convention on the current function. The mask should
/// include all call-preserved aliases. This is used by the register
/// allocator to determine which registers can be live across a call.
///
@@ -445,7 +447,8 @@ public:
/// instructions should use implicit-def operands to indicate call clobbered
/// registers.
///
- virtual const uint32_t *getCallPreservedMask(CallingConv::ID) const {
+ virtual const uint32_t *getCallPreservedMask(const MachineFunction &MF,
+ CallingConv::ID) const {
// The default mask clobbers everything. All targets should override.
return nullptr;
}
@@ -622,8 +625,9 @@ public:
/// legal to use in the current sub-target and has the same spill size.
/// The returned register class can be used to create virtual registers which
/// means that all its registers can be copied and spilled.
- virtual const TargetRegisterClass*
- getLargestLegalSuperClass(const TargetRegisterClass *RC) const {
+ virtual const TargetRegisterClass *
+ getLargestLegalSuperClass(const TargetRegisterClass *RC,
+ const MachineFunction &) const {
/// The default implementation is very conservative and doesn't allow the
/// register allocator to inflate register classes.
return RC;
@@ -655,7 +659,8 @@ public:
/// Get the register unit pressure limit for this dimension.
/// This limit must be adjusted dynamically for reserved registers.
- virtual unsigned getRegPressureSetLimit(unsigned Idx) const = 0;
+ virtual unsigned getRegPressureSetLimit(const MachineFunction &MF,
+ unsigned Idx) const = 0;
/// Get the dimensions of register pressure impacted by this register class.
/// Returns a -1 terminated array of pressure set IDs.
@@ -686,14 +691,6 @@ public:
const MachineFunction &MF,
const VirtRegMap *VRM = nullptr) const;
- /// avoidWriteAfterWrite - Return true if the register allocator should avoid
- /// writing a register from RC in two consecutive instructions.
- /// This can avoid pipeline stalls on certain architectures.
- /// It does cause increased register pressure, though.
- virtual bool avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
- return false;
- }
-
/// updateRegAllocHint - A callback to allow target a chance to update
/// register allocation hints when a register is "changed" (e.g. coalesced)
/// to another register. e.g. On ARM, some virtual registers should target
@@ -802,9 +799,9 @@ public:
llvm_unreachable("resolveFrameIndex does not exist on this target");
}
- /// isFrameOffsetLegal - Determine whether a given offset immediate is
- /// encodable to resolve a frame index.
- virtual bool isFrameOffsetLegal(const MachineInstr *MI,
+ /// isFrameOffsetLegal - Determine whether a given base register plus offset
+ /// immediate is encodable to resolve a frame index.
+ virtual bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg,
int64_t Offset) const {
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
diff --git a/include/llvm/Target/TargetSelectionDAG.td b/include/llvm/Target/TargetSelectionDAG.td
index d297162..5388962 100644
--- a/include/llvm/Target/TargetSelectionDAG.td
+++ b/include/llvm/Target/TargetSelectionDAG.td
@@ -68,6 +68,18 @@ class SDTCisSubVecOfVec<int ThisOp, int OtherOp>
int OtherOpNum = OtherOp;
}
+// SDTCVecEltisVT - The specified operand is vector type with element type
+// of VT.
+class SDTCVecEltisVT<int OpNum, ValueType vt> : SDTypeConstraint<OpNum> {
+ ValueType VT = vt;
+}
+
+// SDTCisSameNumEltsAs - The two specified operands have identical number
+// of elements.
+class SDTCisSameNumEltsAs<int OpNum, int OtherOp> : SDTypeConstraint<OpNum> {
+ int OtherOperandNum = OtherOp;
+}
+
//===----------------------------------------------------------------------===//
// Selection DAG Type Profile definitions.
//
@@ -196,14 +208,6 @@ def SDTMaskedLoad: SDTypeProfile<1, 3, [ // masked load
SDTCisVec<0>, SDTCisPtrTy<1>, SDTCisVec<2>, SDTCisSameAs<0, 3>
]>;
-def SDTMaskedGather: SDTypeProfile<1, 3, [ // masked gather
- SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisVec<2>
-]>;
-
-def SDTMaskedScatter: SDTypeProfile<1, 3, [ // masked scatter
- SDTCisVec<0>, SDTCisVec<1>, SDTCisSameAs<0, 2>
-]>;
-
def SDTVecShuffle : SDTypeProfile<1, 2, [
SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>
]>;
@@ -476,10 +480,6 @@ def masked_store : SDNode<"ISD::MSTORE", SDTMaskedStore,
[SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
def masked_load : SDNode<"ISD::MLOAD", SDTMaskedLoad,
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
-def masked_scatter : SDNode<"ISD::MSCATTER", SDTMaskedScatter,
- [SDNPHasChain, SDNPMayStore, SDNPMemOperand]>;
-def masked_gather : SDNode<"ISD::MGATHER", SDTMaskedGather,
- [SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
// Do not use ld, st directly. Use load, extload, sextload, zextload, store,
// and truncst (see below).
diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h
index 83ab4ec..bb5409b6 100644
--- a/include/llvm/Target/TargetSubtargetInfo.h
+++ b/include/llvm/Target/TargetSubtargetInfo.h
@@ -94,16 +94,24 @@ public:
return 0;
}
- /// \brief Temporary API to test migration to MI scheduler.
- bool useMachineScheduler() const;
-
/// \brief True if the subtarget should run MachineScheduler after aggressive
/// coalescing.
///
/// This currently replaces the SelectionDAG scheduler with the "source" order
- /// scheduler. It does not yet disable the postRA scheduler.
+ /// scheduler (though see below for an option to turn this off and use the
+ /// TargetLowering preference). It does not yet disable the postRA scheduler.
virtual bool enableMachineScheduler() const;
+ /// \brief True if the machine scheduler should disable the TLI preference
+ /// for preRA scheduling with the source level scheduler.
+ virtual bool enableMachineSchedDefaultSched() const { return true; }
+
+ /// \brief True if the subtarget should enable joining global copies.
+ ///
+ /// By default this is enabled if the machine scheduler is enabled, but
+ /// can be overridden.
+ virtual bool enableJoinGlobalCopies() const;
+
/// \brief True if the subtarget should run PostMachineScheduler.
///
/// This only takes effect if the target has configured the
diff --git a/include/llvm/Transforms/IPO/LowerBitSets.h b/include/llvm/Transforms/IPO/LowerBitSets.h
index 0f60617..55d7d84 100644
--- a/include/llvm/Transforms/IPO/LowerBitSets.h
+++ b/include/llvm/Transforms/IPO/LowerBitSets.h
@@ -30,8 +30,8 @@ class GlobalVariable;
class Value;
struct BitSetInfo {
- // The actual bitset.
- std::vector<uint8_t> Bits;
+ // The indices of the set bits in the bitset.
+ std::set<uint64_t> Bits;
// The byte offset into the combined global represented by the bitset.
uint64_t ByteOffset;
@@ -45,26 +45,18 @@ struct BitSetInfo {
unsigned AlignLog2;
bool isSingleOffset() const {
- return Bits.size() == 1 && Bits[0] == 1;
+ return Bits.size() == 1;
}
bool isAllOnes() const {
- for (unsigned I = 0; I != Bits.size() - 1; ++I)
- if (Bits[I] != 0xFF)
- return false;
-
- if (BitSize % 8 == 0)
- return Bits[Bits.size() - 1] == 0xFF;
-
- return Bits[Bits.size() - 1] == (1 << (BitSize % 8)) - 1;
+ return Bits.size() == BitSize;
}
bool containsGlobalOffset(uint64_t Offset) const;
- bool containsValue(const DataLayout *DL,
+ bool containsValue(const DataLayout &DL,
const DenseMap<GlobalVariable *, uint64_t> &GlobalLayout,
Value *V, uint64_t COffset = 0) const;
-
};
struct BitSetBuilder {
@@ -148,6 +140,59 @@ struct GlobalLayoutBuilder {
void addFragment(const std::set<uint64_t> &F);
};
+/// This class is used to build a byte array containing overlapping bit sets. By
+/// loading from indexed offsets into the byte array and applying a mask, a
+/// program can test bits from the bit set with a relatively short instruction
+/// sequence. For example, suppose we have 15 bit sets to lay out:
+///
+/// A (16 bits), B (15 bits), C (14 bits), D (13 bits), E (12 bits),
+/// F (11 bits), G (10 bits), H (9 bits), I (7 bits), J (6 bits), K (5 bits),
+/// L (4 bits), M (3 bits), N (2 bits), O (1 bit)
+///
+/// These bits can be laid out in a 16-byte array like this:
+///
+/// Byte Offset
+/// 0123456789ABCDEF
+/// Bit
+/// 7 HHHHHHHHHIIIIIII
+/// 6 GGGGGGGGGGJJJJJJ
+/// 5 FFFFFFFFFFFKKKKK
+/// 4 EEEEEEEEEEEELLLL
+/// 3 DDDDDDDDDDDDDMMM
+/// 2 CCCCCCCCCCCCCCNN
+/// 1 BBBBBBBBBBBBBBBO
+/// 0 AAAAAAAAAAAAAAAA
+///
+/// For example, to test bit X of A, we evaluate ((bits[X] & 1) != 0), or to
+/// test bit X of I, we evaluate ((bits[9 + X] & 0x80) != 0). This can be done
+/// in 1-2 machine instructions on x86, or 4-6 instructions on ARM.
+///
+/// This is a byte array, rather than (say) a 2-byte array or a 4-byte array,
+/// because for one thing it gives us better packing (the more bins there are,
+/// the less evenly they will be filled), and for another, the instruction
+/// sequences can be slightly shorter, both on x86 and ARM.
+struct ByteArrayBuilder {
+ /// The byte array built so far.
+ std::vector<uint8_t> Bytes;
+
+ enum { BitsPerByte = 8 };
+
+ /// The number of bytes allocated so far for each of the bits.
+ uint64_t BitAllocs[BitsPerByte];
+
+ ByteArrayBuilder() {
+ memset(BitAllocs, 0, sizeof(BitAllocs));
+ }
+
+ /// Allocate BitSize bits in the byte array where Bits contains the bits to
+ /// set. AllocByteOffset is set to the offset within the byte array and
+ /// AllocMask is set to the bitmask for those bits. This uses the LPT (Longest
+ /// Processing Time) multiprocessor scheduling algorithm to lay out the bits
+ /// efficiently; the pass allocates bit sets in decreasing size order.
+ void allocate(const std::set<uint64_t> &Bits, uint64_t BitSize,
+ uint64_t &AllocByteOffset, uint8_t &AllocMask);
+};
+
} // namespace llvm
#endif
diff --git a/include/llvm/Transforms/IPO/PassManagerBuilder.h b/include/llvm/Transforms/IPO/PassManagerBuilder.h
index 65f4712..5d574ae 100644
--- a/include/llvm/Transforms/IPO/PassManagerBuilder.h
+++ b/include/llvm/Transforms/IPO/PassManagerBuilder.h
@@ -120,7 +120,6 @@ public:
bool DisableGVNLoadPRE;
bool VerifyInput;
bool VerifyOutput;
- bool StripDebug;
bool MergeFunctions;
private:
@@ -141,6 +140,7 @@ private:
legacy::PassManagerBase &PM) const;
void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
+ void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
public:
/// populateFunctionPassManager - This fills in the function pass manager,
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
index 8fac6ca..a147793 100644
--- a/include/llvm/Transforms/Instrumentation.h
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -60,6 +60,10 @@ struct GCOVOptions {
// Emit the name of the function in the .gcda files. This is redundant, as
// the function identifier can be used to find the name from the .gcno file.
bool FunctionNamesInData;
+
+ // Emit the exit block immediately after the start block, rather than after
+ // all of the function body's blocks.
+ bool ExitBlockBeforeBody;
};
ModulePass *createGCOVProfilerPass(const GCOVOptions &Options =
GCOVOptions::getDefault());
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index 558b81e..2d754d0 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -140,6 +140,13 @@ Pass *createLICMPass();
//===----------------------------------------------------------------------===//
//
+// LoopInterchange - This pass interchanges loops to provide a more
+// cache-friendly memory access patterns.
+//
+Pass *createLoopInterchangePass();
+
+//===----------------------------------------------------------------------===//
+//
// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
// a loop's canonical induction variable as one of their indices.
//
@@ -422,7 +429,6 @@ BasicBlockPass *createLoadCombinePass();
FunctionPass *createStraightLineStrengthReducePass();
-
//===----------------------------------------------------------------------===//
//
// PlaceSafepoints - Rewrite any IR calls to gc.statepoints and insert any
diff --git a/include/llvm/Transforms/Utils/BuildLibCalls.h b/include/llvm/Transforms/Utils/BuildLibCalls.h
index 6387c16..879f295 100644
--- a/include/llvm/Transforms/Utils/BuildLibCalls.h
+++ b/include/llvm/Transforms/Utils/BuildLibCalls.h
@@ -28,52 +28,50 @@ namespace llvm {
/// EmitStrLen - Emit a call to the strlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, and the
/// return value has 'intptr_t' type.
- Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// EmitStrNLen - Emit a call to the strnlen function to the builder, for the
/// specified pointer. Ptr is required to be some pointer type, MaxLen must
/// be of size_t type, and the return value has 'intptr_t' type.
Value *EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitStrChr - Emit a call to the strchr function to the builder, for the
/// specified pointer and character. Ptr is required to be some pointer type,
/// and the return value has 'i8*' type.
- Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
const TargetLibraryInfo *TLI);
/// EmitStrNCmp - Emit a call to the strncmp function to the builder.
Value *EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the
/// specified pointer arguments.
Value *EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI,
- StringRef Name = "strcpy");
+ const TargetLibraryInfo *TLI, StringRef Name = "strcpy");
/// EmitStrNCpy - Emit a call to the strncpy function to the builder, for the
/// specified pointer arguments and length.
Value *EmitStrNCpy(Value *Dst, Value *Src, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI,
- StringRef Name = "strncpy");
+ const TargetLibraryInfo *TLI, StringRef Name = "strncpy");
/// EmitMemCpyChk - Emit a call to the __memcpy_chk function to the builder.
/// This expects that the Len and ObjSize have type 'intptr_t' and Dst/Src
/// are pointers.
Value *EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
- IRBuilder<> &B, const DataLayout *TD,
+ IRBuilder<> &B, const DataLayout &DL,
const TargetLibraryInfo *TLI);
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitMemCmp - Emit a call to the memcmp function.
Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name'
/// (e.g. 'floor'). This function is known to take a single of type matching
@@ -93,28 +91,26 @@ namespace llvm {
/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
/// is an integer.
- Value *EmitPutChar(Value *Char, IRBuilder<> &B, const DataLayout *TD,
- const TargetLibraryInfo *TLI);
+ Value *EmitPutChar(Value *Char, IRBuilder<> &B, const TargetLibraryInfo *TLI);
/// EmitPutS - Emit a call to the puts function. This assumes that Str is
/// some pointer.
- Value *EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
- const TargetLibraryInfo *TLI);
+ Value *EmitPutS(Value *Str, IRBuilder<> &B, const TargetLibraryInfo *TLI);
/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
/// an i32, and File is a pointer to FILE.
Value *EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const TargetLibraryInfo *TLI);
/// EmitFPutS - Emit a call to the puts function. Str is required to be a
/// pointer and File is a pointer to FILE.
- Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, const DataLayout *TD,
+ Value *EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
const TargetLibraryInfo *TLI);
/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Value *EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B,
- const DataLayout *TD, const TargetLibraryInfo *TLI);
+ const DataLayout &DL, const TargetLibraryInfo *TLI);
}
#endif
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
index d1563ef..cb187ec 100644
--- a/include/llvm/Transforms/Utils/Cloning.h
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -144,7 +144,9 @@ public:
///< Skip this instruction but continue cloning the current basic block.
SkipInstruction,
///< Skip this instruction and stop cloning the current basic block.
- StopCloningBB
+ StopCloningBB,
+ ///< Don't clone the terminator but clone the current block's successors.
+ CloneSuccessors
};
virtual ~CloningDirector() {}
@@ -164,7 +166,6 @@ void CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
- const DataLayout *DL = nullptr,
CloningDirector *Director = nullptr);
@@ -184,7 +185,6 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
SmallVectorImpl<ReturnInst*> &Returns,
const char *NameSuffix = "",
ClonedCodeInfo *CodeInfo = nullptr,
- const DataLayout *DL = nullptr,
Instruction *TheCall = nullptr);
/// InlineFunctionInfo - This class captures the data input to the
@@ -192,15 +192,13 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
class InlineFunctionInfo {
public:
explicit InlineFunctionInfo(CallGraph *cg = nullptr,
- const DataLayout *DL = nullptr,
AliasAnalysis *AA = nullptr,
AssumptionCacheTracker *ACT = nullptr)
- : CG(cg), DL(DL), AA(AA), ACT(ACT) {}
+ : CG(cg), AA(AA), ACT(ACT) {}
/// CG - If non-null, InlineFunction will update the callgraph to reflect the
/// changes it makes.
CallGraph *CG;
- const DataLayout *DL;
AliasAnalysis *AA;
AssumptionCacheTracker *ACT;
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
index 463ab96..e89169c 100644
--- a/include/llvm/Transforms/Utils/Local.h
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -88,7 +88,7 @@ bool RecursivelyDeleteDeadPHINode(PHINode *PN,
///
/// This returns true if it changed the code, note that it can delete
/// instructions in other blocks as well in this block.
-bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
+bool SimplifyInstructionsInBlock(BasicBlock *BB,
const TargetLibraryInfo *TLI = nullptr);
//===----------------------------------------------------------------------===//
@@ -106,8 +106,7 @@ bool SimplifyInstructionsInBlock(BasicBlock *BB, const DataLayout *TD = nullptr,
///
/// .. and delete the predecessor corresponding to the '1', this will attempt to
/// recursively fold the 'and' to 0.
-void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred,
- DataLayout *TD = nullptr);
+void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred);
/// MergeBasicBlockIntoOnlyPred - BB is a block with one predecessor and its
/// predecessor is known to have one successor (BB!). Eliminate the edge
@@ -137,8 +136,7 @@ bool EliminateDuplicatePHINodes(BasicBlock *BB);
/// the basic block that was pointed to.
///
bool SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, const DataLayout *TD = nullptr,
- AssumptionCache *AC = nullptr);
+ unsigned BonusInstThreshold, AssumptionCache *AC = nullptr);
/// FlatternCFG - This function is used to flatten a CFG. For
/// example, it uses parallel-and and parallel-or mode to collapse
@@ -150,8 +148,7 @@ bool FlattenCFG(BasicBlock *BB, AliasAnalysis *AA = nullptr);
/// and if a predecessor branches to us and one of our successors, fold the
/// setcc into the predecessor and use logical operations to pick the right
/// destination.
-bool FoldBranchToCommonDest(BranchInst *BI, const DataLayout *DL = nullptr,
- unsigned BonusInstThreshold = 1);
+bool FoldBranchToCommonDest(BranchInst *BI, unsigned BonusInstThreshold = 1);
/// DemoteRegToStack - This function takes a virtual register computed by an
/// Instruction and replaces it with a slot in the stack frame, allocated via
@@ -173,18 +170,17 @@ AllocaInst *DemotePHIToStack(PHINode *P, Instruction *AllocaPoint = nullptr);
/// and it is more than the alignment of the ultimate object, see if we can
/// increase the alignment of the ultimate object, making this check succeed.
unsigned getOrEnforceKnownAlignment(Value *V, unsigned PrefAlign,
- const DataLayout *TD = nullptr,
- AssumptionCache *AC = nullptr,
+ const DataLayout &DL,
const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
const DominatorTree *DT = nullptr);
/// getKnownAlignment - Try to infer an alignment for the specified pointer.
-static inline unsigned getKnownAlignment(Value *V,
- const DataLayout *TD = nullptr,
- AssumptionCache *AC = nullptr,
+static inline unsigned getKnownAlignment(Value *V, const DataLayout &DL,
const Instruction *CxtI = nullptr,
+ AssumptionCache *AC = nullptr,
const DominatorTree *DT = nullptr) {
- return getOrEnforceKnownAlignment(V, 0, TD, AC, CxtI, DT);
+ return getOrEnforceKnownAlignment(V, 0, DL, CxtI, AC, DT);
}
/// EmitGEPOffset - Given a getelementptr instruction/constantexpr, emit the
@@ -192,11 +188,11 @@ static inline unsigned getKnownAlignment(Value *V,
/// in the base pointer). Return the result as a signed integer of intptr size.
/// When NoAssumptions is true, no assumptions about index computation not
/// overflowing is made.
-template<typename IRBuilderTy>
-Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
+template <typename IRBuilderTy>
+Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &DL, User *GEP,
bool NoAssumptions = false) {
GEPOperator *GEPOp = cast<GEPOperator>(GEP);
- Type *IntPtrTy = TD.getIntPtrType(GEP->getType());
+ Type *IntPtrTy = DL.getIntPtrType(GEP->getType());
Value *Result = Constant::getNullValue(IntPtrTy);
// If the GEP is inbounds, we know that none of the addressing operations will
@@ -211,7 +207,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
++i, ++GTI) {
Value *Op = *i;
- uint64_t Size = TD.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
+ uint64_t Size = DL.getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;
if (Constant *OpC = dyn_cast<Constant>(Op)) {
if (OpC->isZeroValue())
continue;
@@ -222,7 +218,7 @@ Value *EmitGEPOffset(IRBuilderTy *Builder, const DataLayout &TD, User *GEP,
OpC = OpC->getSplatValue();
uint64_t OpValue = cast<ConstantInt>(OpC)->getZExtValue();
- Size = TD.getStructLayout(STy)->getElementOffset(OpValue);
+ Size = DL.getStructLayout(STy)->getElementOffset(OpValue);
if (Size)
Result = Builder->CreateAdd(Result, ConstantInt::get(IntPtrTy, Size),
diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h
index bb80f20..2eb2555 100644
--- a/include/llvm/Transforms/Utils/LoopUtils.h
+++ b/include/llvm/Transforms/Utils/LoopUtils.h
@@ -52,7 +52,6 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P);
/// passed into it.
bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP,
AliasAnalysis *AA = nullptr, ScalarEvolution *SE = nullptr,
- const DataLayout *DL = nullptr,
AssumptionCache *AC = nullptr);
/// \brief Put loop into LCSSA form.
@@ -85,13 +84,13 @@ bool formLCSSARecursively(Loop &L, DominatorTree &DT, LoopInfo *LI,
/// dominated by the specified block, and that are in the current loop) in
/// reverse depth first order w.r.t the DominatorTree. This allows us to visit
/// uses before definitions, allowing us to sink a loop body in one pass without
-/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
-/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
-/// instructions of the loop and loop safety information as arguments.
-/// It returns changed status.
+/// iteration. Takes DomTreeNode, AliasAnalysis, LoopInfo, DominatorTree,
+/// DataLayout, TargetLibraryInfo, Loop, AliasSet information for all
+/// instructions of the loop and loop safety information as arguments.
+/// It returns changed status.
bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
- const DataLayout *, TargetLibraryInfo *, Loop *,
- AliasSetTracker *, LICMSafetyInfo *);
+ TargetLibraryInfo *, Loop *, AliasSetTracker *,
+ LICMSafetyInfo *);
/// \brief Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in depth
@@ -101,8 +100,8 @@ bool sinkRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
/// TargetLibraryInfo, Loop, AliasSet information for all instructions of the
/// loop and loop safety information as arguments. It returns changed status.
bool hoistRegion(DomTreeNode *, AliasAnalysis *, LoopInfo *, DominatorTree *,
- const DataLayout *, TargetLibraryInfo *, Loop *,
- AliasSetTracker *, LICMSafetyInfo *);
+ TargetLibraryInfo *, Loop *, AliasSetTracker *,
+ LICMSafetyInfo *);
/// \brief Try to promote memory values to scalars by sinking stores out of
/// the loop and moving loads to before the loop. We do this by looping over
diff --git a/include/llvm/Transforms/Utils/SimplifyLibCalls.h b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
index 08358e1..4115960 100644
--- a/include/llvm/Transforms/Utils/SimplifyLibCalls.h
+++ b/include/llvm/Transforms/Utils/SimplifyLibCalls.h
@@ -15,6 +15,7 @@
#ifndef LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
#define LLVM_TRANSFORMS_UTILS_SIMPLIFYLIBCALLS_H
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/IRBuilder.h"
@@ -36,12 +37,11 @@ class Function;
/// is unknown) by passing true for OnlyLowerUnknownSize.
class FortifiedLibCallSimplifier {
private:
- const DataLayout *DL;
const TargetLibraryInfo *TLI;
bool OnlyLowerUnknownSize;
public:
- FortifiedLibCallSimplifier(const DataLayout *DL, const TargetLibraryInfo *TLI,
+ FortifiedLibCallSimplifier(const TargetLibraryInfo *TLI,
bool OnlyLowerUnknownSize = false);
/// \brief Take the given call instruction and return a more
@@ -71,7 +71,7 @@ private:
class LibCallSimplifier {
private:
FortifiedLibCallSimplifier FortifiedSimplifier;
- const DataLayout *DL;
+ const DataLayout &DL;
const TargetLibraryInfo *TLI;
bool UnsafeFPShrink;
function_ref<void(Instruction *, Value *)> Replacer;
@@ -86,7 +86,7 @@ private:
void replaceAllUsesWith(Instruction *I, Value *With);
public:
- LibCallSimplifier(const DataLayout *TD, const TargetLibraryInfo *TLI,
+ LibCallSimplifier(const DataLayout &DL, const TargetLibraryInfo *TLI,
function_ref<void(Instruction *, Value *)> Replacer =
&replaceAllUsesWithDefault);
@@ -116,6 +116,7 @@ private:
Value *optimizeStrSpn(CallInst *CI, IRBuilder<> &B);
Value *optimizeStrCSpn(CallInst *CI, IRBuilder<> &B);
Value *optimizeStrStr(CallInst *CI, IRBuilder<> &B);
+ Value *optimizeMemChr(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCmp(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
diff --git a/include/llvm/module.modulemap b/include/llvm/module.modulemap
index 0f9c22e..dc6e136 100644
--- a/include/llvm/module.modulemap
+++ b/include/llvm/module.modulemap
@@ -2,7 +2,12 @@ module LLVM_Analysis {
requires cplusplus
umbrella "Analysis"
module * { export * }
+
+ // FIXME: Why is this excluded?
exclude header "Analysis/BlockFrequencyInfoImpl.h"
+
+ // This is intended for (repeated) textual inclusion.
+ textual header "Analysis/TargetLibraryInfo.def"
}
module LLVM_AsmParser { requires cplusplus umbrella "AsmParser" module * { export * } }