aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
committerDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
commitf17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc (patch)
treeebb79ea1ee5e3bc1fdf38541a811a8b804f0679a /include
downloadexternal_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.zip
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.gz
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.bz2
It's not necessary to do rounding for alloca operations when the requested
alignment is equal to the stack alignment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40004 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm-c/LinkTimeOptimizer.h58
-rw-r--r--include/llvm/ADT/APInt.h1228
-rw-r--r--include/llvm/ADT/APSInt.h110
-rw-r--r--include/llvm/ADT/BitVector.h369
-rw-r--r--include/llvm/ADT/DenseMap.h355
-rw-r--r--include/llvm/ADT/DepthFirstIterator.h232
-rw-r--r--include/llvm/ADT/EquivalenceClasses.h279
-rw-r--r--include/llvm/ADT/FoldingSet.h258
-rw-r--r--include/llvm/ADT/GraphTraits.h83
-rw-r--r--include/llvm/ADT/HashExtras.h41
-rw-r--r--include/llvm/ADT/IndexedMap.h75
-rw-r--r--include/llvm/ADT/PostOrderIterator.h230
-rw-r--r--include/llvm/ADT/SCCIterator.h199
-rw-r--r--include/llvm/ADT/STLExtras.h204
-rw-r--r--include/llvm/ADT/SetOperations.h71
-rw-r--r--include/llvm/ADT/SetVector.h168
-rw-r--r--include/llvm/ADT/SmallPtrSet.h250
-rw-r--r--include/llvm/ADT/SmallSet.h112
-rw-r--r--include/llvm/ADT/SmallString.h62
-rw-r--r--include/llvm/ADT/SmallVector.h485
-rw-r--r--include/llvm/ADT/Statistic.h75
-rw-r--r--include/llvm/ADT/StringExtras.h150
-rw-r--r--include/llvm/ADT/StringMap.h346
-rw-r--r--include/llvm/ADT/Tree.h62
-rw-r--r--include/llvm/ADT/UniqueVector.h89
-rw-r--r--include/llvm/ADT/VectorExtras.h41
-rw-r--r--include/llvm/ADT/hash_map.in150
-rw-r--r--include/llvm/ADT/hash_set.in111
-rw-r--r--include/llvm/ADT/ilist586
-rw-r--r--include/llvm/ADT/iterator.in76
-rw-r--r--include/llvm/AbstractTypeUser.h179
-rw-r--r--include/llvm/Analysis/AliasAnalysis.h332
-rw-r--r--include/llvm/Analysis/AliasSetTracker.h392
-rw-r--r--include/llvm/Analysis/CFGPrinter.h24
-rw-r--r--include/llvm/Analysis/CallGraph.h315
-rw-r--r--include/llvm/Analysis/ConstantFolding.h61
-rw-r--r--include/llvm/Analysis/ConstantsScanner.h94
-rw-r--r--include/llvm/Analysis/Dominators.h431
-rw-r--r--include/llvm/Analysis/FindUsedTypes.h67
-rw-r--r--include/llvm/Analysis/Interval.h154
-rw-r--r--include/llvm/Analysis/IntervalIterator.h258
-rw-r--r--include/llvm/Analysis/IntervalPartition.h114
-rw-r--r--include/llvm/Analysis/LoadValueNumbering.h35
-rw-r--r--include/llvm/Analysis/LoopInfo.h363
-rw-r--r--include/llvm/Analysis/LoopPass.h132
-rw-r--r--include/llvm/Analysis/MemoryDependenceAnalysis.h75
-rw-r--r--include/llvm/Analysis/Passes.h117
-rw-r--r--include/llvm/Analysis/PostDominators.h86
-rw-r--r--include/llvm/Analysis/ProfileInfo.h67
-rw-r--r--include/llvm/Analysis/ProfileInfoLoader.h89
-rw-r--r--include/llvm/Analysis/ProfileInfoTypes.h28
-rw-r--r--include/llvm/Analysis/ScalarEvolution.h250
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpander.h153
-rw-r--r--include/llvm/Analysis/ScalarEvolutionExpressions.h580
-rw-r--r--include/llvm/Analysis/Trace.h120
-rw-r--r--include/llvm/Analysis/ValueNumbering.h74
-rw-r--r--include/llvm/Analysis/Verifier.h75
-rw-r--r--include/llvm/Argument.h72
-rw-r--r--include/llvm/Assembly/AsmAnnotationWriter.h53
-rw-r--r--include/llvm/Assembly/Parser.h97
-rw-r--r--include/llvm/Assembly/PrintModulePass.h81
-rw-r--r--include/llvm/Assembly/Writer.h45
-rw-r--r--include/llvm/BasicBlock.h216
-rw-r--r--include/llvm/Bitcode/Archive.h555
-rw-r--r--include/llvm/Bitcode/BitCodes.h179
-rw-r--r--include/llvm/Bitcode/BitstreamReader.h465
-rw-r--r--include/llvm/Bitcode/BitstreamWriter.h398
-rw-r--r--include/llvm/Bitcode/LLVMBitCodes.h195
-rw-r--r--include/llvm/Bitcode/ReaderWriter.h48
-rw-r--r--include/llvm/CallGraphSCCPass.h72
-rw-r--r--include/llvm/CallingConv.h66
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h316
-rw-r--r--include/llvm/CodeGen/CallingConvLower.h202
-rw-r--r--include/llvm/CodeGen/DwarfWriter.h82
-rw-r--r--include/llvm/CodeGen/ELFRelocation.h52
-rw-r--r--include/llvm/CodeGen/FileWriters.h32
-rw-r--r--include/llvm/CodeGen/IntrinsicLowering.h50
-rw-r--r--include/llvm/CodeGen/LinkAllCodegenComponents.h48
-rw-r--r--include/llvm/CodeGen/LiveInterval.h287
-rw-r--r--include/llvm/CodeGen/LiveIntervalAnalysis.h235
-rw-r--r--include/llvm/CodeGen/LiveVariables.h304
-rw-r--r--include/llvm/CodeGen/MachORelocation.h54
-rw-r--r--include/llvm/CodeGen/MachineBasicBlock.h371
-rw-r--r--include/llvm/CodeGen/MachineCodeEmitter.h200
-rw-r--r--include/llvm/CodeGen/MachineConstantPool.h149
-rw-r--r--include/llvm/CodeGen/MachineFrameInfo.h327
-rw-r--r--include/llvm/CodeGen/MachineFunction.h374
-rw-r--r--include/llvm/CodeGen/MachineFunctionPass.h50
-rw-r--r--include/llvm/CodeGen/MachineInstr.h567
-rw-r--r--include/llvm/CodeGen/MachineInstrBuilder.h147
-rw-r--r--include/llvm/CodeGen/MachineJumpTableInfo.h103
-rw-r--r--include/llvm/CodeGen/MachineLocation.h106
-rw-r--r--include/llvm/CodeGen/MachineModuleInfo.h1280
-rw-r--r--include/llvm/CodeGen/MachinePassRegistry.h156
-rw-r--r--include/llvm/CodeGen/MachineRelocation.h298
-rw-r--r--include/llvm/CodeGen/Passes.h120
-rw-r--r--include/llvm/CodeGen/RegAllocRegistry.h64
-rw-r--r--include/llvm/CodeGen/RegisterScavenging.h148
-rw-r--r--include/llvm/CodeGen/RuntimeLibcalls.h109
-rw-r--r--include/llvm/CodeGen/SSARegMap.h55
-rw-r--r--include/llvm/CodeGen/SchedGraphCommon.h289
-rw-r--r--include/llvm/CodeGen/ScheduleDAG.h306
-rw-r--r--include/llvm/CodeGen/SchedulerRegistry.h71
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h524
-rw-r--r--include/llvm/CodeGen/SelectionDAGISel.h194
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h1641
-rw-r--r--include/llvm/CodeGen/SimpleRegisterCoalescing.h160
-rw-r--r--include/llvm/CodeGen/ValueTypes.h284
-rw-r--r--include/llvm/CodeGen/ValueTypes.td52
-rw-r--r--include/llvm/Config/alloca.h50
-rw-r--r--include/llvm/Config/config.h.in564
-rw-r--r--include/llvm/Constant.h129
-rw-r--r--include/llvm/Constants.h713
-rw-r--r--include/llvm/Debugger/Debugger.h173
-rw-r--r--include/llvm/Debugger/InferiorProcess.h138
-rw-r--r--include/llvm/Debugger/ProgramInfo.h246
-rw-r--r--include/llvm/Debugger/RuntimeInfo.h142
-rw-r--r--include/llvm/Debugger/SourceFile.h97
-rw-r--r--include/llvm/Debugger/SourceLanguage.h99
-rw-r--r--include/llvm/DerivedTypes.h419
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h227
-rw-r--r--include/llvm/ExecutionEngine/GenericValue.h44
-rw-r--r--include/llvm/ExecutionEngine/Interpreter.h40
-rw-r--r--include/llvm/ExecutionEngine/JIT.h40
-rw-r--r--include/llvm/Function.h280
-rw-r--r--include/llvm/GlobalAlias.h91
-rw-r--r--include/llvm/GlobalValue.h151
-rw-r--r--include/llvm/GlobalVariable.h139
-rw-r--r--include/llvm/InlineAsm.h138
-rw-r--r--include/llvm/InstrTypes.h569
-rw-r--r--include/llvm/Instruction.def191
-rw-r--r--include/llvm/Instruction.h239
-rw-r--r--include/llvm/Instructions.h2112
-rw-r--r--include/llvm/IntrinsicInst.h323
-rw-r--r--include/llvm/Intrinsics.h58
-rw-r--r--include/llvm/Intrinsics.td255
-rw-r--r--include/llvm/IntrinsicsPowerPC.td462
-rw-r--r--include/llvm/IntrinsicsX86.td715
-rw-r--r--include/llvm/LinkAllPasses.h127
-rw-r--r--include/llvm/LinkAllVMCore.h57
-rw-r--r--include/llvm/LinkTimeOptimizer.h153
-rw-r--r--include/llvm/Linker.h297
-rw-r--r--include/llvm/Module.h425
-rw-r--r--include/llvm/ModuleProvider.h88
-rw-r--r--include/llvm/ParameterAttributes.h221
-rw-r--r--include/llvm/Pass.h418
-rw-r--r--include/llvm/PassAnalysisSupport.h240
-rw-r--r--include/llvm/PassManager.h93
-rw-r--r--include/llvm/PassManagers.h382
-rw-r--r--include/llvm/PassSupport.h257
-rw-r--r--include/llvm/Support/AIXDataTypesFix.h25
-rw-r--r--include/llvm/Support/Allocator.h48
-rw-r--r--include/llvm/Support/Annotation.h216
-rw-r--r--include/llvm/Support/CFG.h266
-rw-r--r--include/llvm/Support/CallSite.h122
-rw-r--r--include/llvm/Support/Casting.h303
-rw-r--r--include/llvm/Support/CommandLine.h1332
-rw-r--r--include/llvm/Support/Compiler.h48
-rw-r--r--include/llvm/Support/ConstantRange.h198
-rw-r--r--include/llvm/Support/DOTGraphTraits.h122
-rw-r--r--include/llvm/Support/DataTypes.h.in131
-rw-r--r--include/llvm/Support/Debug.h78
-rw-r--r--include/llvm/Support/Dwarf.h572
-rw-r--r--include/llvm/Support/DynamicLinker.h40
-rw-r--r--include/llvm/Support/ELF.h300
-rw-r--r--include/llvm/Support/FileUtilities.h59
-rw-r--r--include/llvm/Support/GetElementPtrTypeIterator.h112
-rw-r--r--include/llvm/Support/GraphWriter.h308
-rw-r--r--include/llvm/Support/InstIterator.h147
-rw-r--r--include/llvm/Support/InstVisitor.h221
-rw-r--r--include/llvm/Support/LLVMBuilder.h431
-rw-r--r--include/llvm/Support/LeakDetector.h91
-rw-r--r--include/llvm/Support/ManagedStatic.h96
-rw-r--r--include/llvm/Support/Mangler.h118
-rw-r--r--include/llvm/Support/MathExtras.h363
-rw-r--r--include/llvm/Support/MemoryBuffer.h106
-rw-r--r--include/llvm/Support/MutexGuard.h41
-rw-r--r--include/llvm/Support/OutputBuffer.h152
-rw-r--r--include/llvm/Support/PassNameParser.h94
-rw-r--r--include/llvm/Support/PatternMatch.h382
-rw-r--r--include/llvm/Support/PluginLoader.h37
-rw-r--r--include/llvm/Support/SlowOperationInformer.h65
-rw-r--r--include/llvm/Support/StableBasicBlockNumbering.h59
-rw-r--r--include/llvm/Support/Streams.h72
-rw-r--r--include/llvm/Support/SystemUtils.h42
-rw-r--r--include/llvm/Support/Timer.h165
-rw-r--r--include/llvm/Support/TypeInfo.h76
-rw-r--r--include/llvm/Support/type_traits.h54
-rw-r--r--include/llvm/SymbolTableListTraits.h76
-rw-r--r--include/llvm/System/Alarm.h49
-rw-r--r--include/llvm/System/Disassembler.h35
-rw-r--r--include/llvm/System/DynamicLibrary.h125
-rw-r--r--include/llvm/System/IncludeFile.h65
-rw-r--r--include/llvm/System/LICENSE.TXT6
-rw-r--r--include/llvm/System/MappedFile.h175
-rw-r--r--include/llvm/System/Memory.h76
-rw-r--r--include/llvm/System/Mutex.h88
-rw-r--r--include/llvm/System/Path.h656
-rw-r--r--include/llvm/System/Process.h105
-rw-r--r--include/llvm/System/Program.h95
-rw-r--r--include/llvm/System/Signals.h55
-rw-r--r--include/llvm/System/TimeValue.h385
-rw-r--r--include/llvm/Target/MRegisterInfo.h624
-rw-r--r--include/llvm/Target/SubtargetFeature.h110
-rw-r--r--include/llvm/Target/TargetAsmInfo.h615
-rw-r--r--include/llvm/Target/TargetData.h243
-rw-r--r--include/llvm/Target/TargetELFWriterInfo.h43
-rw-r--r--include/llvm/Target/TargetFrameInfo.h82
-rw-r--r--include/llvm/Target/TargetInstrInfo.h478
-rw-r--r--include/llvm/Target/TargetInstrItineraries.h84
-rw-r--r--include/llvm/Target/TargetJITInfo.h90
-rw-r--r--include/llvm/Target/TargetLowering.h1153
-rw-r--r--include/llvm/Target/TargetMachOWriterInfo.h112
-rw-r--r--include/llvm/Target/TargetMachine.h330
-rw-r--r--include/llvm/Target/TargetMachineRegistry.h128
-rw-r--r--include/llvm/Target/TargetOptions.h79
-rw-r--r--include/llvm/Target/TargetSubtarget.h36
-rw-r--r--include/llvm/Transforms/IPO.h173
-rw-r--r--include/llvm/Transforms/IPO/InlinerPass.h64
-rw-r--r--include/llvm/Transforms/Instrumentation.h37
-rw-r--r--include/llvm/Transforms/RSProfiling.h33
-rw-r--r--include/llvm/Transforms/Scalar.h341
-rw-r--r--include/llvm/Transforms/Utils/BasicBlockUtils.h123
-rw-r--r--include/llvm/Transforms/Utils/Cloning.h181
-rw-r--r--include/llvm/Transforms/Utils/FunctionUtils.h41
-rw-r--r--include/llvm/Transforms/Utils/Local.h90
-rw-r--r--include/llvm/Transforms/Utils/PromoteMemToReg.h46
-rw-r--r--include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h55
-rw-r--r--include/llvm/Type.h403
-rw-r--r--include/llvm/TypeSymbolTable.h137
-rw-r--r--include/llvm/Use.h176
-rw-r--r--include/llvm/User.h122
-rw-r--r--include/llvm/Value.h262
-rw-r--r--include/llvm/ValueSymbolTable.h137
234 files changed, 50882 insertions, 0 deletions
diff --git a/include/llvm-c/LinkTimeOptimizer.h b/include/llvm-c/LinkTimeOptimizer.h
new file mode 100644
index 0000000..6de33ca
--- /dev/null
+++ b/include/llvm-c/LinkTimeOptimizer.h
@@ -0,0 +1,58 @@
+//===-- llvm/LinkTimeOptimizer.h - LTO Public C Interface -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chandler Carruth and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header provides a C API to use the LLVM link time optimization
+// library. This is inteded to be used by linkers which are C-only in
+// their implementation for performing LTO.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LTO_CAPI_H__
+#define __LTO_CAPI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /// This provides a dummy type for pointers to the LTO object.
+ typedef void* llvm_lto_t;
+
+ /// This provides a C-visible enumerator to manage status codes.
+ /// This should map exactly onto the C++ enumerator LTOStatus.
+ typedef enum llvm_lto_status {
+ LLVM_LTO_UNKNOWN,
+ LLVM_LTO_OPT_SUCCESS,
+ LLVM_LTO_READ_SUCCESS,
+ LLVM_LTO_READ_FAILURE,
+ LLVM_LTO_WRITE_FAILURE,
+ LLVM_LTO_NO_TARGET,
+ LLVM_LTO_NO_WORK,
+ LLVM_LTO_MODULE_MERGE_FAILURE,
+ LLVM_LTO_ASM_FAILURE,
+
+ // Added C-specific error codes
+ LLVM_LTO_NULL_OBJECT
+ } llvm_lto_status_t;
+
+ /// This provides C interface to initialize link time optimizer. This allows
+ /// linker to use dlopen() interface to dynamically load LinkTimeOptimizer.
+ /// extern "C" helps, because dlopen() interface uses name to find the symbol.
+ extern llvm_lto_t llvm_create_optimizer(void);
+ extern void llvm_destroy_optimizer(llvm_lto_t lto);
+
+ extern llvm_lto_status_t llvm_read_object_file
+ (llvm_lto_t lto, const char* input_filename);
+ extern llvm_lto_status_t llvm_optimize_modules
+ (llvm_lto_t lto, const char* output_filename);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h
new file mode 100644
index 0000000..535e5db
--- /dev/null
+++ b/include/llvm/ADT/APInt.h
@@ -0,0 +1,1228 @@
+//===-- llvm/Support/APInt.h - For Arbitrary Precision Integer -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Sheng Zhou and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a class to represent arbitrary precision integral
+// constant values and operations on them.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APINT_H
+#define LLVM_APINT_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// APInt Class
+//===----------------------------------------------------------------------===//
+
+/// APInt - This class represents arbitrary precision constant integral values.
+/// It is a functional replacement for common case unsigned integer type like
+/// "unsigned", "unsigned long" or "uint64_t", but also allows non-byte-width
+/// integer sizes and large integer value types such as 3-bits, 15-bits, or more
+/// than 64-bits of precision. APInt provides a variety of arithmetic operators
+/// and methods to manipulate integer values of any bit-width. It supports both
+/// the typical integer arithmetic and comparison operations as well as bitwise
+/// manipulation.
+///
+/// The class has several invariants worth noting:
+/// * All bit, byte, and word positions are zero-based.
+/// * Once the bit width is set, it doesn't change except by the Truncate,
+/// SignExtend, or ZeroExtend operations.
+/// * All binary operators must be on APInt instances of the same bit width.
+/// Attempting to use these operators on instances with different bit
+/// widths will yield an assertion.
+/// * The value is stored canonically as an unsigned value. For operations
+/// where it makes a difference, there are both signed and unsigned variants
+/// of the operation. For example, sdiv and udiv. However, because the bit
+/// widths must be the same, operations such as Mul and Add produce the same
+/// results regardless of whether the values are interpreted as signed or
+/// not.
+/// * In general, the class tries to follow the style of computation that LLVM
+/// uses in its IR. This simplifies its use for LLVM.
+///
+/// @brief Class for arbitrary precision integers.
+class APInt {
+
+ uint32_t BitWidth; ///< The number of bits in this APInt.
+
+ /// This union is used to store the integer value. When the
+ /// integer bit-width <= 64, it uses VAL, otherwise it uses pVal.
+ union {
+ uint64_t VAL; ///< Used to store the <= 64 bits integer value.
+ uint64_t *pVal; ///< Used to store the >64 bits integer value.
+ };
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum {
+ APINT_BITS_PER_WORD = sizeof(uint64_t) * 8, ///< Bits in a word
+ APINT_WORD_SIZE = sizeof(uint64_t) ///< Byte size of a word
+ };
+
+ /// This constructor is used only internally for speed of construction of
+ /// temporaries. It is unsafe for general use so it is not public.
+ /// @brief Fast internal constructor
+ APInt(uint64_t* val, uint32_t bits) : BitWidth(bits), pVal(val) { }
+
+ /// @returns true if the number of bits <= 64, false otherwise.
+ /// @brief Determine if this APInt just has one word to store value.
+ inline bool isSingleWord() const {
+ return BitWidth <= APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the word position for the specified bit position.
+ /// @brief Determine which word a bit is in.
+ static inline uint32_t whichWord(uint32_t bitPosition) {
+ return bitPosition / APINT_BITS_PER_WORD;
+ }
+
+ /// @returns the bit position in a word for the specified bit position
+ /// in the APInt.
+ /// @brief Determine which bit in a word a bit is in.
+ static inline uint32_t whichBit(uint32_t bitPosition) {
+ return bitPosition % APINT_BITS_PER_WORD;
+ }
+
+ /// This method generates and returns a uint64_t (word) mask for a single
+ /// bit at a specific bit position. This is used to mask the bit in the
+ /// corresponding word.
+ /// @returns a uint64_t with only bit at "whichBit(bitPosition)" set
+ /// @brief Get a single bit mask.
+ static inline uint64_t maskBit(uint32_t bitPosition) {
+ return 1ULL << whichBit(bitPosition);
+ }
+
+ /// This method is used internally to clear the to "N" bits in the high order
+ /// word that are not used by the APInt. This is needed after the most
+ /// significant word is assigned a value to ensure that those bits are
+ /// zero'd out.
+ /// @brief Clear unused high order bits
+ inline APInt& clearUnusedBits() {
+ // Compute how many bits are used in the final word
+ uint32_t wordBits = BitWidth % APINT_BITS_PER_WORD;
+ if (wordBits == 0)
+ // If all bits are used, we want to leave the value alone. This also
+ // avoids the undefined behavior of >> when the shfit is the same size as
+ // the word size (64).
+ return *this;
+
+ // Mask out the hight bits.
+ uint64_t mask = ~uint64_t(0ULL) >> (APINT_BITS_PER_WORD - wordBits);
+ if (isSingleWord())
+ VAL &= mask;
+ else
+ pVal[getNumWords() - 1] &= mask;
+ return *this;
+ }
+
+ /// @returns the corresponding word for the specified bit position.
+ /// @brief Get the word corresponding to a bit position
+ inline uint64_t getWord(uint32_t bitPosition) const {
+ return isSingleWord() ? VAL : pVal[whichWord(bitPosition)];
+ }
+
+ /// This is used by the constructors that take string arguments.
+ /// @brief Convert a char array into an APInt
+ void fromString(uint32_t numBits, const char *strStart, uint32_t slen,
+ uint8_t radix);
+
+ /// This is used by the toString method to divide by the radix. It simply
+ /// provides a more convenient form of divide for internal use since KnuthDiv
+ /// has specific constraints on its inputs. If those constraints are not met
+ /// then it provides a simpler form of divide.
+ /// @brief An internal division function for dividing APInts.
+ static void divide(const APInt LHS, uint32_t lhsWords,
+ const APInt &RHS, uint32_t rhsWords,
+ APInt *Quotient, APInt *Remainder);
+
+#ifndef NDEBUG
+ /// @brief debug method
+ void dump() const;
+#endif
+
+public:
+ /// @name Constructors
+ /// @{
+ /// If isSigned is true then val is treated as if it were a signed value
+ /// (i.e. as an int64_t) and the appropriate sign extension to the bit width
+ /// will be done. Otherwise, no sign extension occurs (high order bits beyond
+ /// the range of val are zero filled).
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the initial value of the APInt
+ /// @param isSigned how to treat signedness of val
+ /// @brief Create a new APInt of numBits width, initialized as val.
+ APInt(uint32_t numBits, uint64_t val, bool isSigned = false);
+
+ /// Note that numWords can be smaller or larger than the corresponding bit
+ /// width but any extraneous bits will be dropped.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param numWords the number of words in bigVal
+ /// @param bigVal a sequence of words to form the initial value of the APInt
+ /// @brief Construct an APInt of numBits width, initialized as bigVal[].
+ APInt(uint32_t numBits, uint32_t numWords, uint64_t bigVal[]);
+
+ /// This constructor interprets Val as a string in the given radix. The
+ /// interpretation stops when the first charater that is not suitable for the
+ /// radix is encountered. Acceptable radix values are 2, 8, 10 and 16. It is
+ /// an error for the value implied by the string to require more bits than
+ /// numBits.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param val the string to be interpreted
+ /// @param radix the radix of Val to use for the intepretation
+ /// @brief Construct an APInt from a string representation.
+ APInt(uint32_t numBits, const std::string& val, uint8_t radix);
+
+ /// This constructor interprets the slen characters starting at StrStart as
+ /// a string in the given radix. The interpretation stops when the first
+ /// character that is not suitable for the radix is encountered. Acceptable
+ /// radix values are 2, 8, 10 and 16. It is an error for the value implied by
+ /// the string to require more bits than numBits.
+ /// @param numBits the bit width of the constructed APInt
+ /// @param strStart the start of the string to be interpreted
+ /// @param slen the maximum number of characters to interpret
+ /// @brief Construct an APInt from a string representation.
+ APInt(uint32_t numBits, const char strStart[], uint32_t slen, uint8_t radix);
+
+ /// Simply makes *this a copy of that.
+ /// @brief Copy Constructor.
+ APInt(const APInt& that);
+
+ /// @brief Destructor.
+ ~APInt();
+
+ /// @}
+ /// @name Value Tests
+ /// @{
+ /// This tests the high bit of this APInt to determine if it is set.
+ /// @returns true if this APInt is negative, false otherwise
+ /// @brief Determine sign of this APInt.
+ bool isNegative() const {
+ return (*this)[BitWidth - 1];
+ }
+
+ /// This tests the high bit of the APInt to determine if it is unset.
+ /// @brief Determine if this APInt Value is positive (not negative).
+ bool isPositive() const {
+ return !isNegative();
+ }
+
+ /// This tests if the value of this APInt is strictly positive (> 0).
+ /// @returns true if this APInt is Positive and not zero.
+ /// @brief Determine if this APInt Value is strictly positive.
+ inline bool isStrictlyPositive() const {
+ return isPositive() && (*this) != 0;
+ }
+
+ /// This checks to see if the value has all bits of the APInt are set or not.
+ /// @brief Determine if all bits are set
+ inline bool isAllOnesValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest unsigned value.
+ bool isMaxValue() const {
+ return countPopulation() == BitWidth;
+ }
+
+ /// This checks to see if the value of this APInt is the maximum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the largest signed value.
+ bool isMaxSignedValue() const {
+ return BitWidth == 1 ? VAL == 0 :
+ !isNegative() && countPopulation() == BitWidth - 1;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum unsigned
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest unsigned value.
+ bool isMinValue() const {
+ return countPopulation() == 0;
+ }
+
+ /// This checks to see if the value of this APInt is the minimum signed
+ /// value for the APInt's bit width.
+ /// @brief Determine if this is the smallest signed value.
+ bool isMinSignedValue() const {
+ return BitWidth == 1 ? VAL == 1 :
+ isNegative() && countPopulation() == 1;
+ }
+
+ /// @brief Check if this APInt has an N-bits integer value.
+ inline bool isIntN(uint32_t N) const {
+ assert(N && "N == 0 ???");
+ if (isSingleWord()) {
+ return VAL == (VAL & (~0ULL >> (64 - N)));
+ } else {
+ APInt Tmp(N, getNumWords(), pVal);
+ return Tmp == (*this);
+ }
+ }
+
+ /// @returns true if the argument APInt value is a power of two > 0.
+ bool isPowerOf2() const;
+
+ /// isSignBit - Return true if this is the value returned by getSignBit.
+ bool isSignBit() const { return isMinSignedValue(); }
+
+ /// This converts the APInt to a boolean value as a test against zero.
+ /// @brief Boolean conversion function.
+ inline bool getBoolValue() const {
+ return *this != 0;
+ }
+
+ /// getLimitedValue - If this value is smaller than the specified limit,
+ /// return it, otherwise return the limit value. This causes the value
+ /// to saturate to the limit.
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return (getActiveBits() > 64 || getZExtValue() > Limit) ?
+ Limit : getZExtValue();
+ }
+
+ /// @}
+ /// @name Value Generators
+ /// @{
+ /// @brief Gets maximum unsigned value of APInt for specific bit width.
+ static APInt getMaxValue(uint32_t numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @brief Gets maximum signed value of APInt for a specific bit width.
+ static APInt getSignedMaxValue(uint32_t numBits) {
+ return APInt(numBits, 0).set().clear(numBits - 1);
+ }
+
+ /// @brief Gets minimum unsigned value of APInt for a specific bit width.
+ static APInt getMinValue(uint32_t numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// @brief Gets minimum signed value of APInt for a specific bit width.
+ static APInt getSignedMinValue(uint32_t numBits) {
+ return APInt(numBits, 0).set(numBits - 1);
+ }
+
+ /// getSignBit - This is just a wrapper function of getSignedMinValue(), and
+ /// it helps code readability when we want to get a SignBit.
+ /// @brief Get the SignBit for a specific bit width.
+ inline static APInt getSignBit(uint32_t BitWidth) {
+ return getSignedMinValue(BitWidth);
+ }
+
+ /// @returns the all-ones value for an APInt of the specified bit-width.
+ /// @brief Get the all-ones value.
+ static APInt getAllOnesValue(uint32_t numBits) {
+ return APInt(numBits, 0).set();
+ }
+
+ /// @returns the '0' value for an APInt of the specified bit-width.
+ /// @brief Get the '0' value.
+ static APInt getNullValue(uint32_t numBits) {
+ return APInt(numBits, 0);
+ }
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the low bits and right shift to the least significant bit.
+ /// @returns the high "numBits" bits of this APInt.
+ APInt getHiBits(uint32_t numBits) const;
+
+ /// Get an APInt with the same BitWidth as this APInt, just zero mask
+ /// the high bits.
+ /// @returns the low "numBits" bits of this APInt.
+ APInt getLoBits(uint32_t numBits) const;
+
+ /// Constructs an APInt value that has a contiguous range of bits set. The
+ /// bits from loBit to hiBit will be set. All other bits will be zero. For
+ /// example, with parameters(32, 15, 0) you would get 0x0000FFFF. If hiBit is
+ /// less than loBit then the set bits "wrap". For example, with
+ /// parameters (32, 3, 28), you would get 0xF000000F.
+ /// @param numBits the intended bit width of the result
+ /// @param loBit the index of the lowest bit set.
+ /// @param hiBit the index of the highest bit set.
+ /// @returns An APInt value with the requested bits set.
+ /// @brief Get a value with a block of bits set.
+ static APInt getBitsSet(uint32_t numBits, uint32_t loBit, uint32_t hiBit) {
+ assert(hiBit < numBits && "hiBit out of range");
+ assert(loBit < numBits && "loBit out of range");
+ if (hiBit < loBit)
+ return getLowBitsSet(numBits, hiBit+1) |
+ getHighBitsSet(numBits, numBits-loBit+1);
+ return getLowBitsSet(numBits, hiBit-loBit+1).shl(loBit);
+ }
+
+ /// Constructs an APInt value that has the top hiBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param hiBitsSet the number of high-order bits set in the result.
+ /// @brief Get a value with high bits set
+ static APInt getHighBitsSet(uint32_t numBits, uint32_t hiBitsSet) {
+ assert(hiBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (hiBitsSet == 0)
+ return APInt(numBits, 0);
+ uint32_t shiftAmt = numBits - hiBitsSet;
+ // For small values, return quickly
+ if (numBits <= APINT_BITS_PER_WORD)
+ return APInt(numBits, ~0ULL << shiftAmt);
+ return (~APInt(numBits, 0)).shl(shiftAmt);
+ }
+
+ /// Constructs an APInt value that has the bottom loBitsSet bits set.
+ /// @param numBits the bitwidth of the result
+ /// @param loBitsSet the number of low-order bits set in the result.
+ /// @brief Get a value with low bits set
+ static APInt getLowBitsSet(uint32_t numBits, uint32_t loBitsSet) {
+ assert(loBitsSet <= numBits && "Too many bits to set!");
+ // Handle a degenerate case, to avoid shifting by word size
+ if (loBitsSet == 0)
+ return APInt(numBits, 0);
+ if (loBitsSet == APINT_BITS_PER_WORD)
+ return APInt(numBits, -1ULL);
+ // For small values, return quickly
+ if (numBits < APINT_BITS_PER_WORD)
+ return APInt(numBits, (1ULL << loBitsSet) - 1);
+ return (~APInt(numBits, 0)).lshr(numBits - loBitsSet);
+ }
+
+ /// The hash value is computed as the sum of the words and the bit width.
+ /// @returns A hash value computed from the sum of the APInt words.
+ /// @brief Get a hash value based on this APInt
+ uint64_t getHashValue() const;
+
+ /// This function returns a pointer to the internal storage of the APInt.
+ /// This is useful for writing out the APInt in binary form without any
+ /// conversions.
+ inline const uint64_t* getRawData() const {
+ if (isSingleWord())
+ return &VAL;
+ return &pVal[0];
+ }
+
+ /// @}
+ /// @name Unary Operators
+ /// @{
+ /// @returns a new APInt value representing *this incremented by one
+ /// @brief Postfix increment operator.
+ inline const APInt operator++(int) {
+ APInt API(*this);
+ ++(*this);
+ return API;
+ }
+
+ /// @returns *this incremented by one
+ /// @brief Prefix increment operator.
+ APInt& operator++();
+
+ /// @returns a new APInt representing *this decremented by one.
+ /// @brief Postfix decrement operator.
+ inline const APInt operator--(int) {
+ APInt API(*this);
+ --(*this);
+ return API;
+ }
+
+ /// @returns *this decremented by one.
+ /// @brief Prefix decrement operator.
+ APInt& operator--();
+
+ /// Performs a bitwise complement operation on this APInt.
+ /// @returns an APInt that is the bitwise complement of *this
+ /// @brief Unary bitwise complement operator.
+ APInt operator~() const;
+
+ /// Negates *this using two's complement logic.
+ /// @returns An APInt value representing the negation of *this.
+ /// @brief Unary negation operator
+ inline APInt operator-() const {
+ return APInt(BitWidth, 0) - (*this);
+ }
+
+ /// Performs logical negation operation on this APInt.
+ /// @returns true if *this is zero, false otherwise.
+ /// @brief Logical negation operator.
+ bool operator !() const;
+
+ /// @}
+ /// @name Assignment Operators
+ /// @{
+ /// @returns *this after assignment of RHS.
+ /// @brief Copy assignment operator.
+ APInt& operator=(const APInt& RHS);
+
+ /// The RHS value is assigned to *this. If the significant bits in RHS exceed
+ /// the bit width, the excess bits are truncated. If the bit width is larger
+ /// than 64, the value is zero filled in the unspecified high order bits.
+ /// @returns *this after assignment of RHS value.
+ /// @brief Assignment operator.
+ APInt& operator=(uint64_t RHS);
+
+ /// Performs a bitwise AND operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after ANDing with RHS.
+ /// @brief Bitwise AND assignment operator.
+ APInt& operator&=(const APInt& RHS);
+
+ /// Performs a bitwise OR operation on this APInt and RHS. The result is
+ /// assigned *this;
+ /// @returns *this after ORing with RHS.
+ /// @brief Bitwise OR assignment operator.
+ APInt& operator|=(const APInt& RHS);
+
+ /// Performs a bitwise XOR operation on this APInt and RHS. The result is
+ /// assigned to *this.
+ /// @returns *this after XORing with RHS.
+ /// @brief Bitwise XOR assignment operator.
+ APInt& operator^=(const APInt& RHS);
+
+ /// Multiplies this APInt by RHS and assigns the result to *this.
+ /// @returns *this
+ /// @brief Multiplication assignment operator.
+ APInt& operator*=(const APInt& RHS);
+
+ /// Adds RHS to *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Addition assignment operator.
+ APInt& operator+=(const APInt& RHS);
+
+ /// Subtracts RHS from *this and assigns the result to *this.
+ /// @returns *this
+ /// @brief Subtraction assignment operator.
+ APInt& operator-=(const APInt& RHS);
+
+ /// Shifts *this left by shiftAmt and assigns the result to *this.
+ /// @returns *this after shifting left by shiftAmt
+ /// @brief Left-shift assignment function.
+ inline APInt& operator<<=(uint32_t shiftAmt) {
+ *this = shl(shiftAmt);
+ return *this;
+ }
+
+ /// @}
+ /// @name Binary Operators
+ /// @{
+ /// Performs a bitwise AND operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise AND of *this and RHS.
+ /// @brief Bitwise AND operator.
+ APInt operator&(const APInt& RHS) const;
+ APInt And(const APInt& RHS) const {
+ return this->operator&(RHS);
+ }
+
+ /// Performs a bitwise OR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise OR of *this and RHS.
+ /// @brief Bitwise OR operator.
+ APInt operator|(const APInt& RHS) const;
+ APInt Or(const APInt& RHS) const {
+ return this->operator|(RHS);
+ }
+
+ /// Performs a bitwise XOR operation on *this and RHS.
+ /// @returns An APInt value representing the bitwise XOR of *this and RHS.
+ /// @brief Bitwise XOR operator.
+ APInt operator^(const APInt& RHS) const;
+ APInt Xor(const APInt& RHS) const {
+ return this->operator^(RHS);
+ }
+
+ /// Multiplies this APInt by RHS and returns the result.
+ /// @brief Multiplication operator.
+ APInt operator*(const APInt& RHS) const;
+
+ /// Adds RHS to this APInt and returns the result.
+ /// @brief Addition operator.
+ APInt operator+(const APInt& RHS) const;
+ APInt operator+(uint64_t RHS) const {
+ return (*this) + APInt(BitWidth, RHS);
+ }
+
+ /// Subtracts RHS from this APInt and returns the result.
+ /// @brief Subtraction operator.
+ APInt operator-(const APInt& RHS) const;
+ APInt operator-(uint64_t RHS) const {
+ return (*this) - APInt(BitWidth, RHS);
+ }
+
+ APInt operator<<(unsigned Bits) const {
+ return shl(Bits);
+ }
+
+ /// Arithmetic right-shift this APInt by shiftAmt.
+ /// @brief Arithmetic right-shift function.
+ APInt ashr(uint32_t shiftAmt) const;
+
+ /// Logical right-shift this APInt by shiftAmt.
+ /// @brief Logical right-shift function.
+ APInt lshr(uint32_t shiftAmt) const;
+
+ /// Left-shift this APInt by shiftAmt.
+ /// @brief Left-shift function.
+ APInt shl(uint32_t shiftAmt) const;
+
+ /// @brief Rotate left by rotateAmt.
+ APInt rotl(uint32_t rotateAmt) const;
+
+ /// @brief Rotate right by rotateAmt.
+ APInt rotr(uint32_t rotateAmt) const;
+
+ /// Perform an unsigned divide operation on this APInt by RHS. Both this and
+ /// RHS are treated as unsigned quantities for purposes of this division.
+ /// @returns a new APInt value containing the division result
+ /// @brief Unsigned division operation.
+ APInt udiv(const APInt& RHS) const;
+
+ /// Signed divide this APInt by APInt RHS.
+ /// @brief Signed division function for APInt.
+ inline APInt sdiv(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return (-(*this)).udiv(-RHS);
+ else
+ return -((-(*this)).udiv(RHS));
+ else if (RHS.isNegative())
+ return -(this->udiv(-RHS));
+ return this->udiv(RHS);
+ }
+
+ /// Perform an unsigned remainder operation on this APInt with RHS being the
+ /// divisor. Both this and RHS are treated as unsigned quantities for purposes
+ /// of this operation. Note that this is a true remainder operation and not
+ /// a modulo operation because the sign follows the sign of the dividend
+ /// which is *this.
+ /// @returns a new APInt value containing the remainder result
+ /// @brief Unsigned remainder operation.
+ APInt urem(const APInt& RHS) const;
+
+ /// Signed remainder operation on APInt.
+ /// @brief Function for signed remainder operation.
+ inline APInt srem(const APInt& RHS) const {
+ if (isNegative())
+ if (RHS.isNegative())
+ return -((-(*this)).urem(-RHS));
+ else
+ return -((-(*this)).urem(RHS));
+ else if (RHS.isNegative())
+ return this->urem(-RHS);
+ return this->urem(RHS);
+ }
+
+ /// Sometimes it is convenient to divide two APInt values and obtain both
+ /// the quotient and remainder. This function does both operations in the
+ /// same computation making it a little more efficient.
+ /// @brief Dual division/remainder interface.
+ static void udivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder);
+
+ static void sdivrem(const APInt &LHS, const APInt &RHS,
+ APInt &Quotient, APInt &Remainder)
+ {
+ if (LHS.isNegative()) {
+ if (RHS.isNegative())
+ APInt::udivrem(-LHS, -RHS, Quotient, Remainder);
+ else
+ APInt::udivrem(-LHS, RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ Remainder = -Remainder;
+ } else if (RHS.isNegative()) {
+ APInt::udivrem(LHS, -RHS, Quotient, Remainder);
+ Quotient = -Quotient;
+ } else {
+ APInt::udivrem(LHS, RHS, Quotient, Remainder);
+ }
+ }
+
+ /// @returns the bit value at bitPosition
+ /// @brief Array-indexing support.
+ bool operator[](uint32_t bitPosition) const;
+
+ /// @}
+ /// @name Comparison Operators
+ /// @{
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @brief Equality operator.
+ bool operator==(const APInt& RHS) const;
+
+ /// Compares this APInt with a uint64_t for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality operator.
+ bool operator==(uint64_t Val) const;
+
+ /// Compares this APInt with RHS for the validity of the equality
+ /// relationship.
+ /// @returns true if *this == Val
+ /// @brief Equality comparison.
+ bool eq(const APInt &RHS) const {
+ return (*this) == RHS;
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ inline bool operator!=(const APInt& RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Compares this APInt with a uint64_t for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality operator.
+ inline bool operator!=(uint64_t Val) const {
+ return !((*this) == Val);
+ }
+
+ /// Compares this APInt with RHS for the validity of the inequality
+ /// relationship.
+ /// @returns true if *this != Val
+ /// @brief Inequality comparison
+ bool ne(const APInt &RHS) const {
+ return !((*this) == RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered unsigned.
+ /// @brief Unsigned less than comparison
+ bool ult(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-than relationship.
+ /// @returns true if *this < RHS when both are considered signed.
+ /// @brief Signed less than comparison
+ bool slt(const APInt& RHS) const;
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered unsigned.
+ /// @brief Unsigned less or equal comparison
+ bool ule(const APInt& RHS) const {
+ return ult(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the less-or-equal relationship.
+ /// @returns true if *this <= RHS when both are considered signed.
+ /// @brief Signed less or equal comparison
+ bool sle(const APInt& RHS) const {
+ return slt(RHS) || eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered unsigned.
+ /// @brief Unsigned greather than comparison
+ bool ugt(const APInt& RHS) const {
+ return !ult(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// the validity of the greater-than relationship.
+ /// @returns true if *this > RHS when both are considered signed.
+ /// @brief Signed greather than comparison
+ bool sgt(const APInt& RHS) const {
+ return !slt(RHS) && !eq(RHS);
+ }
+
+ /// Regards both *this and RHS as unsigned quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered unsigned.
+ /// @brief Unsigned greater or equal comparison
+ bool uge(const APInt& RHS) const {
+ return !ult(RHS);
+ }
+
+ /// Regards both *this and RHS as signed quantities and compares them for
+ /// validity of the greater-or-equal relationship.
+ /// @returns true if *this >= RHS when both are considered signed.
+ /// @brief Signed greather or equal comparison
+ bool sge(const APInt& RHS) const {
+ return !slt(RHS);
+ }
+
+ /// @}
+ /// @name Resizing Operators
+ /// @{
+ /// Truncate the APInt to a specified width. It is an error to specify a width
+ /// that is greater than or equal to the current width.
+ /// @brief Truncate to new width.
+ APInt &trunc(uint32_t width);
+
+ /// This operation sign extends the APInt to a new width. If the high order
+ /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
+ /// It is an error to specify a width that is less than or equal to the
+ /// current width.
+ /// @brief Sign extend to a new width.
+ APInt &sext(uint32_t width);
+
+ /// This operation zero extends the APInt to a new width. The high order bits
+ /// are filled with 0 bits. It is an error to specify a width that is less
+ /// than or equal to the current width.
+ /// @brief Zero extend to a new width.
+ APInt &zext(uint32_t width);
+
+ /// Make this APInt have the bit width given by \p width. The value is sign
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Sign extend or truncate to width
+ APInt &sextOrTrunc(uint32_t width);
+
+ /// Make this APInt have the bit width given by \p width. The value is zero
+ /// extended, truncated, or left alone to make it that width.
+ /// @brief Zero extend or truncate to width
+ APInt &zextOrTrunc(uint32_t width);
+
+ /// @}
+ /// @name Bit Manipulation Operators
+ /// @{
+ /// @brief Set every bit to 1.
+ APInt& set();
+
+ /// Set the given bit to 1 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 1.
+ APInt& set(uint32_t bitPosition);
+
+ /// @brief Set every bit to 0.
+ APInt& clear();
+
+ /// Set the given bit to 0 whose position is given as "bitPosition".
+ /// @brief Set a given bit to 0.
+ APInt& clear(uint32_t bitPosition);
+
+ /// @brief Toggle every bit to its opposite value.
+ APInt& flip();
+
+ /// Toggle a given bit to its opposite value whose position is given
+ /// as "bitPosition".
+ /// @brief Toggles a given bit to its opposite value.
+ APInt& flip(uint32_t bitPosition);
+
+ /// @}
+ /// @name Value Characterization Functions
+ /// @{
+
+ /// @returns the total number of bits.
+ inline uint32_t getBitWidth() const {
+ return BitWidth;
+ }
+
+ /// Here one word's bitwidth equals to that of uint64_t.
+ /// @returns the number of words to hold the integer value of this APInt.
+ /// @brief Get the number of words.
+ inline uint32_t getNumWords() const {
+ return (BitWidth + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
+ }
+
+ /// This function returns the number of active bits which is defined as the
+ /// bit width minus the number of leading zeros. This is used in several
+ /// computations to see how "wide" the value is.
+ /// @brief Compute the number of active bits in the value
+ inline uint32_t getActiveBits() const {
+ return BitWidth - countLeadingZeros();
+ }
+
+ /// This function returns the number of active words in the value of this
+ /// APInt. This is used in conjunction with getActiveData to extract the raw
+ /// value of the APInt.
+ inline uint32_t getActiveWords() const {
+ return whichWord(getActiveBits()-1) + 1;
+ }
+
+ /// Computes the minimum bit width for this APInt while considering it to be
+ /// a signed (and probably negative) value. If the value is not negative,
+ /// this function returns the same value as getActiveBits(). Otherwise, it
+ /// returns the smallest bit width that will retain the negative value. For
+ /// example, -1 can be written as 0b1 or 0xFFFFFFFFFF. 0b1 is shorter and so
+ /// for -1, this function will always return 1.
+ /// @brief Get the minimum bit size for this signed APInt
+ inline uint32_t getMinSignedBits() const {
+ if (isNegative())
+ return BitWidth - countLeadingOnes() + 1;
+ return getActiveBits();
+ }
+
+ /// This method attempts to return the value of this APInt as a zero extended
+ /// uint64_t. The bitwidth must be <= 64 or the value must fit within a
+ /// uint64_t. Otherwise an assertion will result.
+ /// @brief Get zero extended value
+ inline uint64_t getZExtValue() const {
+ if (isSingleWord())
+ return VAL;
+ assert(getActiveBits() <= 64 && "Too many bits for uint64_t");
+ return pVal[0];
+ }
+
+ /// This method attempts to return the value of this APInt as a sign extended
+ /// int64_t. The bit width must be <= 64 or the value must fit within an
+ /// int64_t. Otherwise an assertion will result.
+ /// @brief Get sign extended value
+ inline int64_t getSExtValue() const {
+ if (isSingleWord())
+ return int64_t(VAL << (APINT_BITS_PER_WORD - BitWidth)) >>
+ (APINT_BITS_PER_WORD - BitWidth);
+ assert(getActiveBits() <= 64 && "Too many bits for int64_t");
+ return int64_t(pVal[0]);
+ }
+
+ /// This method determines how many bits are required to hold the APInt
+ /// equivalent of the string given by \p str of length \p slen.
+ /// @brief Get bits required for string value.
+ static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix);
+
+ /// countLeadingZeros - This function is an APInt version of the
+ /// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
+ /// of zeros from the most significant bit to the first one bit.
+ /// @returns getNumWords() * APINT_BITS_PER_WORD if the value is zero.
+ /// @returns the number of zeros from the most significant bit to the first
+ /// one bits.
+ /// @brief Count the number of leading one bits.
+ uint32_t countLeadingZeros() const;
+
+ /// countLeadingOnes - This function counts the number of contiguous 1 bits
+ /// in the high order bits. The count stops when the first 0 bit is reached.
+ /// @returns 0 if the high order bit is not set
+ /// @returns the number of 1 bits from the most significant to the least
+ /// @brief Count the number of leading one bits.
+ uint32_t countLeadingOnes() const;
+
+ /// countTrailingZeros - This function is an APInt version of the
+ /// countTrailingZoers_{32,64} functions in MathExtras.h. It counts
+ /// the number of zeros from the least significant bit to the first one bit.
+ /// @returns getNumWords() * APINT_BITS_PER_WORD if the value is zero.
+ /// @returns the number of zeros from the least significant bit to the first
+ /// one bit.
+ /// @brief Count the number of trailing zero bits.
+ uint32_t countTrailingZeros() const;
+
+ /// countPopulation - This function is an APInt version of the
+ /// countPopulation_{32,64} functions in MathExtras.h. It counts the number
+ /// of 1 bits in the APInt value.
+ /// @returns 0 if the value is zero.
+ /// @returns the number of set bits.
+ /// @brief Count the number of bits set.
+ uint32_t countPopulation() const;
+
+ /// @}
+ /// @name Conversion Functions
+ /// @{
+
+ /// This is used internally to convert an APInt to a string.
+ /// @brief Converts an APInt to a std::string
+ std::string toString(uint8_t radix, bool wantSigned) const;
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ /// @returns a character interpretation of the APInt
+ /// @brief Convert unsigned APInt to string representation.
+ inline std::string toString(uint8_t radix = 10) const {
+ return toString(radix, false);
+ }
+
+ /// Considers the APInt to be unsigned and converts it into a string in the
+ /// radix given. The radix can be 2, 8, 10 or 16.
+ /// @returns a character interpretation of the APInt
+ /// @brief Convert unsigned APInt to string representation.
+ inline std::string toStringSigned(uint8_t radix = 10) const {
+ return toString(radix, true);
+ }
+
+ /// @returns a byte-swapped representation of this APInt Value.
+ APInt byteSwap() const;
+
+ /// @brief Converts this APInt to a double value.
+ double roundToDouble(bool isSigned) const;
+
+ /// @brief Converts this unsigned APInt to a double value.
+ double roundToDouble() const {
+ return roundToDouble(false);
+ }
+
+ /// @brief Converts this signed APInt to a double value.
+ double signedRoundToDouble() const {
+ return roundToDouble(true);
+ }
+
+ /// The conversion does not do a translation from integer to double, it just
+ /// re-interprets the bits as a double. Note that it is valid to do this on
+ /// any bit width. Exactly 64 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ double bitsToDouble() const {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.I = (isSingleWord() ? VAL : pVal[0]);
+ return T.D;
+ }
+
+ /// The conversion does not do a translation from integer to float, it just
+ /// re-interprets the bits as a float. Note that it is valid to do this on
+ /// any bit width. Exactly 32 bits will be translated.
+ /// @brief Converts APInt bits to a double
+ float bitsToFloat() const {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = uint32_t((isSingleWord() ? VAL : pVal[0]));
+ return T.F;
+ }
+
+ /// The conversion does not do a translation from double to integer, it just
+ /// re-interprets the bits of the double. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a double to APInt bits.
+ APInt& doubleToBits(double V) {
+ union {
+ uint64_t I;
+ double D;
+ } T;
+ T.D = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// The conversion does not do a translation from float to integer, it just
+ /// re-interprets the bits of the float. Note that it is valid to do this on
+ /// any bit width but bits from V may get truncated.
+ /// @brief Converts a float to APInt bits.
+ APInt& floatToBits(float V) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = V;
+ if (isSingleWord())
+ VAL = T.I;
+ else
+ pVal[0] = T.I;
+ return clearUnusedBits();
+ }
+
+ /// @}
+ /// @name Mathematics Operations
+ /// @{
+
+ /// @returns the floor log base 2 of this APInt.
+ inline uint32_t logBase2() const {
+ return BitWidth - 1 - countLeadingZeros();
+ }
+
+ /// @returns the log base 2 of this APInt if its an exact power of two, -1
+ /// otherwise
+ inline int32_t exactLogBase2() const {
+ if (!isPowerOf2())
+ return -1;
+ return logBase2();
+ }
+
+ /// @brief Compute the square root
+ APInt sqrt() const;
+
+ /// If *this is < 0 then return -(*this), otherwise *this;
+ /// @brief Get the absolute value;
+ APInt abs() const {
+ if (isNegative())
+ return -(*this);
+ return *this;
+ }
+ /// @}
+};
+
+inline bool operator==(uint64_t V1, const APInt& V2) {
+ return V2 == V1;
+}
+
+inline bool operator!=(uint64_t V1, const APInt& V2) {
+ return V2 != V1;
+}
+
+namespace APIntOps {
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt smin(const APInt &A, const APInt &B) {
+ return A.slt(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be signed.
+inline APInt smax(const APInt &A, const APInt &B) {
+ return A.sgt(B) ? A : B;
+}
+
+/// @brief Determine the smaller of two APInts considered to be signed.
+inline APInt umin(const APInt &A, const APInt &B) {
+ return A.ult(B) ? A : B;
+}
+
+/// @brief Determine the larger of two APInts considered to be unsigned.
+inline APInt umax(const APInt &A, const APInt &B) {
+ return A.ugt(B) ? A : B;
+}
+
+/// @brief Check if the specified APInt has a N-bits integer value.
+inline bool isIntN(uint32_t N, const APInt& APIVal) {
+ return APIVal.isIntN(N);
+}
+
+/// @returns true if the argument APInt value is a sequence of ones
+/// starting at the least significant bit with the remainder zero.
+inline bool isMask(uint32_t numBits, const APInt& APIVal) {
+ return APIVal.getBoolValue() && ((APIVal + APInt(numBits,1)) & APIVal) == 0;
+}
+
+/// @returns true if the argument APInt value contains a sequence of ones
+/// with the remainder zero.
+inline bool isShiftedMask(uint32_t numBits, const APInt& APIVal) {
+ return isMask(numBits, (APIVal - APInt(numBits,1)) | APIVal);
+}
+
+/// @returns a byte-swapped representation of the specified APInt Value.
+inline APInt byteSwap(const APInt& APIVal) {
+ return APIVal.byteSwap();
+}
+
+/// @returns the floor log base 2 of the specified APInt value.
+inline uint32_t logBase2(const APInt& APIVal) {
+ return APIVal.logBase2();
+}
+
+/// GreatestCommonDivisor - This function returns the greatest common
+/// divisor of the two APInt values using Enclid's algorithm.
+/// @returns the greatest common divisor of Val1 and Val2
+/// @brief Compute GCD of two APInt values.
+APInt GreatestCommonDivisor(const APInt& Val1, const APInt& Val2);
+
+/// Treats the APInt as an unsigned value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundAPIntToDouble(const APInt& APIVal) {
+ return APIVal.roundToDouble();
+}
+
+/// Treats the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a double value.
+inline double RoundSignedAPIntToDouble(const APInt& APIVal) {
+ return APIVal.signedRoundToDouble();
+}
+
+/// @brief Converts the given APInt to a float vlalue.
+inline float RoundAPIntToFloat(const APInt& APIVal) {
+ return float(RoundAPIntToDouble(APIVal));
+}
+
+/// Treast the APInt as a signed value for conversion purposes.
+/// @brief Converts the given APInt to a float value.
+inline float RoundSignedAPIntToFloat(const APInt& APIVal) {
+ return float(APIVal.signedRoundToDouble());
+}
+
+/// RoundDoubleToAPInt - This function convert a double value to an APInt value.
+/// @brief Converts the given double value into a APInt.
+APInt RoundDoubleToAPInt(double Double, uint32_t width);
+
+/// RoundFloatToAPInt - Converts a float value into an APInt value.
+/// @brief Converts a float value into a APInt.
+inline APInt RoundFloatToAPInt(float Float, uint32_t width) {
+ return RoundDoubleToAPInt(double(Float), width);
+}
+
+/// Arithmetic right-shift the APInt by shiftAmt.
+/// @brief Arithmetic right-shift function.
+inline APInt ashr(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.ashr(shiftAmt);
+}
+
+/// Logical right-shift the APInt by shiftAmt.
+/// @brief Logical right-shift function.
+inline APInt lshr(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.lshr(shiftAmt);
+}
+
+/// Left-shift the APInt by shiftAmt.
+/// @brief Left-shift function.
+inline APInt shl(const APInt& LHS, uint32_t shiftAmt) {
+ return LHS.shl(shiftAmt);
+}
+
+/// Signed divide APInt LHS by APInt RHS.
+/// @brief Signed division function for APInt.
+inline APInt sdiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.sdiv(RHS);
+}
+
+/// Unsigned divide APInt LHS by APInt RHS.
+/// @brief Unsigned division function for APInt.
+inline APInt udiv(const APInt& LHS, const APInt& RHS) {
+ return LHS.udiv(RHS);
+}
+
+/// Signed remainder operation on APInt.
+/// @brief Function for signed remainder operation.
+inline APInt srem(const APInt& LHS, const APInt& RHS) {
+ return LHS.srem(RHS);
+}
+
+/// Unsigned remainder operation on APInt.
+/// @brief Function for unsigned remainder operation.
+inline APInt urem(const APInt& LHS, const APInt& RHS) {
+ return LHS.urem(RHS);
+}
+
+/// Performs multiplication on APInt values.
+/// @brief Function for multiplication operation.
+inline APInt mul(const APInt& LHS, const APInt& RHS) {
+ return LHS * RHS;
+}
+
+/// Performs addition on APInt values.
+/// @brief Function for addition operation.
+inline APInt add(const APInt& LHS, const APInt& RHS) {
+ return LHS + RHS;
+}
+
+/// Performs subtraction on APInt values.
+/// @brief Function for subtraction operation.
+inline APInt sub(const APInt& LHS, const APInt& RHS) {
+ return LHS - RHS;
+}
+
+/// Performs bitwise AND operation on APInt LHS and
+/// APInt RHS.
+/// @brief Bitwise AND function for APInt.
+inline APInt And(const APInt& LHS, const APInt& RHS) {
+ return LHS & RHS;
+}
+
+/// Performs bitwise OR operation on APInt LHS and APInt RHS.
+/// @brief Bitwise OR function for APInt.
+inline APInt Or(const APInt& LHS, const APInt& RHS) {
+ return LHS | RHS;
+}
+
+/// Performs bitwise XOR operation on APInt.
+/// @brief Bitwise XOR function for APInt.
+inline APInt Xor(const APInt& LHS, const APInt& RHS) {
+ return LHS ^ RHS;
+}
+
+/// Performs a bitwise complement operation on APInt.
+/// @brief Bitwise complement function.
+inline APInt Not(const APInt& APIVal) {
+ return ~APIVal;
+}
+
+} // End of APIntOps namespace
+
+} // End of llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/APSInt.h b/include/llvm/ADT/APSInt.h
new file mode 100644
index 0000000..4eb4be2
--- /dev/null
+++ b/include/llvm/ADT/APSInt.h
@@ -0,0 +1,110 @@
+//===-- llvm/Support/APSInt.h - Arbitrary Precision Signed Int -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the APSInt class, which is a simple class that
+// represents an arbitrary sized integer that knows its signedness.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_APSINT_H
+#define LLVM_APSINT_H
+
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+
+class APSInt : public APInt {
+ bool IsUnsigned;
+public:
+ /// APSInt ctor - Create an APSInt with the specified width, default to
+ /// unsigned.
+ explicit APSInt(unsigned BitWidth) : APInt(BitWidth, 0), IsUnsigned(true) {}
+ APSInt(const APInt &I) : APInt(I), IsUnsigned(true) {}
+
+ APSInt &operator=(const APSInt &RHS) {
+ APInt::operator=(RHS);
+ IsUnsigned = RHS.IsUnsigned;
+ return *this;
+ }
+
+ APSInt &operator=(const APInt &RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ APSInt &operator=(uint64_t RHS) {
+ // Retain our current sign.
+ APInt::operator=(RHS);
+ return *this;
+ }
+
+ // Query sign information.
+ bool isSigned() const { return !IsUnsigned; }
+ bool isUnsigned() const { return IsUnsigned; }
+ void setIsUnsigned(bool Val) { IsUnsigned = Val; }
+ void setIsSigned(bool Val) { IsUnsigned = !Val; }
+
+
+ const APSInt &operator%=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = urem(RHS);
+ else
+ *this = srem(RHS);
+ return *this;
+ }
+ const APSInt &operator/=(const APSInt &RHS) {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ if (IsUnsigned)
+ *this = udiv(RHS);
+ else
+ *this = sdiv(RHS);
+ return *this;
+ }
+ APSInt operator%(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? urem(RHS) : srem(RHS);
+ }
+ APSInt operator/(const APSInt &RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? udiv(RHS) : sdiv(RHS);
+ }
+
+ const APSInt &operator>>=(unsigned Amt) {
+ *this = *this >> Amt;
+ return *this;
+ }
+
+ APSInt operator>>(unsigned Amt) const {
+ return IsUnsigned ? lshr(Amt) : ashr(Amt);
+ }
+
+ inline bool operator<(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ult(RHS) : slt(RHS);
+ }
+ inline bool operator>(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ugt(RHS) : sgt(RHS);
+ }
+ inline bool operator<=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? ule(RHS) : sle(RHS);
+ }
+ inline bool operator>=(const APSInt& RHS) const {
+ assert(IsUnsigned == RHS.IsUnsigned && "Signedness mismatch!");
+ return IsUnsigned ? uge(RHS) : sge(RHS);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/BitVector.h b/include/llvm/ADT/BitVector.h
new file mode 100644
index 0000000..243a810
--- /dev/null
+++ b/include/llvm/ADT/BitVector.h
@@ -0,0 +1,369 @@
+//===- llvm/ADT/BitVector.h - Bit vectors -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the BitVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_BITVECTOR_H
+#define LLVM_ADT_BITVECTOR_H
+
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cstdlib>
+#include <cassert>
+
+namespace llvm {
+
+class BitVector {
+ typedef unsigned long BitWord;
+
+ enum { BITWORD_SIZE = sizeof(BitWord) * 8 };
+
+ BitWord *Bits; // Actual bits.
+ unsigned Size; // Size of bitvector in bits.
+ unsigned Capacity; // Size of allocated memory in BitWord.
+
+public:
+ // Encapsulation of a single bit.
+ class reference {
+ friend class BitVector;
+
+ BitWord *WordRef;
+ unsigned BitPos;
+
+ reference(); // Undefined
+
+ public:
+ reference(BitVector &b, unsigned Idx) {
+ WordRef = &b.Bits[Idx / BITWORD_SIZE];
+ BitPos = Idx % BITWORD_SIZE;
+ }
+
+ ~reference() {}
+
+ reference& operator=(bool t) {
+ if (t)
+ *WordRef |= 1L << BitPos;
+ else
+ *WordRef &= ~(1L << BitPos);
+ return *this;
+ }
+
+ operator bool() const {
+ return (*WordRef) & (1L << BitPos);
+ }
+ };
+
+
+ /// BitVector default ctor - Creates an empty bitvector.
+ BitVector() : Size(0), Capacity(0) {
+ Bits = NULL;
+ }
+
+ /// BitVector ctor - Creates a bitvector of specified number of bits. All
+ /// bits are initialized to the specified value.
+ explicit BitVector(unsigned s, bool t = false) : Size(s) {
+ Capacity = NumBitWords(s);
+ Bits = new BitWord[Capacity];
+ init_words(Bits, Capacity, t);
+ if (t)
+ clear_unused_bits();
+ }
+
+ /// BitVector copy ctor.
+ BitVector(const BitVector &RHS) : Size(RHS.size()) {
+ if (Size == 0) {
+ Bits = NULL;
+ Capacity = 0;
+ return;
+ }
+
+ Capacity = NumBitWords(RHS.size());
+ Bits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[Capacity], Bits);
+ }
+
+ ~BitVector() {
+ delete[] Bits;
+ }
+
+ /// size - Returns the number of bits in this bitvector.
+ unsigned size() const { return Size; }
+
+ /// count - Returns the number of bits which are set.
+ unsigned count() const {
+ unsigned NumBits = 0;
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (sizeof(BitWord) == 4)
+ NumBits += CountPopulation_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ NumBits += CountPopulation_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ return NumBits;
+ }
+
+ /// any - Returns true if any bit is set.
+ bool any() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0)
+ return true;
+ return false;
+ }
+
+ /// none - Returns true if none of the bits are set.
+ bool none() const {
+ return !any();
+ }
+
+ /// find_first - Returns the index of the first set bit, -1 if none
+ /// of the bits are set.
+ int find_first() const {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// find_next - Returns the index of the next set bit following the
+ /// "Prev" bit. Returns -1 if the next set bit is not found.
+ int find_next(unsigned Prev) const {
+ ++Prev;
+ if (Prev >= Size)
+ return -1;
+
+ unsigned WordPos = Prev / BITWORD_SIZE;
+ unsigned BitPos = Prev % BITWORD_SIZE;
+ BitWord Copy = Bits[WordPos];
+ // Mask off previous bits.
+ Copy &= ~0L << BitPos;
+
+ if (Copy != 0) {
+ if (sizeof(BitWord) == 4)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_32(Copy);
+ else if (sizeof(BitWord) == 8)
+ return WordPos * BITWORD_SIZE + CountTrailingZeros_64(Copy);
+ else
+ assert(0 && "Unsupported!");
+ }
+
+ // Check subsequent words.
+ for (unsigned i = WordPos+1; i < NumBitWords(size()); ++i)
+ if (Bits[i] != 0) {
+ if (sizeof(BitWord) == 4)
+ return i * BITWORD_SIZE + CountTrailingZeros_32(Bits[i]);
+ else if (sizeof(BitWord) == 8)
+ return i * BITWORD_SIZE + CountTrailingZeros_64(Bits[i]);
+ else
+ assert(0 && "Unsupported!");
+ }
+ return -1;
+ }
+
+ /// clear - Clear all bits.
+ void clear() {
+ Size = 0;
+ }
+
+ /// resize - Grow or shrink the bitvector.
+ void resize(unsigned N, bool t = false) {
+ if (N > Capacity * BITWORD_SIZE) {
+ unsigned OldCapacity = Capacity;
+ grow(N);
+ init_words(&Bits[OldCapacity], (Capacity-OldCapacity), t);
+ }
+
+ // If we previously had no size, initialize the low word
+ if (Size == 0)
+ for (unsigned i = 0; i < Capacity; ++i)
+ Bits[i] = 0 - (unsigned)t;
+
+ Size = N;
+ clear_unused_bits();
+ }
+
+ void reserve(unsigned N) {
+ if (N > Capacity * BITWORD_SIZE)
+ grow(N);
+ }
+
+ // Set, reset, flip
+ BitVector &set() {
+ init_words(Bits, Capacity, true);
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &set(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] |= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ BitVector &reset() {
+ init_words(Bits, Capacity, false);
+ return *this;
+ }
+
+ BitVector &reset(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
+ return *this;
+ }
+
+ BitVector &flip() {
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] = ~Bits[i];
+ clear_unused_bits();
+ return *this;
+ }
+
+ BitVector &flip(unsigned Idx) {
+ Bits[Idx / BITWORD_SIZE] ^= 1L << (Idx % BITWORD_SIZE);
+ return *this;
+ }
+
+ // No argument flip.
+ BitVector operator~() const {
+ return BitVector(*this).flip();
+ }
+
+ // Indexing.
+ reference operator[](unsigned Idx) {
+ return reference(*this, Idx);
+ }
+
+ bool operator[](unsigned Idx) const {
+ BitWord Mask = 1L << (Idx % BITWORD_SIZE);
+ return (Bits[Idx / BITWORD_SIZE] & Mask) != 0;
+ }
+
+ bool test(unsigned Idx) const {
+ return (*this)[Idx];
+ }
+
+ // Comparison operators.
+ bool operator==(const BitVector &RHS) const {
+ if (Size != RHS.Size)
+ return false;
+
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ if (Bits[i] != RHS.Bits[i])
+ return false;
+ return true;
+ }
+
+ bool operator!=(const BitVector &RHS) const {
+ return !(*this == RHS);
+ }
+
+ // Intersection, union, disjoint union.
+ BitVector operator&=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] &= RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector operator|=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] |= RHS.Bits[i];
+ return *this;
+ }
+
+ BitVector operator^=(const BitVector &RHS) {
+ assert(Size == RHS.Size && "Illegal operation!");
+ for (unsigned i = 0; i < NumBitWords(size()); ++i)
+ Bits[i] ^= RHS.Bits[i];
+ return *this;
+ }
+
+ // Assignment operator.
+ const BitVector &operator=(const BitVector &RHS) {
+ if (this == &RHS) return *this;
+
+ Size = RHS.size();
+ unsigned RHSWords = NumBitWords(Size);
+ if (Size <= Capacity * BITWORD_SIZE) {
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], Bits);
+ clear_unused_bits();
+ return *this;
+ }
+
+ // Grow the bitvector to have enough elements.
+ Capacity = NumBitWords(Size);
+ BitWord *NewBits = new BitWord[Capacity];
+ std::copy(RHS.Bits, &RHS.Bits[RHSWords], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+
+ return *this;
+ }
+
+private:
+ unsigned NumBitWords(unsigned S) const {
+ return (S + BITWORD_SIZE-1) / BITWORD_SIZE;
+ }
+
+ // Clear the unused top bits in the high word.
+ void clear_unused_bits() {
+ unsigned ExtraBits = Size % BITWORD_SIZE;
+ if (ExtraBits) {
+ unsigned index = Size / BITWORD_SIZE;
+ Bits[index] &= ~(~0L << ExtraBits);
+ }
+ }
+
+ void grow(unsigned NewSize) {
+ unsigned OldCapacity = Capacity;
+ Capacity = NumBitWords(NewSize);
+ BitWord *NewBits = new BitWord[Capacity];
+
+ // Copy the old bits over.
+ if (OldCapacity != 0)
+ std::copy(Bits, &Bits[OldCapacity], NewBits);
+
+ // Destroy the old bits.
+ delete[] Bits;
+ Bits = NewBits;
+ }
+
+ void init_words(BitWord *B, unsigned NumWords, bool t) {
+ memset(B, 0 - (int)t, NumWords*sizeof(BitWord));
+ }
+};
+
+inline BitVector operator&(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result &= RHS;
+ return Result;
+}
+
+inline BitVector operator|(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result |= RHS;
+ return Result;
+}
+
+inline BitVector operator^(const BitVector &LHS, const BitVector &RHS) {
+ BitVector Result(LHS);
+ Result ^= RHS;
+ return Result;
+}
+
+} // End llvm namespace
+#endif
diff --git a/include/llvm/ADT/DenseMap.h b/include/llvm/ADT/DenseMap.h
new file mode 100644
index 0000000..83edd64
--- /dev/null
+++ b/include/llvm/ADT/DenseMap.h
@@ -0,0 +1,355 @@
+//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DenseMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DENSEMAP_H
+#define LLVM_ADT_DENSEMAP_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+#include <utility>
+
+namespace llvm {
+
+template<typename T>
+struct DenseMapKeyInfo {
+ //static inline T getEmptyKey();
+ //static inline T getTombstoneKey();
+ //static unsigned getHashValue(const T &Val);
+ //static bool isPod()
+};
+
+// Provide DenseMapKeyInfo for all pointers.
+template<typename T>
+struct DenseMapKeyInfo<T*> {
+ static inline T* getEmptyKey() { return (T*)-1; }
+ static inline T* getTombstoneKey() { return (T*)-2; }
+ static unsigned getHashValue(const T *PtrVal) {
+ return (unsigned)((uintptr_t)PtrVal >> 4) ^
+ (unsigned)((uintptr_t)PtrVal >> 9);
+ }
+ static bool isPod() { return true; }
+};
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapKeyInfo<KeyT> >
+class DenseMapIterator;
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapKeyInfo<KeyT> >
+class DenseMapConstIterator;
+
+template<typename KeyT, typename ValueT,
+ typename KeyInfoT = DenseMapKeyInfo<KeyT> >
+class DenseMap {
+ typedef std::pair<KeyT, ValueT> BucketT;
+ unsigned NumBuckets;
+ BucketT *Buckets;
+
+ unsigned NumEntries;
+ unsigned NumTombstones;
+ DenseMap(const DenseMap &); // not implemented.
+public:
+ explicit DenseMap(unsigned NumInitBuckets = 64) {
+ init(NumInitBuckets);
+ }
+ ~DenseMap() {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (P->first != EmptyKey && P->first != TombstoneKey)
+ P->second.~ValueT();
+ P->first.~KeyT();
+ }
+ delete[] (char*)Buckets;
+ }
+
+ typedef DenseMapIterator<KeyT, ValueT, KeyInfoT> iterator;
+ typedef DenseMapConstIterator<KeyT, ValueT, KeyInfoT> const_iterator;
+ inline iterator begin() {
+ return iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline iterator end() {
+ return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+ inline const_iterator begin() const {
+ return const_iterator(Buckets, Buckets+NumBuckets);
+ }
+ inline const_iterator end() const {
+ return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+ }
+
+ bool empty() const { return NumEntries == 0; }
+ unsigned size() const { return NumEntries; }
+
+ void clear() {
+ const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
+ for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+ if (P->first != EmptyKey && P->first != TombstoneKey) {
+ P->first = EmptyKey;
+ P->second.~ValueT();
+ --NumEntries;
+ }
+ }
+ assert(NumEntries == 0 && "Node count imbalance!");
+ NumTombstones = 0;
+ }
+
+ /// count - Return true if the specified key is in the map.
+ bool count(const KeyT &Val) const {
+ BucketT *TheBucket;
+ return LookupBucketFor(Val, TheBucket);
+ }
+
+ iterator find(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+ const_iterator find(const KeyT &Val) const {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Val, TheBucket))
+ return const_iterator(TheBucket, Buckets+NumBuckets);
+ return end();
+ }
+
+ bool insert(const std::pair<KeyT, ValueT> &KV) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(KV.first, TheBucket))
+ return false; // Already in map.
+
+ // Otherwise, insert the new element.
+ InsertIntoBucket(KV.first, KV.second, TheBucket);
+ return true;
+ }
+
+ bool erase(const KeyT &Val) {
+ BucketT *TheBucket;
+ if (!LookupBucketFor(Val, TheBucket))
+ return false; // not in map.
+
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+ bool erase(iterator I) {
+ BucketT *TheBucket = &*I;
+ TheBucket->second.~ValueT();
+ TheBucket->first = getTombstoneKey();
+ --NumEntries;
+ ++NumTombstones;
+ return true;
+ }
+
+ ValueT &operator[](const KeyT &Key) {
+ BucketT *TheBucket;
+ if (LookupBucketFor(Key, TheBucket))
+ return TheBucket->second;
+
+ return InsertIntoBucket(Key, ValueT(), TheBucket)->second;
+ }
+
+private:
+ BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+ BucketT *TheBucket) {
+ // 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.
+ //
+ // The later case is tricky. For example, if we had one empty bucket with
+ // tons of tombstones, failing lookups (e.g. for insertion) would have to
+ // probe almost the entire table until it found the empty bucket. If the
+ // table completely filled with tombstones, no lookup would ever succeed,
+ // causing infinite loops in lookup.
+ if (NumEntries*4 >= NumBuckets*3 ||
+ NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+ this->grow();
+ LookupBucketFor(Key, TheBucket);
+ }
+ ++NumEntries;
+
+ // If we are writing over a tombstone, remember this.
+ if (TheBucket->first != getEmptyKey())
+ --NumTombstones;
+
+ TheBucket->first = Key;
+ new (&TheBucket->second) ValueT(Value);
+ return TheBucket;
+ }
+
+ static unsigned getHashValue(const KeyT &Val) {
+ return KeyInfoT::getHashValue(Val);
+ }
+ static const KeyT getEmptyKey() {
+ return KeyInfoT::getEmptyKey();
+ }
+ static const KeyT getTombstoneKey() {
+ return KeyInfoT::getTombstoneKey();
+ }
+
+ /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+ /// FoundBucket. If the bucket contains the key and a value, this returns
+ /// true, otherwise it returns a bucket with an empty marker or tombstone and
+ /// returns false.
+ bool LookupBucketFor(const KeyT &Val, BucketT *&FoundBucket) const {
+ unsigned BucketNo = getHashValue(Val);
+ unsigned ProbeAmt = 1;
+ BucketT *BucketsPtr = Buckets;
+
+ // FoundTombstone - Keep track of whether we find a tombstone while probing.
+ BucketT *FoundTombstone = 0;
+ const KeyT EmptyKey = getEmptyKey();
+ const KeyT TombstoneKey = getTombstoneKey();
+ assert(Val != EmptyKey && Val != TombstoneKey &&
+ "Empty/Tombstone value shouldn't be inserted into map!");
+
+ while (1) {
+ BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+ // Found Val's bucket? If so, return it.
+ if (ThisBucket->first == Val) {
+ FoundBucket = ThisBucket;
+ return true;
+ }
+
+ // If we found an empty bucket, the key doesn't exist in the set.
+ // Insert it and return the default value.
+ if (ThisBucket->first == EmptyKey) {
+ // If we've already seen a tombstone while probing, fill it in instead
+ // of the empty bucket we eventually probed to.
+ if (FoundTombstone) ThisBucket = FoundTombstone;
+ FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+ return false;
+ }
+
+ // If this is a tombstone, remember it. If Val ends up not in the map, we
+ // prefer to return it than something that would require more probing.
+ if (ThisBucket->first == TombstoneKey && !FoundTombstone)
+ FoundTombstone = ThisBucket; // Remember the first tombstone found.
+
+ // Otherwise, it's a hash collision or a tombstone, continue quadratic
+ // probing.
+ BucketNo += ProbeAmt++;
+ }
+ }
+
+ void init(unsigned InitBuckets) {
+ NumEntries = 0;
+ NumTombstones = 0;
+ NumBuckets = InitBuckets;
+ assert(InitBuckets && (InitBuckets & InitBuckets-1) == 0 &&
+ "# initial buckets must be a power of two!");
+ Buckets = (BucketT*)new char[sizeof(BucketT)*InitBuckets];
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0; i != InitBuckets; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+ }
+
+ void grow() {
+ unsigned OldNumBuckets = NumBuckets;
+ BucketT *OldBuckets = Buckets;
+
+ // Double the number of buckets.
+ NumBuckets <<= 1;
+ NumTombstones = 0;
+ Buckets = (BucketT*)new char[sizeof(BucketT)*NumBuckets];
+
+ // Initialize all the keys to EmptyKey.
+ const KeyT EmptyKey = getEmptyKey();
+ for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+ new (&Buckets[i].first) KeyT(EmptyKey);
+
+ // Insert all the old elements.
+ const KeyT TombstoneKey = getTombstoneKey();
+ for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+ if (B->first != EmptyKey && B->first != TombstoneKey) {
+ // Insert the key/value into the new table.
+ BucketT *DestBucket;
+ bool FoundVal = LookupBucketFor(B->first, DestBucket);
+ FoundVal = FoundVal; // silence warning.
+ assert(!FoundVal && "Key already in new map?");
+ DestBucket->first = B->first;
+ new (&DestBucket->second) ValueT(B->second);
+
+ // Free the value.
+ B->second.~ValueT();
+ }
+ B->first.~KeyT();
+ }
+
+ // Free the old table.
+ delete[] (char*)OldBuckets;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT>
+class DenseMapIterator {
+ typedef std::pair<KeyT, ValueT> BucketT;
+protected:
+ const BucketT *Ptr, *End;
+public:
+ DenseMapIterator(const BucketT *Pos, const BucketT *E) : Ptr(Pos), End(E) {
+ AdvancePastEmptyBuckets();
+ }
+
+ std::pair<KeyT, ValueT> &operator*() const {
+ return *const_cast<BucketT*>(Ptr);
+ }
+ std::pair<KeyT, ValueT> *operator->() const {
+ return const_cast<BucketT*>(Ptr);
+ }
+
+ bool operator==(const DenseMapIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const DenseMapIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline DenseMapIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ DenseMapIterator operator++(int) { // Postincrement
+ DenseMapIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ const KeyT Empty = KeyInfoT::getEmptyKey();
+ const KeyT Tombstone = KeyInfoT::getTombstoneKey();
+
+ while (Ptr != End && (Ptr->first == Empty || Ptr->first == Tombstone))
+ ++Ptr;
+ }
+};
+
+template<typename KeyT, typename ValueT, typename KeyInfoT>
+class DenseMapConstIterator : public DenseMapIterator<KeyT, ValueT, KeyInfoT> {
+public:
+ DenseMapConstIterator(const std::pair<KeyT, ValueT> *Pos,
+ const std::pair<KeyT, ValueT> *E)
+ : DenseMapIterator<KeyT, ValueT, KeyInfoT>(Pos, E) {
+ }
+ const std::pair<KeyT, ValueT> &operator*() const {
+ return *this->Ptr;
+ }
+ const std::pair<KeyT, ValueT> *operator->() const {
+ return this->Ptr;
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/DepthFirstIterator.h b/include/llvm/ADT/DepthFirstIterator.h
new file mode 100644
index 0000000..0cdd79b
--- /dev/null
+++ b/include/llvm/ADT/DepthFirstIterator.h
@@ -0,0 +1,232 @@
+//===- llvm/ADT/DepthFirstIterator.h - Depth First iterator -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build generic depth
+// first graph iterator. This file exposes the following functions/types:
+//
+// df_begin/df_end/df_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+//
+// idf_begin/idf_end/idf_iterator
+// * Depth-first iteration on the 'inverse' graph.
+//
+// df_ext_begin/df_ext_end/df_ext_iterator
+// * Normal depth-first iteration - visit a node and then all of its children.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+// idf_ext_begin/idf_ext_end/idf_ext_iterator
+// * Depth-first iteration on the 'inverse' graph.
+// This iterator stores the 'visited' set in an external set, which allows
+// it to be more efficient, and allows external clients to use the set for
+// other purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_DEPTHFIRSTITERATOR_H
+#define LLVM_ADT_DEPTHFIRSTITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <vector>
+#include <set>
+
+namespace llvm {
+
+// df_iterator_storage - A private class which is used to figure out where to
+// store the visited set.
+template<class SetType, bool External> // Non-external set
+class df_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class df_iterator_storage<SetType, true> {
+public:
+ df_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ df_iterator_storage(const df_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+
+// Generic Depth First Iterator
+template<class GraphT,
+class SetType = llvm::SmallPtrSet<typename GraphTraits<GraphT>::NodeType*, 8>,
+ bool ExtStorage = false, class GT = GraphTraits<GraphT> >
+class df_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public df_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is node pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+private:
+ inline df_iterator(NodeType *Node) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ inline df_iterator() { /* End is when stack is empty */ }
+
+ inline df_iterator(NodeType *Node, SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ if (!S.count(Node)) {
+ this->Visited.insert(Node);
+ VisitStack.push_back(std::make_pair(Node, GT::child_begin(Node)));
+ }
+ }
+ inline df_iterator(SetType &S)
+ : df_iterator_storage<SetType, ExtStorage>(S) {
+ // End is when stack is empty
+ }
+
+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(GraphT G) {
+ return _Self(GT::getEntryNode(G));
+ }
+ static inline _Self end(GraphT G) { return _Self(); }
+
+ // Static begin and end methods as our public ctors for external iterators
+ static inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end(GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack.size() == x.VisitStack.size() &&
+ VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline 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 Node, because
+ // the contained type is a pointer. This allows BBIt->getTerminator() f.e.
+ //
+ inline NodeType *operator->() const { return operator*(); }
+
+ inline _Self& operator++() { // Preincrement
+ do {
+ std::pair<NodeType *, ChildItTy> &Top = VisitStack.back();
+ NodeType *Node = Top.first;
+ ChildItTy &It = Top.second;
+
+ while (It != GT::child_end(Node)) {
+ NodeType *Next = *It++;
+ if (!this->Visited.count(Next)) { // Has our next sibling been visited?
+ // No, do it now.
+ this->Visited.insert(Next);
+ VisitStack.push_back(std::make_pair(Next, GT::child_begin(Next)));
+ return *this;
+ }
+ }
+
+ // Oops, ran out of successors... go up a level on the stack.
+ VisitStack.pop_back();
+ } while (!VisitStack.empty());
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self 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 {
+ return this->Visited.count(Node) != 0;
+ }
+};
+
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+df_iterator<T> df_begin(T G) {
+ return df_iterator<T>::begin(G);
+}
+
+template <class T>
+df_iterator<T> df_end(T G) {
+ return df_iterator<T>::end(G);
+}
+
+// Provide global definitions of external depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct df_ext_iterator : public df_iterator<T, SetTy, true> {
+ df_ext_iterator(const df_iterator<T, SetTy, true> &V)
+ : df_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_begin(T G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+df_ext_iterator<T, SetTy> df_ext_end(T G, SetTy &S) {
+ return df_ext_iterator<T, SetTy>::end(G, S);
+}
+
+
+// Provide global definitions of inverse depth first iterators...
+template <class T,
+ class SetTy = llvm::SmallPtrSet<typename GraphTraits<T>::NodeType*, 8>,
+ bool External = false>
+struct idf_iterator : public df_iterator<Inverse<T>, SetTy, External> {
+ idf_iterator(const df_iterator<Inverse<T>, SetTy, External> &V)
+ : df_iterator<Inverse<T>, SetTy, External>(V) {}
+};
+
+template <class T>
+idf_iterator<T> idf_begin(T G) {
+ return idf_iterator<T>::begin(G);
+}
+
+template <class T>
+idf_iterator<T> idf_end(T G){
+ return idf_iterator<T>::end(G);
+}
+
+// Provide global definitions of external inverse depth first iterators...
+template <class T, class SetTy = std::set<typename GraphTraits<T>::NodeType*> >
+struct idf_ext_iterator : public idf_iterator<T, SetTy, true> {
+ idf_ext_iterator(const idf_iterator<T, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+ idf_ext_iterator(const df_iterator<Inverse<T>, SetTy, true> &V)
+ : idf_iterator<T, SetTy, true>(V) {}
+};
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_begin(T G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::begin(G, S);
+}
+
+template <class T, class SetTy>
+idf_ext_iterator<T, SetTy> idf_ext_end(T G, SetTy &S) {
+ return idf_ext_iterator<T, SetTy>::end(G, S);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/EquivalenceClasses.h b/include/llvm/ADT/EquivalenceClasses.h
new file mode 100644
index 0000000..7d305cb
--- /dev/null
+++ b/include/llvm/ADT/EquivalenceClasses.h
@@ -0,0 +1,279 @@
+//===-- llvm/ADT/EquivalenceClasses.h - Generic Equiv. Classes --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Generic implementation of equivalence classes through the use Tarjan's
+// efficient union-find algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_EQUIVALENCECLASSES_H
+#define LLVM_ADT_EQUIVALENCECLASSES_H
+
+#include "llvm/ADT/iterator"
+#include "llvm/Support/DataTypes.h"
+#include <set>
+
+namespace llvm {
+
+/// EquivalenceClasses - This represents a collection of equivalence classes and
+/// supports three efficient operations: insert an element into a class of its
+/// own, union two classes, and find the class for a given element. In
+/// addition to these modification methods, it is possible to iterate over all
+/// of the equivalence classes and all of the elements in a class.
+///
+/// This implementation is an efficient implementation that only stores one copy
+/// of the element being indexed per entry in the set, and allows any arbitrary
+/// type to be indexed (as long as it can be ordered with operator<).
+///
+/// Here is a simple example using integers:
+///
+/// EquivalenceClasses<int> EC;
+/// EC.unionSets(1, 2); // insert 1, 2 into the same set
+/// EC.insert(4); EC.insert(5); // insert 4, 5 into own sets
+/// EC.unionSets(5, 1); // merge the set for 1 with 5's set.
+///
+/// for (EquivalenceClasses<int>::iterator I = EC.begin(), E = EC.end();
+/// I != E; ++I) { // Iterate over all of the equivalence sets.
+/// if (!I->isLeader()) continue; // Ignore non-leader sets.
+/// for (EquivalenceClasses<int>::member_iterator MI = EC.member_begin(I);
+/// MI != EC.member_end(); ++MI) // Loop over members in this set.
+/// cerr << *MI << " "; // Print member.
+/// cerr << "\n"; // Finish set.
+/// }
+///
+/// This example prints:
+/// 4
+/// 5 1 2
+///
+template <class ElemTy>
+class EquivalenceClasses {
+ /// ECValue - The EquivalenceClasses data structure is just a set of these.
+ /// Each of these represents a relation for a value. First it stores the
+ /// value itself, which provides the ordering that the set queries. Next, it
+ /// provides a "next pointer", which is used to enumerate all of the elements
+ /// in the unioned set. Finally, it defines either a "end of list pointer" or
+ /// "leader pointer" depending on whether the value itself is a leader. A
+ /// "leader pointer" points to the node that is the leader for this element,
+ /// if the node is not a leader. A "end of list pointer" points to the last
+ /// node in the list of members of this list. Whether or not a node is a
+ /// leader is determined by a bit stolen from one of the pointers.
+ class ECValue {
+ friend class EquivalenceClasses;
+ mutable const ECValue *Leader, *Next;
+ ElemTy Data;
+ // ECValue ctor - Start out with EndOfList pointing to this node, Next is
+ // Null, isLeader = true.
+ ECValue(const ElemTy &Elt)
+ : Leader(this), Next((ECValue*)(intptr_t)1), Data(Elt) {}
+
+ const ECValue *getLeader() const {
+ if (isLeader()) return this;
+ if (Leader->isLeader()) return Leader;
+ // Path compression.
+ return Leader = Leader->getLeader();
+ }
+ const ECValue *getEndOfList() const {
+ assert(isLeader() && "Cannot get the end of a list for a non-leader!");
+ return Leader;
+ }
+
+ void setNext(const ECValue *NewNext) const {
+ assert(getNext() == 0 && "Already has a next pointer!");
+ Next = (const ECValue*)((intptr_t)NewNext | (intptr_t)isLeader());
+ }
+ public:
+ ECValue(const ECValue &RHS) : Leader(this), Next((ECValue*)(intptr_t)1),
+ Data(RHS.Data) {
+ // Only support copying of singleton nodes.
+ assert(RHS.isLeader() && RHS.getNext() == 0 && "Not a singleton!");
+ }
+
+ bool operator<(const ECValue &UFN) const { return Data < UFN.Data; }
+
+ bool isLeader() const { return (intptr_t)Next & 1; }
+ const ElemTy &getData() const { return Data; }
+
+ const ECValue *getNext() const {
+ return (ECValue*)((intptr_t)Next & ~(intptr_t)1);
+ }
+
+ template<typename T>
+ bool operator<(const T &Val) const { return Data < Val; }
+ };
+
+ /// TheMapping - This implicitly provides a mapping from ElemTy values to the
+ /// ECValues, it just keeps the key as part of the value.
+ std::set<ECValue> TheMapping;
+
+public:
+ EquivalenceClasses() {}
+ EquivalenceClasses(const EquivalenceClasses &RHS) {
+ operator=(RHS);
+ }
+
+ const EquivalenceClasses &operator=(const EquivalenceClasses &RHS) {
+ TheMapping.clear();
+ for (iterator I = RHS.begin(), E = RHS.end(); I != E; ++I)
+ if (I->isLeader()) {
+ member_iterator MI = RHS.member_begin(I);
+ member_iterator LeaderIt = member_begin(insert(*MI));
+ for (++MI; MI != member_end(); ++MI)
+ unionSets(LeaderIt, member_begin(insert(*MI)));
+ }
+ return *this;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Inspection methods
+ //
+
+ /// iterator* - Provides a way to iterate over all values in the set.
+ typedef typename std::set<ECValue>::const_iterator iterator;
+ iterator begin() const { return TheMapping.begin(); }
+ iterator end() const { return TheMapping.end(); }
+
+ bool empty() const { return TheMapping.empty(); }
+
+ /// member_* Iterate over the members of an equivalence class.
+ ///
+ class member_iterator;
+ member_iterator member_begin(iterator I) const {
+ // Only leaders provide anything to iterate over.
+ return member_iterator(I->isLeader() ? &*I : 0);
+ }
+ member_iterator member_end() const {
+ return member_iterator(0);
+ }
+
+ /// findValue - Return an iterator to the specified value. If it does not
+ /// exist, end() is returned.
+ iterator findValue(const ElemTy &V) const {
+ return TheMapping.find(V);
+ }
+
+ /// getLeaderValue - Return the leader for the specified value that is in the
+ /// set. It is an error to call this method for a value that is not yet in
+ /// the set. For that, call getOrInsertLeaderValue(V).
+ const ElemTy &getLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(V);
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getOrInsertLeaderValue - Return the leader for the specified value that is
+ /// in the set. If the member is not in the set, it is inserted, then
+ /// returned.
+ const ElemTy &getOrInsertLeaderValue(const ElemTy &V) const {
+ member_iterator MI = findLeader(insert(V));
+ assert(MI != member_end() && "Value is not in the set!");
+ return *MI;
+ }
+
+ /// getNumClasses - Return the number of equivalence classes in this set.
+ /// Note that this is a linear time operation.
+ unsigned getNumClasses() const {
+ unsigned NC = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (I->isLeader()) ++NC;
+ return NC;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Mutation methods
+
+ /// insert - Insert a new value into the union/find set, ignoring the request
+ /// if the value already exists.
+ iterator insert(const ElemTy &Data) {
+ return TheMapping.insert(Data).first;
+ }
+
+ /// findLeader - Given a value in the set, return a member iterator for the
+ /// equivalence class it is in. This does the path-compression part that
+ /// makes union-find "union findy". This returns an end iterator if the value
+ /// is not in the equivalence class.
+ ///
+ member_iterator findLeader(iterator I) const {
+ if (I == TheMapping.end()) return member_end();
+ return member_iterator(I->getLeader());
+ }
+ member_iterator findLeader(const ElemTy &V) const {
+ return findLeader(TheMapping.find(V));
+ }
+
+
+ /// union - Merge the two equivalence sets for the specified values, inserting
+ /// them if they do not already exist in the equivalence set.
+ member_iterator unionSets(const ElemTy &V1, const ElemTy &V2) {
+ iterator V1I = insert(V1), V2I = insert(V2);
+ return unionSets(findLeader(V1I), findLeader(V2I));
+ }
+ member_iterator unionSets(member_iterator L1, member_iterator L2) {
+ assert(L1 != member_end() && L2 != member_end() && "Illegal inputs!");
+ if (L1 == L2) return L1; // Unifying the same two sets, noop.
+
+ // Otherwise, this is a real union operation. Set the end of the L1 list to
+ // point to the L2 leader node.
+ const ECValue &L1LV = *L1.Node, &L2LV = *L2.Node;
+ L1LV.getEndOfList()->setNext(&L2LV);
+
+ // Update L1LV's end of list pointer.
+ L1LV.Leader = L2LV.getEndOfList();
+
+ // Clear L2's leader flag:
+ L2LV.Next = L2LV.getNext();
+
+ // L2's leader is now L1.
+ L2LV.Leader = &L1LV;
+ return L1;
+ }
+
+ class member_iterator : public forward_iterator<ElemTy, ptrdiff_t> {
+ typedef forward_iterator<const ElemTy, ptrdiff_t> super;
+ const ECValue *Node;
+ friend class EquivalenceClasses;
+ public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+
+ explicit member_iterator() {}
+ explicit member_iterator(const ECValue *N) : Node(N) {}
+ member_iterator(const member_iterator &I) : Node(I.Node) {}
+
+ reference operator*() const {
+ assert(Node != 0 && "Dereferencing end()!");
+ return Node->getData();
+ }
+ reference operator->() const { return operator*(); }
+
+ member_iterator &operator++() {
+ assert(Node != 0 && "++'d off the end of the list!");
+ Node = Node->getNext();
+ return *this;
+ }
+
+ member_iterator operator++(int) { // postincrement operators.
+ member_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ bool operator==(const member_iterator &RHS) const {
+ return Node == RHS.Node;
+ }
+ bool operator!=(const member_iterator &RHS) const {
+ return Node != RHS.Node;
+ }
+ };
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/FoldingSet.h b/include/llvm/ADT/FoldingSet.h
new file mode 100644
index 0000000..e6ded76
--- /dev/null
+++ b/include/llvm/ADT/FoldingSet.h
@@ -0,0 +1,258 @@
+//===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a hash set that can be used to remove duplication of nodes
+// in a graph. This code was originally created by Chris Lattner for use with
+// SelectionDAGCSEMap, but was isolated to provide use across the llvm code set.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_FOLDINGSET_H
+#define LLVM_ADT_FOLDINGSET_H
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+
+namespace llvm {
+
+/// 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
+/// it, otherwise return the bucket it should be inserted into.
+/// 2. Given a node that has already been created, remove it from the set.
+///
+/// This class is implemented as a single-link chained hash table, where the
+/// "buckets" are actually the nodes themselves (the next pointer is in the
+/// node). The last node points back to the bucket to simplified node removal.
+///
+/// Any node that is to be included in the folding set must be a subclass of
+/// FoldingSetNode. The node class must also define a Profile method used to
+/// establish the unique bits of data for the node. The Profile method is
+/// passed a FoldingSetNodeID object which is used to gather the bits. Just
+/// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
+/// NOTE: That the folding set does not own the nodes and it is the
+/// responsibility of the user to dispose of the nodes.
+///
+/// Eg.
+/// class MyNode : public FoldingSetNode {
+/// private:
+/// std::string Name;
+/// unsigned Value;
+/// public:
+/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
+/// ...
+/// void Profile(FoldingSetNodeID &ID) {
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// }
+/// ...
+/// };
+///
+/// To define the folding set itself use the FoldingSet template;
+///
+/// Eg.
+/// FoldingSet<MyNode> MyFoldingSet;
+///
+/// Four public methods are available to manipulate the folding set;
+///
+/// 1) If you have an existing node that you want add to the set but unsure
+/// that the node might already exist then call;
+///
+/// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///
+/// If The result is equal to the input then the node has been inserted.
+/// Otherwise, the result is the node existing in the folding set, and the
+/// input can be discarded (use the result instead.)
+///
+/// 2) If you are ready to construct a node but want to check if it already
+/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
+/// check;
+///
+/// FoldingSetNodeID ID;
+/// ID.AddString(Name);
+/// ID.AddInteger(Value);
+/// void *InsertPoint;
+///
+/// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///
+/// If found then M with be non-NULL, else InsertPoint will point to where it
+/// should be inserted using InsertNode.
+///
+/// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
+/// node with FindNodeOrInsertPos;
+///
+/// InsertNode(N, InsertPoint);
+///
+/// 4) Finally, if you want to remove a node from the folding set call;
+///
+/// bool WasRemoved = RemoveNode(N);
+///
+/// The result indicates whether the node existed in the folding set.
+
+
+//===----------------------------------------------------------------------===//
+/// FoldingSetImpl - Implements the folding set functionality. The main
+/// structure is an array of buckets. Each bucket is indexed by the hash of
+/// the nodes it contains. The bucket itself points to the nodes contained
+/// in the bucket via a singly linked list. The last node in the list points
+/// back to the bucket to facilitate node removal.
+///
+class FoldingSetImpl {
+private:
+ /// Buckets - Array of bucket chains.
+ ///
+ void **Buckets;
+
+ /// NumBuckets - Length of the Buckets array. Always a power of 2.
+ ///
+ unsigned NumBuckets;
+
+ /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
+ /// is greater than twice the number of buckets.
+ unsigned NumNodes;
+
+public:
+ FoldingSetImpl(unsigned Log2InitSize = 6);
+ virtual ~FoldingSetImpl();
+
+ // Forward declaration.
+ class Node;
+
+ //===--------------------------------------------------------------------===//
+ /// NodeID - This class is used to gather all the unique data bits of a
+ /// node. When all the bits are gathered this class is used to produce a
+ /// hash value for the node.
+ ///
+ class NodeID {
+ /// Bits - Vector of all the data bits that make the node unique.
+ /// Use a SmallVector to avoid a heap allocation in the common case.
+ SmallVector<unsigned, 32> Bits;
+
+ public:
+ NodeID() {}
+
+ /// getRawData - Return the ith entry in the Bits data.
+ ///
+ unsigned getRawData(unsigned i) const {
+ return Bits[i];
+ }
+
+ /// Add* - Add various data types to Bit data.
+ ///
+ void AddPointer(const void *Ptr);
+ void AddInteger(signed I);
+ void AddInteger(unsigned I);
+ void AddInteger(uint64_t I);
+ void AddFloat(float F);
+ void AddDouble(double D);
+ void AddString(const std::string &String);
+
+ /// ComputeHash - Compute a strong hash value for this NodeID, used to
+ /// lookup the node in the FoldingSetImpl.
+ unsigned ComputeHash() const;
+
+ /// operator== - Used to compare two nodes to each other.
+ ///
+ bool operator==(const NodeID &RHS) const;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// Node - This class is used to maintain the singly linked bucket list in
+ /// a folding set.
+ ///
+ class Node {
+ private:
+ // NextInFoldingSetBucket - next link in the bucket list.
+ void *NextInFoldingSetBucket;
+
+ public:
+
+ Node() : NextInFoldingSetBucket(0) {}
+
+ // Accessors
+ void *getNextInBucket() const { return NextInFoldingSetBucket; }
+ void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
+ };
+
+ /// RemoveNode - Remove a node from the folding set, returning true if one
+ /// was removed or false if the node was not in the folding set.
+ bool RemoveNode(Node *N);
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and return
+ /// it instead.
+ Node *GetOrInsertNode(Node *N);
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ Node *FindNodeOrInsertPos(const NodeID &ID, void *&InsertPos);
+
+ /// InsertNode - Insert the specified node into the folding set, knowing that
+ /// it is not already in the folding set. InsertPos must be obtained from
+ /// FindNodeOrInsertPos.
+ void InsertNode(Node *N, void *InsertPos);
+
+private:
+
+ /// GrowHashTable - Double the size of the hash table and rehash everything.
+ ///
+ void GrowHashTable();
+
+protected:
+
+ /// GetNodeProfile - Instantiations of the FoldingSet template implement
+ /// this function to gather data bits for the given node.
+ virtual void GetNodeProfile(NodeID &ID, Node *N) const = 0;
+};
+
+// Convenience types to hide the implementation of the folding set.
+typedef FoldingSetImpl::Node FoldingSetNode;
+typedef FoldingSetImpl::NodeID FoldingSetNodeID;
+
+//===----------------------------------------------------------------------===//
+/// FoldingSet - This template class is used to instantiate a specialized
+/// 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 {
+private:
+ /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
+ /// way to convert nodes into a unique specifier.
+ virtual void GetNodeProfile(NodeID &ID, Node *N) const {
+ T *TN = static_cast<T *>(N);
+ TN->Profile(ID);
+ }
+
+public:
+ FoldingSet(unsigned Log2InitSize = 6)
+ : FoldingSetImpl(Log2InitSize)
+ {}
+
+ /// GetOrInsertNode - If there is an existing simple Node exactly
+ /// equal to the specified node, return it. Otherwise, insert 'N' and
+ /// return it instead.
+ T *GetOrInsertNode(Node *N) {
+ return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
+ }
+
+ /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
+ /// return it. If not, return the insertion token that will make insertion
+ /// faster.
+ T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
+ return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
+ }
+};
+
+} // End of namespace llvm.
+
+
+#endif
+
diff --git a/include/llvm/ADT/GraphTraits.h b/include/llvm/ADT/GraphTraits.h
new file mode 100644
index 0000000..99a69b8
--- /dev/null
+++ b/include/llvm/ADT/GraphTraits.h
@@ -0,0 +1,83 @@
+//===-- llvm/ADT/GraphTraits.h - Graph traits template ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the little GraphTraits<X> template class that should be
+// specialized by classes that want to be iteratable by generic graph iterators.
+//
+// This file also defines the marker class Inverse that is used to iterate over
+// graphs in a graph defined, inverse ordering...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_GRAPHTRAITS_H
+#define LLVM_ADT_GRAPHTRAITS_H
+
+namespace llvm {
+
+// GraphTraits - This class should be specialized by different graph types...
+// which is why the default version is empty.
+//
+template<class GraphType>
+struct GraphTraits {
+ // Elements to provide:
+
+ // typedef NodeType - Type of Node in the graph
+ // typedef ChildIteratorType - Type used to iterate over children in graph
+
+ // static NodeType *getEntryNode(GraphType *)
+ // Return the entry node of the graph
+
+ // static ChildIteratorType child_begin(NodeType *)
+ // static ChildIteratorType child_end (NodeType *)
+ // Return iterators that point to the beginning and ending of the child
+ // node list for the specified node.
+ //
+
+
+ // typedef ...iterator nodes_iterator;
+ // static nodes_iterator nodes_begin(GraphType *G)
+ // static nodes_iterator nodes_end (GraphType *G)
+ //
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+
+
+ // If anyone tries to use this class without having an appropriate
+ // specialization, make an error. If you get this error, it's because you
+ // need to include the appropriate specialization of GraphTraits<> for your
+ // graph, or you need to define it for a new graph type. Either that or
+ // your argument to XXX_begin(...) is unknown or needs to have the proper .h
+ // file #include'd.
+ //
+ typedef typename GraphType::UnknownGraphTypeError NodeType;
+};
+
+
+// Inverse - This class is used as a little marker class to tell the graph
+// iterator to iterate over the graph in a graph defined "Inverse" ordering.
+// Not all graphs define an inverse ordering, and if they do, it depends on
+// the graph exactly what that is. Here's an example of usage with the
+// df_iterator:
+//
+// idf_iterator<Method*> I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+// Which is equivalent to:
+// df_iterator<Inverse<Method*> > I = idf_begin(M), E = idf_end(M);
+// for (; I != E; ++I) { ... }
+//
+template <class GraphType>
+struct Inverse {
+ GraphType &Graph;
+
+ inline Inverse(GraphType &G) : Graph(G) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/HashExtras.h b/include/llvm/ADT/HashExtras.h
new file mode 100644
index 0000000..9993248
--- /dev/null
+++ b/include/llvm/ADT/HashExtras.h
@@ -0,0 +1,41 @@
+//===-- llvm/ADT/HashExtras.h - Useful functions for STL hash ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL Hashed containers.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASHEXTRAS_H
+#define LLVM_ADT_HASHEXTRAS_H
+
+#include "llvm/ADT/hash_map"
+#include <string>
+
+// Cannot specialize hash template from outside of the std namespace.
+namespace HASH_NAMESPACE {
+
+// Provide a hash function for arbitrary pointers...
+template <class T> struct hash<T *> {
+ inline size_t operator()(const T *Val) const {
+ return reinterpret_cast<size_t>(Val);
+ }
+};
+
+template <> struct hash<std::string> {
+ size_t operator()(std::string const &str) const {
+ return hash<char const *>()(str.c_str());
+ }
+};
+
+} // End namespace std
+
+#endif
diff --git a/include/llvm/ADT/IndexedMap.h b/include/llvm/ADT/IndexedMap.h
new file mode 100644
index 0000000..bc38fdd
--- /dev/null
+++ b/include/llvm/ADT/IndexedMap.h
@@ -0,0 +1,75 @@
+//===- llvm/ADT/IndexedMap.h - An index map implementation ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an indexed map. The index map template takes two
+// types. The first is the mapped type and the second is a functor
+// that maps its argument to a size_t. On instantiation a "null" value
+// can be provided to be used as a "does not exist" indicator in the
+// map. A member function grow() is provided that given the value of
+// the maximally indexed key (the argument of the functor) makes sure
+// the map has enough space for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_INDEXEDMAP_H
+#define LLVM_ADT_INDEXEDMAP_H
+
+#include <functional>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+
+ struct IdentityFunctor : std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Index) const {
+ return Index;
+ }
+ };
+
+ template <typename T, typename ToIndexT = IdentityFunctor>
+ class IndexedMap {
+ typedef typename ToIndexT::argument_type IndexT;
+ typedef std::vector<T> StorageT;
+ StorageT storage_;
+ T nullVal_;
+ ToIndexT toIndex_;
+
+ public:
+ IndexedMap() : nullVal_(T()) { }
+
+ explicit IndexedMap(const T& val) : nullVal_(val) { }
+
+ typename StorageT::reference operator[](IndexT n) {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ typename StorageT::const_reference operator[](IndexT n) const {
+ assert(toIndex_(n) < storage_.size() && "index out of bounds!");
+ return storage_[toIndex_(n)];
+ }
+
+ void clear() {
+ storage_.clear();
+ }
+
+ void grow(IndexT n) {
+ unsigned NewSize = toIndex_(n) + 1;
+ if (NewSize > storage_.size())
+ storage_.resize(NewSize, nullVal_);
+ }
+
+ typename StorageT::size_type size() const {
+ return storage_.size();
+ }
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/PostOrderIterator.h b/include/llvm/ADT/PostOrderIterator.h
new file mode 100644
index 0000000..16f0865
--- /dev/null
+++ b/include/llvm/ADT/PostOrderIterator.h
@@ -0,0 +1,230 @@
+//===- llvm/ADT/PostOrderIterator.h - PostOrder iterator --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file builds on the ADT/GraphTraits.h file to build a generic graph
+// post order iterator. This should work over any graph type that has a
+// GraphTraits specialization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_POSTORDERITERATOR_H
+#define LLVM_ADT_POSTORDERITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include <stack>
+#include <set>
+#include <vector>
+
+namespace llvm {
+
+template<class SetType, bool External> // Non-external set
+class po_iterator_storage {
+public:
+ SetType Visited;
+};
+
+template<class SetType>
+class po_iterator_storage<SetType, true> {
+public:
+ po_iterator_storage(SetType &VSet) : Visited(VSet) {}
+ po_iterator_storage(const po_iterator_storage &S) : Visited(S.Visited) {}
+ SetType &Visited;
+};
+
+template<class GraphT,
+ class SetType = std::set<typename GraphTraits<GraphT>::NodeType*>,
+ bool ExtStorage = false,
+ class GT = GraphTraits<GraphT> >
+class po_iterator : public forward_iterator<typename GT::NodeType, ptrdiff_t>,
+ public po_iterator_storage<SetType, ExtStorage> {
+ typedef forward_iterator<typename GT::NodeType, ptrdiff_t> super;
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::stack<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ void traverseChild() {
+ while (VisitStack.top().second != GT::child_end(VisitStack.top().first)) {
+ NodeType *BB = *VisitStack.top().second++;
+ if (!this->Visited.count(BB)) { // If the block is not visited...
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ }
+ }
+ }
+
+ inline po_iterator(NodeType *BB) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ inline po_iterator() {} // End is when stack is empty.
+
+ inline po_iterator(NodeType *BB, SetType &S) :
+ po_iterator_storage<SetType, ExtStorage>(&S) {
+ if(!S.count(BB)) {
+ this->Visited.insert(BB);
+ VisitStack.push(std::make_pair(BB, GT::child_begin(BB)));
+ traverseChild();
+ }
+ }
+
+ inline 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 inline _Self begin(GraphT G, SetType &S) {
+ return _Self(GT::getEntryNode(G), S);
+ }
+ static inline _Self end (GraphT G, SetType &S) { return _Self(S); }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ return VisitStack.top().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*(); }
+
+ inline _Self& operator++() { // Preincrement
+ VisitStack.pop();
+ if (!VisitStack.empty())
+ traverseChild();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+// Provide global constructors that automatically figure out correct types...
+//
+template <class T>
+po_iterator<T> po_begin(T G) { return po_iterator<T>::begin(G); }
+template <class T>
+po_iterator<T> po_end (T G) { return po_iterator<T>::end(G); }
+
+// Provide global definitions of external postorder iterators...
+template<class T, class SetType=std::set<typename GraphTraits<T>::NodeType*> >
+struct po_ext_iterator : public po_iterator<T, SetType, true> {
+ po_ext_iterator(const po_iterator<T, SetType, true> &V) :
+ po_iterator<T, SetType, true>(V) {}
+};
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_begin(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template<class T, class SetType>
+po_ext_iterator<T, SetType> po_ext_end(T G, SetType &S) {
+ return po_ext_iterator<T, SetType>::end(G, S);
+}
+
+// Provide global definitions of inverse post order iterators...
+template <class T,
+ class SetType = std::set<typename GraphTraits<T>::NoddeType*>,
+ bool External = false>
+struct ipo_iterator : public po_iterator<Inverse<T>, SetType, External > {
+ ipo_iterator(const po_iterator<Inverse<T>, SetType, External> &V) :
+ po_iterator<Inverse<T>, SetType, External> (V) {}
+};
+
+template <class T>
+ipo_iterator<T> ipo_begin(T G, bool Reverse = false) {
+ return ipo_iterator<T>::begin(G, Reverse);
+}
+
+template <class T>
+ipo_iterator<T> ipo_end(T G){
+ return ipo_iterator<T>::end(G);
+}
+
+//Provide global definitions of external inverse postorder iterators...
+template <class T, class SetType = std::set<typename GraphTraits<T>::NodeType*> >
+struct ipo_ext_iterator : public ipo_iterator<T, SetType, true> {
+ ipo_ext_iterator(const ipo_iterator<T, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+ ipo_ext_iterator(const po_iterator<Inverse<T>, SetType, true> &V) :
+ ipo_iterator<T, SetType, true>(&V) {}
+};
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_begin(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::begin(G, S);
+}
+
+template <class T, class SetType>
+ipo_ext_iterator<T, SetType> ipo_ext_end(T G, SetType &S) {
+ return ipo_ext_iterator<T, SetType>::end(G, S);
+}
+
+//===--------------------------------------------------------------------===//
+// Reverse Post Order CFG iterator code
+//===--------------------------------------------------------------------===//
+//
+// This is used to visit basic blocks in a method in reverse post order. This
+// class is awkward to use because I don't know a good incremental algorithm to
+// computer RPO from a graph. Because of this, the construction of the
+// ReversePostOrderTraversal object is expensive (it must walk the entire graph
+// with a postorder iterator to build the data structures). The moral of this
+// story is: Don't create more ReversePostOrderTraversal classes than necessary.
+//
+// This class should be used like this:
+// {
+// ReversePostOrderTraversal<Function*> RPOT(FuncPtr); // Expensive to create
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// for (rpo_iterator I = RPOT.begin(); I != RPOT.end(); ++I) {
+// ...
+// }
+// }
+//
+
+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) {
+ copy(po_begin(BB), po_end(BB), back_inserter(Blocks));
+ }
+public:
+ typedef typename std::vector<NodeType*>::reverse_iterator rpo_iterator;
+
+ inline 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(); }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SCCIterator.h b/include/llvm/ADT/SCCIterator.h
new file mode 100644
index 0000000..6b1260d
--- /dev/null
+++ b/include/llvm/ADT/SCCIterator.h
@@ -0,0 +1,199 @@
+//===-- Support/SCCIterator.h - Strongly Connected Comp. Iter. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected
+// components (SCCs) of a graph in O(N+E) time using Tarjan's DFS algorithm.
+//
+// The SCC iterator has the important property that if a node in SCC S1 has an
+// edge to a node in SCC S2, then it visits S1 *after* S2.
+//
+// To visit S1 *before* S2, use the scc_iterator on the Inverse graph.
+// (NOTE: This requires some simple wrappers and is not supported yet.)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SCCITERATOR_H
+#define LLVM_ADT_SCCITERATOR_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include <vector>
+#include <map>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// scc_iterator - Enumerate the SCCs of a directed graph, in
+/// reverse topological order of the SCC DAG.
+///
+template<class GraphT, class GT = GraphTraits<GraphT> >
+class scc_iterator
+ : public forward_iterator<std::vector<typename GT::NodeType>, ptrdiff_t> {
+ typedef typename GT::NodeType NodeType;
+ typedef typename GT::ChildIteratorType ChildItTy;
+ typedef std::vector<NodeType*> SccTy;
+ typedef forward_iterator<SccTy, ptrdiff_t> super;
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ // The visit counters used to detect when a complete SCC is on the stack.
+ // visitNum is the global counter.
+ // nodeVisitNumbers are per-node visit numbers, also used as DFS flags.
+ unsigned visitNum;
+ std::map<NodeType *, unsigned> nodeVisitNumbers;
+
+ // SCCNodeStack - Stack holding nodes of the SCC.
+ std::vector<NodeType *> SCCNodeStack;
+
+ // CurrentSCC - The current SCC, retrieved using operator*().
+ SccTy CurrentSCC;
+
+ // VisitStack - Used to maintain the ordering. Top = current block
+ // First element is basic block pointer, second is the 'next child' to visit
+ std::vector<std::pair<NodeType *, ChildItTy> > VisitStack;
+
+ // MinVistNumStack - Stack holding the "min" values for each node in the DFS.
+ // This is used to track the minimum uplink values for all children of
+ // the corresponding node on the VisitStack.
+ std::vector<unsigned> MinVisitNumStack;
+
+ // A single "visit" within the non-recursive DFS traversal.
+ void DFSVisitOne(NodeType* N) {
+ ++visitNum; // Global counter for the visit order
+ nodeVisitNumbers[N] = visitNum;
+ SCCNodeStack.push_back(N);
+ MinVisitNumStack.push_back(visitNum);
+ VisitStack.push_back(std::make_pair(N, GT::child_begin(N)));
+ //DOUT << "TarjanSCC: Node " << N <<
+ // " : visitNum = " << visitNum << "\n";
+ }
+
+ // The stack-based DFS traversal; defined below.
+ void DFSVisitChildren() {
+ assert(!VisitStack.empty());
+ while (VisitStack.back().second != GT::child_end(VisitStack.back().first)) {
+ // TOS has at least one more child so continue DFS
+ NodeType *childN = *VisitStack.back().second++;
+ if (!nodeVisitNumbers.count(childN)) {
+ // this node has never been seen
+ DFSVisitOne(childN);
+ } else {
+ unsigned childNum = nodeVisitNumbers[childN];
+ if (MinVisitNumStack.back() > childNum)
+ MinVisitNumStack.back() = childNum;
+ }
+ }
+ }
+
+ // Compute the next SCC using the DFS traversal.
+ void GetNextSCC() {
+ assert(VisitStack.size() == MinVisitNumStack.size());
+ CurrentSCC.clear(); // Prepare to compute the next SCC
+ while (!VisitStack.empty()) {
+ DFSVisitChildren();
+ assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
+ NodeType* visitingN = VisitStack.back().first;
+ unsigned minVisitNum = MinVisitNumStack.back();
+ VisitStack.pop_back();
+ MinVisitNumStack.pop_back();
+ if (!MinVisitNumStack.empty() && MinVisitNumStack.back() > minVisitNum)
+ MinVisitNumStack.back() = minVisitNum;
+
+ //DOUT << "TarjanSCC: Popped node " << visitingN <<
+ // " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
+ // nodeVisitNumbers[visitingN] << "\n";
+
+ if (minVisitNum == nodeVisitNumbers[visitingN]) {
+ // A full SCC is on the SCCNodeStack! It includes all nodes below
+ // visitingN on the stack. Copy those nodes to CurrentSCC,
+ // reset their minVisit values, and return (this suspends
+ // the DFS traversal till the next ++).
+ do {
+ CurrentSCC.push_back(SCCNodeStack.back());
+ SCCNodeStack.pop_back();
+ nodeVisitNumbers[CurrentSCC.back()] = ~0U;
+ } while (CurrentSCC.back() != visitingN);
+ return;
+ }
+ }
+ }
+
+ inline scc_iterator(NodeType *entryN) : visitNum(0) {
+ DFSVisitOne(entryN);
+ GetNextSCC();
+ }
+ inline scc_iterator() { /* End is when DFS stack is empty */ }
+
+public:
+ typedef scc_iterator<GraphT, GT> _Self;
+
+ // Provide static "constructors"...
+ static inline _Self begin(GraphT& G) { return _Self(GT::getEntryNode(G)); }
+ static inline _Self end (GraphT& G) { return _Self(); }
+
+ // Direct loop termination test (I.fini() is more efficient than I == end())
+ inline bool fini() const {
+ assert(!CurrentSCC.empty() || VisitStack.empty());
+ return CurrentSCC.empty();
+ }
+
+ inline bool operator==(const _Self& x) const {
+ return VisitStack == x.VisitStack && CurrentSCC == x.CurrentSCC;
+ }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // Iterator traversal: forward iteration only
+ inline _Self& operator++() { // Preincrement
+ GetNextSCC();
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a reference to the current SCC
+ inline const SccTy &operator*() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+ inline SccTy &operator*() {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ return CurrentSCC;
+ }
+
+ // hasLoop() -- Test if the current SCC has a loop. If it has more than one
+ // node, this is trivially true. If not, it may still contain a loop if the
+ // node has an edge back to itself.
+ bool hasLoop() const {
+ assert(!CurrentSCC.empty() && "Dereferencing END SCC iterator!");
+ if (CurrentSCC.size() > 1) return true;
+ NodeType *N = CurrentSCC.front();
+ for (ChildItTy CI = GT::child_begin(N), CE=GT::child_end(N); CI != CE; ++CI)
+ if (*CI == N)
+ return true;
+ return false;
+ }
+};
+
+
+// Global constructor for the SCC iterator.
+template <class T>
+scc_iterator<T> scc_begin(T G) {
+ return scc_iterator<T>::begin(G);
+}
+
+template <class T>
+scc_iterator<T> scc_end(T G) {
+ return scc_iterator<T>::end(G);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/STLExtras.h b/include/llvm/ADT/STLExtras.h
new file mode 100644
index 0000000..14137e3
--- /dev/null
+++ b/include/llvm/ADT/STLExtras.h
@@ -0,0 +1,204 @@
+//===- llvm/ADT/STLExtras.h - Useful STL related functions ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some templates that are useful if you are working with the
+// STL at all.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STLEXTRAS_H
+#define LLVM_ADT_STLEXTRAS_H
+
+#include <functional>
+#include <utility> // for std::pair
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <functional>
+//===----------------------------------------------------------------------===//
+
+template<class Ty>
+struct greater_ptr : public std::binary_function<Ty, Ty, bool> {
+ bool operator()(const Ty* left, const Ty* right) const {
+ return *right < *left;
+ }
+};
+
+// deleter - Very very very simple method that is used to invoke operator
+// delete on something. It is used like this:
+//
+// for_each(V.begin(), B.end(), deleter<Interval>);
+//
+template <class T>
+static inline void deleter(T *Ptr) {
+ delete Ptr;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <iterator>
+//===----------------------------------------------------------------------===//
+
+// mapped_iterator - This is a simple iterator adapter that causes a function to
+// be dereferenced whenever operator* is invoked on the iterator.
+//
+template <class RootIt, class UnaryFunc>
+class mapped_iterator {
+ RootIt current;
+ UnaryFunc Fn;
+public:
+ typedef typename std::iterator_traits<RootIt>::iterator_category
+ iterator_category;
+ typedef typename std::iterator_traits<RootIt>::difference_type
+ difference_type;
+ typedef typename UnaryFunc::result_type value_type;
+
+ typedef void pointer;
+ //typedef typename UnaryFunc::result_type *pointer;
+ 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 explicit mapped_iterator(const RootIt &I, UnaryFunc F)
+ : current(I), Fn(F) {}
+ inline mapped_iterator(const mapped_iterator &It)
+ : current(It.current), Fn(It.Fn) {}
+
+ inline value_type operator*() const { // All this work to do this
+ 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); }
+ _Self& operator+= (difference_type n) { current += n; return *this; }
+ _Self operator- (difference_type n) const { return _Self(current - n); }
+ _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; }
+
+ inline difference_type operator-(const _Self &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);
+}
+
+
+// map_iterator - Provide a convenient way to create mapped_iterators, just like
+// make_pair is useful for creating pairs...
+//
+template <class ItTy, class FuncTy>
+inline mapped_iterator<ItTy, FuncTy> map_iterator(const ItTy &I, FuncTy F) {
+ return mapped_iterator<ItTy, FuncTy>(I, F);
+}
+
+
+// next/prior - These functions unlike std::advance do not modify the
+// passed iterator but return a copy.
+//
+// next(myIt) returns copy of myIt incremented once
+// next(myIt, n) returns copy of myIt incremented n times
+// prior(myIt) returns copy of myIt decremented once
+// prior(myIt, n) returns copy of myIt decremented n times
+
+template <typename ItTy, typename Dist>
+inline ItTy next(ItTy it, Dist n)
+{
+ std::advance(it, n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy next(ItTy it)
+{
+ std::advance(it, 1);
+ return it;
+}
+
+template <typename ItTy, typename Dist>
+inline ItTy prior(ItTy it, Dist n)
+{
+ std::advance(it, -n);
+ return it;
+}
+
+template <typename ItTy>
+inline ItTy prior(ItTy it)
+{
+ std::advance(it, -1);
+ return it;
+}
+
+//===----------------------------------------------------------------------===//
+// Extra additions to <utility>
+//===----------------------------------------------------------------------===//
+
+// tie - this function ties two objects and returns a temporary object
+// that is assignable from a std::pair. This can be used to make code
+// more readable when using values returned from functions bundled in
+// a std::pair. Since an example is worth 1000 words:
+//
+// typedef std::map<int, int> Int2IntMap;
+//
+// Int2IntMap myMap;
+// Int2IntMap::iterator where;
+// bool inserted;
+// tie(where, inserted) = myMap.insert(std::make_pair(123,456));
+//
+// if (inserted)
+// // do stuff
+// else
+// // do other stuff
+
+namespace
+{
+ template <typename T1, typename T2>
+ struct tier {
+ typedef T1 &first_type;
+ typedef T2 &second_type;
+
+ first_type first;
+ second_type second;
+
+ tier(first_type f, second_type s) : first(f), second(s) { }
+ tier& operator=(const std::pair<T1, T2>& p) {
+ first = p.first;
+ second = p.second;
+ return *this;
+ }
+ };
+}
+
+template <typename T1, typename T2>
+inline tier<T1, T2> tie(T1& f, T2& s) {
+ return tier<T1, T2>(f, s);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SetOperations.h b/include/llvm/ADT/SetOperations.h
new file mode 100644
index 0000000..c37d1e7
--- /dev/null
+++ b/include/llvm/ADT/SetOperations.h
@@ -0,0 +1,71 @@
+//===-- llvm/ADT/SetOperations.h - Generic Set Operations -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines generic set operations that may be used on set's of
+// different types, and different element types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETOPERATIONS_H
+#define LLVM_ADT_SETOPERATIONS_H
+
+namespace llvm {
+
+/// set_union(A, B) - Compute A := A u B, return whether A changed.
+///
+template <class S1Ty, class S2Ty>
+bool set_union(S1Ty &S1, const S2Ty &S2) {
+ bool Changed = false;
+
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ if (S1.insert(*SI).second)
+ Changed = true;
+
+ return Changed;
+}
+
+/// set_intersect(A, B) - Compute A := A ^ B
+/// Identical to set_intersection, except that it works on set<>'s and
+/// is nicer to use. Functionally, this iterates through S1, removing
+/// elements that are not contained in S2.
+///
+template <class S1Ty, class S2Ty>
+void set_intersect(S1Ty &S1, const S2Ty &S2) {
+ for (typename S1Ty::iterator I = S1.begin(); I != S1.end();) {
+ const typename S1Ty::key_type &E = *I;
+ ++I;
+ if (!S2.count(E)) S1.erase(E); // Erase element if not in S2
+ }
+}
+
+/// set_difference(A, B) - Return A - B
+///
+template <class S1Ty, class S2Ty>
+S1Ty set_difference(const S1Ty &S1, const S2Ty &S2) {
+ S1Ty Result;
+ for (typename S1Ty::const_iterator SI = S1.begin(), SE = S1.end();
+ SI != SE; ++SI)
+ if (!S2.count(*SI)) // if the element is not in set2
+ Result.insert(*SI);
+ return Result;
+}
+
+/// set_subtract(A, B) - Compute A := A - B
+///
+template <class S1Ty, class S2Ty>
+void set_subtract(S1Ty &S1, const S2Ty &S2) {
+ for (typename S2Ty::const_iterator SI = S2.begin(), SE = S2.end();
+ SI != SE; ++SI)
+ S1.erase(*SI);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/SetVector.h b/include/llvm/ADT/SetVector.h
new file mode 100644
index 0000000..7675534
--- /dev/null
+++ b/include/llvm/ADT/SetVector.h
@@ -0,0 +1,168 @@
+//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a set that has insertion order iteration
+// characteristics. This is useful for keeping a set of things that need to be
+// visited later but in a deterministic order (insertion order). The interface
+// is purposefully minimal.
+//
+// This file defines SetVector and SmallSetVector, which performs no allocations
+// if the SetVector has less than a certain number of elements.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SETVECTOR_H
+#define LLVM_ADT_SETVECTOR_H
+
+#include "llvm/ADT/SmallSet.h"
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+namespace llvm {
+
+/// This adapter class provides a way to keep a set of things that also has the
+/// property of a deterministic iteration order. The order of iteration is the
+/// order of insertion.
+/// @brief A vector that has set insertion semantics.
+template <typename T, typename Vector = std::vector<T>,
+ typename Set = SmallSet<T, 16> >
+class SetVector {
+public:
+ typedef T value_type;
+ typedef T key_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+ typedef Set set_type;
+ typedef Vector vector_type;
+ typedef typename vector_type::const_iterator iterator;
+ typedef typename vector_type::const_iterator const_iterator;
+ typedef typename vector_type::size_type size_type;
+
+ /// @brief Construct an empty SetVector
+ SetVector() {}
+
+ /// @brief Initialize a SetVector with a range of elements
+ template<typename It>
+ SetVector(It Start, It End) {
+ insert(Start, End);
+ }
+
+ /// @brief Determine if the SetVector is empty or not.
+ bool empty() const {
+ return vector_.empty();
+ }
+
+ /// @brief Determine the number of elements in the SetVector.
+ size_type size() const {
+ return vector_.size();
+ }
+
+ /// @brief Get an iterator to the beginning of the SetVector.
+ iterator begin() {
+ return vector_.begin();
+ }
+
+ /// @brief Get a const_iterator to the beginning of the SetVector.
+ const_iterator begin() const {
+ return vector_.begin();
+ }
+
+ /// @brief Get an iterator to the end of the SetVector.
+ iterator end() {
+ return vector_.end();
+ }
+
+ /// @brief Get a const_iterator to the end of the SetVector.
+ const_iterator end() const {
+ return vector_.end();
+ }
+
+ /// @brief Return the last element of the SetVector.
+ const T &back() const {
+ assert(!empty() && "Cannot call back() on empty SetVector!");
+ return vector_.back();
+ }
+
+ /// @brief Index into the SetVector.
+ const_reference operator[](size_type n) const {
+ assert(n < vector_.size() && "SetVector access out of range!");
+ return vector_[n];
+ }
+
+ /// @returns true iff the element was inserted into the SetVector.
+ /// @brief Insert a new element into the SetVector.
+ bool insert(const value_type &X) {
+ bool result = set_.insert(X);
+ if (result)
+ vector_.push_back(X);
+ return result;
+ }
+
+ /// @brief Insert a range of elements into the SetVector.
+ template<typename It>
+ void insert(It Start, It End) {
+ for (; Start != End; ++Start)
+ if (set_.insert(*Start))
+ vector_.push_back(*Start);
+ }
+
+ /// @brief Remove an item from the set vector.
+ void remove(const value_type& X) {
+ if (set_.erase(X)) {
+ typename vector_type::iterator I =
+ std::find(vector_.begin(), vector_.end(), X);
+ assert(I != vector_.end() && "Corrupted SetVector instances!");
+ vector_.erase(I);
+ }
+ }
+
+
+ /// @returns 0 if the element is not in the SetVector, 1 if it is.
+ /// @brief Count the number of elements of a given key in the SetVector.
+ size_type count(const key_type &key) const {
+ return set_.count(key);
+ }
+
+ /// @brief Completely clear the SetVector
+ void clear() {
+ set_.clear();
+ vector_.clear();
+ }
+
+ /// @brief Remove the last element of the SetVector.
+ void pop_back() {
+ assert(!empty() && "Cannot remove an element from an empty SetVector!");
+ set_.erase(back());
+ vector_.pop_back();
+ }
+
+private:
+ set_type set_; ///< The set.
+ vector_type vector_; ///< The vector.
+};
+
+/// SmallSetVector - A SetVector that performs no allocations if smaller than
+/// a certain size.
+template <typename T, unsigned N>
+class SmallSetVector : public SetVector<T, SmallVector<T, N>, SmallSet<T, N> > {
+public:
+ SmallSetVector() {}
+
+ /// @brief Initialize a SmallSetVector with a range of elements
+ template<typename It>
+ SmallSetVector(It Start, It End) {
+ this->insert(Start, End);
+ }
+};
+
+} // End llvm namespace
+
+// vim: sw=2 ai
+#endif
diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h
new file mode 100644
index 0000000..27c8459
--- /dev/null
+++ b/include/llvm/ADT/SmallPtrSet.h
@@ -0,0 +1,250 @@
+//===- llvm/ADT/SmallPtrSet.h - 'Normally small' pointer set ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallPtrSet class. See the doxygen comment for
+// SmallPtrSetImpl for more details on the algorithm used.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLPTRSET_H
+#define LLVM_ADT_SMALLPTRSET_H
+
+#include <cassert>
+#include <cstring>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+/// SmallPtrSetImpl - This is the common code shared among all the
+/// SmallPtrSet<>'s, which is almost everything. SmallPtrSet has two modes, one
+/// for small and one for large sets.
+///
+/// Small sets use an array of pointers allocated in the SmallPtrSet object,
+/// which is treated as a simple array of pointers. When a pointer is added to
+/// the set, the array is scanned to see if the element already exists, if not
+/// the element is 'pushed back' onto the array. If we run out of space in the
+/// array, we grow into the 'large set' case. SmallSet should be used when the
+/// sets are often small. In this case, no memory allocation is used, and only
+/// light-weight and cache-efficient scanning is used.
+///
+/// Large sets use a classic exponentially-probed hash table. Empty buckets are
+/// represented with an illegal pointer value (-1) to allow null pointers to be
+/// inserted. Tombstones are represented with another illegal pointer value
+/// (-2), to allow deletion. The hash table is resized when the table is 3/4 or
+/// more. When this happens, the table is doubled in size.
+///
+class SmallPtrSetImpl {
+protected:
+ /// CurArray - This is the current set of buckets. If it points to
+ /// SmallArray, then the set is in 'small mode'.
+ void **CurArray;
+ /// CurArraySize - The allocated size of CurArray, always a power of two.
+ /// Note that CurArray points to an array that has CurArraySize+1 elements in
+ /// it, so that the end iterator actually points to valid memory.
+ unsigned CurArraySize;
+
+ // If small, this is # elts allocated consequtively
+ unsigned NumElements;
+ unsigned NumTombstones;
+ void *SmallArray[1]; // Must be last ivar.
+
+ // Helper to copy construct a SmallPtrSet.
+ SmallPtrSetImpl(const SmallPtrSetImpl& that);
+public:
+ SmallPtrSetImpl(unsigned SmallSize) {
+ assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
+ "Initial size must be a power of two!");
+ CurArray = &SmallArray[0];
+ CurArraySize = SmallSize;
+ // The end pointer, always valid, is set to a valid element to help the
+ // iterator.
+ CurArray[SmallSize] = 0;
+ clear();
+ }
+ ~SmallPtrSetImpl();
+
+ bool empty() const { return size() == 0; }
+ unsigned size() const { return NumElements; }
+
+ static void *getTombstoneMarker() { return reinterpret_cast<void*>(-2); }
+ static void *getEmptyMarker() {
+ // Note that -1 is chosen to make clear() efficiently implementable with
+ // memset and because it's not a valid pointer value.
+ return reinterpret_cast<void*>(-1);
+ }
+
+ void clear() {
+ // Fill the array with empty markers.
+ memset(CurArray, -1, CurArraySize*sizeof(void*));
+ NumElements = 0;
+ NumTombstones = 0;
+ }
+
+ /// insert - This returns true if the pointer was new to the set, false if it
+ /// was already in the set.
+ bool insert(void *Ptr);
+
+ template <typename IterT>
+ void insert(IterT I, IterT E) {
+ for (; I != E; ++I)
+ insert((void*)*I);
+ }
+
+ /// erase - If the set contains the specified pointer, remove it and return
+ /// true, otherwise return false.
+ bool erase(void *Ptr);
+
+ bool count(void *Ptr) const {
+ if (isSmall()) {
+ // Linear search for the item.
+ for (void *const *APtr = SmallArray, *const *E = SmallArray+NumElements;
+ APtr != E; ++APtr)
+ if (*APtr == Ptr)
+ return true;
+ return false;
+ }
+
+ // Big set case.
+ return *FindBucketFor(Ptr) == Ptr;
+ }
+
+private:
+ bool isSmall() const { return CurArray == &SmallArray[0]; }
+
+ unsigned Hash(void *Ptr) const {
+ return ((uintptr_t)Ptr >> 4) & (CurArraySize-1);
+ }
+ void * const *FindBucketFor(void *Ptr) const;
+
+ /// Grow - Allocate a larger backing store for the buckets and move it over.
+ void Grow();
+
+ void operator=(const SmallPtrSetImpl &RHS); // DO NOT IMPLEMENT.
+protected:
+ void CopyFrom(const SmallPtrSetImpl &RHS);
+};
+
+/// SmallPtrSetIteratorImpl - This is the common base class shared between all
+/// instances of SmallPtrSetIterator.
+class SmallPtrSetIteratorImpl {
+protected:
+ void *const *Bucket;
+public:
+ SmallPtrSetIteratorImpl(void *const *BP) : Bucket(BP) {
+ AdvanceIfNotValid();
+ }
+
+ bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket == RHS.Bucket;
+ }
+ bool operator!=(const SmallPtrSetIteratorImpl &RHS) const {
+ return Bucket != RHS.Bucket;
+ }
+
+protected:
+ /// AdvanceIfNotValid - If the current bucket isn't valid, advance to a bucket
+ /// that is. This is guaranteed to stop because the end() bucket is marked
+ /// valid.
+ void AdvanceIfNotValid() {
+ while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
+ *Bucket == SmallPtrSetImpl::getTombstoneMarker())
+ ++Bucket;
+ }
+};
+
+/// SmallPtrSetIterator - This implements a const_iterator for SmallPtrSet.
+template<typename PtrTy>
+class SmallPtrSetIterator : public SmallPtrSetIteratorImpl {
+public:
+ SmallPtrSetIterator(void *const *BP) : SmallPtrSetIteratorImpl(BP) {}
+
+ // Most methods provided by baseclass.
+
+ PtrTy operator*() const {
+ return static_cast<PtrTy>(*Bucket);
+ }
+
+ inline SmallPtrSetIterator& operator++() { // Preincrement
+ ++Bucket;
+ AdvanceIfNotValid();
+ return *this;
+ }
+
+ SmallPtrSetIterator operator++(int) { // Postincrement
+ SmallPtrSetIterator tmp = *this; ++*this; return tmp;
+ }
+};
+
+/// NextPowerOfTwo - This is a helper template that rounds N up to the next
+/// power of two.
+template<unsigned N>
+struct NextPowerOfTwo;
+
+/// NextPowerOfTwoH - If N is not a power of two, increase it. This is a helper
+/// template used to implement NextPowerOfTwo.
+template<unsigned N, bool isPowerTwo>
+struct NextPowerOfTwoH {
+ enum { Val = N };
+};
+template<unsigned N>
+struct NextPowerOfTwoH<N, false> {
+ enum {
+ // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets
+ // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111.
+ Val = NextPowerOfTwo<(N|(N-1)) + 1>::Val
+ };
+};
+
+template<unsigned N>
+struct NextPowerOfTwo {
+ enum { Val = NextPowerOfTwoH<N, (N&(N-1)) == 0>::Val };
+};
+
+
+/// SmallPtrSet - This class implements a set which is optimizer for holding
+/// SmallSize or less elements. This internally rounds up SmallSize to the next
+/// power of two if it is not already a power of two. See the comments above
+/// SmallPtrSetImpl for details of the algorithm.
+template<class PtrType, unsigned SmallSize>
+class SmallPtrSet : public SmallPtrSetImpl {
+ // Make sure that SmallSize is a power of two, round up if not.
+ enum { SmallSizePowTwo = NextPowerOfTwo<SmallSize>::Val };
+ void *SmallArray[SmallSizePowTwo];
+public:
+ SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {}
+ SmallPtrSet(const SmallPtrSet &that) : SmallPtrSetImpl(that) {}
+
+ template<typename It>
+ SmallPtrSet(It I, It E)
+ : SmallPtrSetImpl(NextPowerOfTwo<SmallSizePowTwo>::Val) {
+ insert(I, E);
+ }
+
+ typedef SmallPtrSetIterator<PtrType> iterator;
+ typedef SmallPtrSetIterator<PtrType> const_iterator;
+ inline iterator begin() const {
+ return iterator(CurArray);
+ }
+ inline iterator end() const {
+ return iterator(CurArray+CurArraySize);
+ }
+
+ // Allow assignment from any smallptrset with the same element type even if it
+ // doesn't have the same smallsize.
+ const SmallPtrSet<PtrType, SmallSize>&
+ operator=(const SmallPtrSet<PtrType, SmallSize> &RHS) {
+ CopyFrom(RHS);
+ return *this;
+ }
+
+};
+
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallSet.h b/include/llvm/ADT/SmallSet.h
new file mode 100644
index 0000000..30e8ee5
--- /dev/null
+++ b/include/llvm/ADT/SmallSet.h
@@ -0,0 +1,112 @@
+//===- llvm/ADT/SmallSet.h - 'Normally small' sets --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallSet class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSET_H
+#define LLVM_ADT_SMALLSET_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <set>
+
+namespace llvm {
+
+/// SmallSet - This maintains a set of unique values, optimizing for the case
+/// when the set is small (less than N). In this case, the set can be
+/// maintained with no mallocs. If the set gets large, we expand to using an
+/// std::set to maintain reasonable lookup times.
+///
+/// Note that this set does not provide a way to iterate over members in the
+/// set.
+template <typename T, unsigned N>
+class SmallSet {
+ /// Use a SmallVector to hold the elements here (even though it will never
+ /// reach it's 'large' stage) to avoid calling the default ctors of elements
+ /// we will never use.
+ SmallVector<T, N> Vector;
+ std::set<T> Set;
+ typedef typename SmallVector<T, N>::const_iterator VIterator;
+ typedef typename SmallVector<T, N>::iterator mutable_iterator;
+public:
+ SmallSet() {}
+
+ bool empty() const { return Vector.empty() && Set.empty(); }
+ unsigned size() const {
+ return isSmall() ? Vector.size() : Set.size();
+ }
+
+ /// count - Return true if the element is in the set.
+ bool count(const T &V) const {
+ if (isSmall()) {
+ // Since the collection is small, just do a linear search.
+ return vfind(V) != Vector.end();
+ } else {
+ return Set.count(V);
+ }
+ }
+
+ /// insert - Insert an element into the set if it isn't already there.
+ bool insert(const T &V) {
+ if (!isSmall())
+ return Set.insert(V).second;
+
+ VIterator I = vfind(V);
+ if (I != Vector.end()) // Don't reinsert if it already exists.
+ return false;
+ if (Vector.size() < N) {
+ Vector.push_back(V);
+ return true;
+ }
+
+ // Otherwise, grow from vector to set.
+ while (!Vector.empty()) {
+ Set.insert(Vector.back());
+ Vector.pop_back();
+ }
+ Set.insert(V);
+ return true;
+ }
+
+ bool erase(const T &V) {
+ if (!isSmall())
+ return Set.erase(V);
+ for (mutable_iterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V) {
+ Vector.erase(I);
+ return true;
+ }
+ return false;
+ }
+
+ void clear() {
+ Vector.clear();
+ Set.clear();
+ }
+private:
+ bool isSmall() const { return Set.empty(); }
+
+ VIterator vfind(const T &V) const {
+ for (VIterator I = Vector.begin(), E = Vector.end(); I != E; ++I)
+ if (*I == V)
+ return I;
+ return Vector.end();
+ }
+};
+
+/// If this set is of pointer values, transparently switch over to using
+/// SmallPtrSet for performance.
+template <typename PointeeType, unsigned N>
+class SmallSet<PointeeType*, N> : public SmallPtrSet<PointeeType*, N> {};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/ADT/SmallString.h b/include/llvm/ADT/SmallString.h
new file mode 100644
index 0000000..2818ebb
--- /dev/null
+++ b/include/llvm/ADT/SmallString.h
@@ -0,0 +1,62 @@
+//===- llvm/ADT/SmallString.h - 'Normally small' strings --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallString class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLSTRING_H
+#define LLVM_ADT_SMALLSTRING_H
+
+#include "llvm/ADT/SmallVector.h"
+#include <cstring>
+
+namespace llvm {
+
+/// SmallString - A SmallString is just a SmallVector with methods and accessors
+/// that make it work better as a string (e.g. operator+ etc).
+template<unsigned InternalLen>
+class SmallString : public SmallVector<char, InternalLen> {
+public:
+ // Default ctor - Initialize to empty.
+ SmallString() {}
+
+ // Initialize with a range.
+ template<typename ItTy>
+ SmallString(ItTy S, ItTy E) : SmallVector<char, InternalLen>(S, E) {}
+
+ // Copy ctor.
+ SmallString(const SmallString &RHS) : SmallVector<char, InternalLen>(RHS) {}
+
+
+ // Extra methods.
+ const char *c_str() const {
+ SmallString *This = const_cast<SmallString*>(this);
+ // Ensure that there is a \0 at the end of the string.
+ This->reserve(this->size()+1);
+ This->End[0] = 0;
+ return this->begin();
+ }
+
+ // Extra operators.
+ SmallString &operator+=(const char *RHS) {
+ this->append(RHS, RHS+strlen(RHS));
+ return *this;
+ }
+ SmallString &operator+=(char C) {
+ this->push_back(C);
+ return *this;
+ }
+
+};
+
+
+}
+
+#endif
diff --git a/include/llvm/ADT/SmallVector.h b/include/llvm/ADT/SmallVector.h
new file mode 100644
index 0000000..876ca27
--- /dev/null
+++ b/include/llvm/ADT/SmallVector.h
@@ -0,0 +1,485 @@
+//===- llvm/ADT/SmallVector.h - 'Normally small' vectors --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SmallVector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_SMALLVECTOR_H
+#define LLVM_ADT_SMALLVECTOR_H
+
+#include <algorithm>
+#include <iterator>
+#include <memory>
+
+#ifdef _MSC_VER
+namespace std {
+#if _MSC_VER <= 1310
+ // Work around flawed VC++ implementation of std::uninitialized_copy. Define
+ // additional overloads so that elements with pointer types are recognized as
+ // scalars and not objects, causing bizarre type conversion errors.
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1 **, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+
+ template<class T1, class T2>
+ inline _Scalar_ptr_iterator_tag _Ptr_cat(T1* const *, T2 **) {
+ _Scalar_ptr_iterator_tag _Cat;
+ return _Cat;
+ }
+#else
+// FIXME: It is not clear if the problem is fixed in VS 2005. What is clear
+// is that the above hack won't work if it wasn't fixed.
+#endif
+}
+#endif
+
+namespace llvm {
+
+/// SmallVectorImpl - This class consists of common code factored out of the
+/// SmallVector class to reduce code duplication based on the SmallVector 'N'
+/// template parameter.
+template <typename T>
+class SmallVectorImpl {
+protected:
+ T *Begin, *End, *Capacity;
+
+ // Allocate raw space for N elements of type T. If T has a ctor or dtor, we
+ // don't want it to be automatically run, so we need to represent the space as
+ // something else. An array of char would work great, but might not be
+ // aligned sufficiently. Instead, we either use GCC extensions, or some
+ // number of union instances for the space, which guarantee maximal alignment.
+protected:
+#ifdef __GNUC__
+ typedef char U;
+ U FirstEl __attribute__((aligned));
+#else
+ union U {
+ double D;
+ long double LD;
+ long long L;
+ void *P;
+ } FirstEl;
+#endif
+ // Space after 'FirstEl' is clobbered, do not add any instance vars after it.
+public:
+ // Default ctor - Initialize to empty.
+ SmallVectorImpl(unsigned N)
+ : Begin((T*)&FirstEl), End((T*)&FirstEl), Capacity((T*)&FirstEl+N) {
+ }
+
+ ~SmallVectorImpl() {
+ // Destroy the constructed elements in the vector.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ delete[] (char*)Begin;
+ }
+
+ typedef size_t size_type;
+ typedef T* iterator;
+ typedef const T* const_iterator;
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ bool empty() const { return Begin == End; }
+ size_type size() const { return End-Begin; }
+
+ iterator begin() { return Begin; }
+ const_iterator begin() const { return Begin; }
+
+ iterator end() { return End; }
+ const_iterator end() const { return End; }
+
+ reference operator[](unsigned idx) {
+ return Begin[idx];
+ }
+ const_reference operator[](unsigned idx) const {
+ return Begin[idx];
+ }
+
+ reference front() {
+ return begin()[0];
+ }
+ const_reference front() const {
+ return begin()[0];
+ }
+
+ reference back() {
+ return end()[-1];
+ }
+ const_reference back() const {
+ return end()[-1];
+ }
+
+ void push_back(const_reference Elt) {
+ if (End < Capacity) {
+ Retry:
+ new (End) T(Elt);
+ ++End;
+ return;
+ }
+ grow();
+ goto Retry;
+ }
+
+ void pop_back() {
+ --End;
+ End->~T();
+ }
+
+ void clear() {
+ destroy_range(Begin, End);
+ End = Begin;
+ }
+
+ void resize(unsigned N) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, T());
+ End = Begin+N;
+ }
+ }
+
+ void resize(unsigned N, const T &NV) {
+ if (N < size()) {
+ destroy_range(Begin+N, End);
+ End = Begin+N;
+ } else if (N > size()) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ construct_range(End, Begin+N, NV);
+ End = Begin+N;
+ }
+ }
+
+ void reserve(unsigned N) {
+ if (unsigned(Capacity-Begin) < N)
+ grow(N);
+ }
+
+ void swap(SmallVectorImpl &RHS);
+
+ /// append - Add the specified range to the end of the SmallVector.
+ ///
+ template<typename in_iter>
+ void append(in_iter in_start, in_iter in_end) {
+ unsigned NumInputs = std::distance(in_start, in_end);
+ // Grow allocated space if needed.
+ if (End+NumInputs > Capacity)
+ grow(size()+NumInputs);
+
+ // Copy the new elements over.
+ std::uninitialized_copy(in_start, in_end, End);
+ End += NumInputs;
+ }
+
+ void assign(unsigned NumElts, const T &Elt) {
+ clear();
+ if (unsigned(Capacity-Begin) < NumElts)
+ grow(NumElts);
+ End = Begin+NumElts;
+ construct_range(Begin, End, Elt);
+ }
+
+ void erase(iterator I) {
+ // Shift all elts down one.
+ std::copy(I+1, End, I);
+ // Drop the last elt.
+ pop_back();
+ }
+
+ void erase(iterator S, iterator E) {
+ // Shift all elts down.
+ iterator I = std::copy(E, End, S);
+ // Drop the last elts.
+ destroy_range(I, End);
+ End = I;
+ }
+
+ iterator insert(iterator I, const T &Elt) {
+ if (I == End) { // Important special case for empty vector.
+ push_back(Elt);
+ return end()-1;
+ }
+
+ if (End < Capacity) {
+ Retry:
+ new (End) T(back());
+ ++End;
+ // Push everything else over.
+ std::copy_backward(I, End-1, End);
+ *I = Elt;
+ return I;
+ }
+ unsigned EltNo = I-Begin;
+ grow();
+ I = Begin+EltNo;
+ goto Retry;
+ }
+
+ template<typename ItTy>
+ iterator insert(iterator I, ItTy From, ItTy To) {
+ if (I == End) { // Important special case for empty vector.
+ append(From, To);
+ return end()-1;
+ }
+
+ unsigned NumToInsert = std::distance(From, To);
+ // Convert iterator to elt# to avoid invalidating iterator when we reserve()
+ unsigned InsertElt = I-begin();
+
+ // Ensure there is enough space.
+ reserve(size() + NumToInsert);
+
+ // Uninvalidate the iterator.
+ I = begin()+InsertElt;
+
+ // If we already have this many elements in the collection, append the
+ // dest elements at the end, then copy over the appropriate elements. Since
+ // we already reserved space, we know that this won't reallocate the vector.
+ if (size() >= NumToInsert) {
+ T *OldEnd = End;
+ append(End-NumToInsert, End);
+
+ // Copy the existing elements that get replaced.
+ std::copy(I, OldEnd-NumToInsert, I+NumToInsert);
+
+ std::copy(From, To, I);
+ return I;
+ }
+
+ // Otherwise, we're inserting more elements than exist already, and we're
+ // not inserting at the end.
+
+ // Copy over the elements that we're about to overwrite.
+ T *OldEnd = End;
+ End += NumToInsert;
+ unsigned NumOverwritten = OldEnd-I;
+ std::uninitialized_copy(I, OldEnd, End-NumOverwritten);
+
+ // Replace the overwritten part.
+ std::copy(From, From+NumOverwritten, I);
+
+ // Insert the non-overwritten middle part.
+ std::uninitialized_copy(From+NumOverwritten, To, OldEnd);
+ return I;
+ }
+
+ const SmallVectorImpl &operator=(const SmallVectorImpl &RHS);
+
+private:
+ /// isSmall - Return true if this is a smallvector which has not had dynamic
+ /// memory allocated for it.
+ bool isSmall() const {
+ return (void*)Begin == (void*)&FirstEl;
+ }
+
+ /// grow - double the size of the allocated memory, guaranteeing space for at
+ /// least one more element or MinSize if specified.
+ void grow(unsigned MinSize = 0);
+
+ void construct_range(T *S, T *E, const T &Elt) {
+ for (; S != E; ++S)
+ new (S) T(Elt);
+ }
+
+ void destroy_range(T *S, T *E) {
+ while (S != E) {
+ --E;
+ E->~T();
+ }
+ }
+};
+
+// Define this out-of-line to dissuade the C++ compiler from inlining it.
+template <typename T>
+void SmallVectorImpl<T>::grow(unsigned MinSize) {
+ unsigned CurCapacity = unsigned(Capacity-Begin);
+ unsigned CurSize = unsigned(size());
+ unsigned NewCapacity = 2*CurCapacity;
+ if (NewCapacity < MinSize)
+ NewCapacity = MinSize;
+ T *NewElts = reinterpret_cast<T*>(new char[NewCapacity*sizeof(T)]);
+
+ // Copy the elements over.
+ std::uninitialized_copy(Begin, End, NewElts);
+
+ // Destroy the original elements.
+ destroy_range(Begin, End);
+
+ // If this wasn't grown from the inline copy, deallocate the old space.
+ if (!isSmall())
+ delete[] (char*)Begin;
+
+ Begin = NewElts;
+ End = NewElts+CurSize;
+ Capacity = Begin+NewCapacity;
+}
+
+template <typename T>
+void SmallVectorImpl<T>::swap(SmallVectorImpl<T> &RHS) {
+ if (this == &RHS) return;
+
+ // We can only avoid copying elements if neither vector is small.
+ if (!isSmall() && !RHS.isSmall()) {
+ std::swap(Begin, RHS.Begin);
+ std::swap(End, RHS.End);
+ std::swap(Capacity, RHS.Capacity);
+ return;
+ }
+ if (Begin+RHS.size() > Capacity)
+ grow(RHS.size());
+ if (RHS.begin()+size() > RHS.Capacity)
+ RHS.grow(size());
+
+ // Swap the shared elements.
+ unsigned NumShared = size();
+ if (NumShared > RHS.size()) NumShared = RHS.size();
+ for (unsigned i = 0; i != NumShared; ++i)
+ std::swap(Begin[i], RHS[i]);
+
+ // Copy over the extra elts.
+ if (size() > RHS.size()) {
+ unsigned EltDiff = size() - RHS.size();
+ std::uninitialized_copy(Begin+NumShared, End, RHS.End);
+ RHS.End += EltDiff;
+ destroy_range(Begin+NumShared, End);
+ End = Begin+NumShared;
+ } else if (RHS.size() > size()) {
+ unsigned EltDiff = RHS.size() - size();
+ std::uninitialized_copy(RHS.Begin+NumShared, RHS.End, End);
+ End += EltDiff;
+ destroy_range(RHS.Begin+NumShared, RHS.End);
+ RHS.End = RHS.Begin+NumShared;
+ }
+}
+
+template <typename T>
+const SmallVectorImpl<T> &
+SmallVectorImpl<T>::operator=(const SmallVectorImpl<T> &RHS) {
+ // Avoid self-assignment.
+ if (this == &RHS) return *this;
+
+ // If we already have sufficient space, assign the common elements, then
+ // destroy any excess.
+ unsigned RHSSize = unsigned(RHS.size());
+ unsigned CurSize = unsigned(size());
+ if (CurSize >= RHSSize) {
+ // Assign common elements.
+ iterator NewEnd = std::copy(RHS.Begin, RHS.Begin+RHSSize, Begin);
+
+ // Destroy excess elements.
+ destroy_range(NewEnd, End);
+
+ // Trim.
+ End = NewEnd;
+ return *this;
+ }
+
+ // If we have to grow to have enough elements, destroy the current elements.
+ // This allows us to avoid copying them during the grow.
+ if (unsigned(Capacity-Begin) < RHSSize) {
+ // Destroy current elements.
+ destroy_range(Begin, End);
+ End = Begin;
+ CurSize = 0;
+ grow(RHSSize);
+ } else if (CurSize) {
+ // Otherwise, use assignment for the already-constructed elements.
+ std::copy(RHS.Begin, RHS.Begin+CurSize, Begin);
+ }
+
+ // Copy construct the new elements in place.
+ std::uninitialized_copy(RHS.Begin+CurSize, RHS.End, Begin+CurSize);
+
+ // Set end.
+ End = Begin+RHSSize;
+ return *this;
+}
+
+/// SmallVector - This is a 'vector' (really, a variable-sized array), optimized
+/// for the case when the array is small. It contains some number of elements
+/// in-place, which allows it to avoid heap allocation when the actual number of
+/// elements is below that threshold. This allows normal "small" cases to be
+/// fast without losing generality for large inputs.
+///
+/// Note that this does not attempt to be exception safe.
+///
+template <typename T, unsigned N>
+class SmallVector : public SmallVectorImpl<T> {
+ /// InlineElts - These are 'N-1' elements that are stored inline in the body
+ /// of the vector. The extra '1' element is stored in SmallVectorImpl.
+ typedef typename SmallVectorImpl<T>::U U;
+ enum {
+ // MinUs - The number of U's require to cover N T's.
+ MinUs = (sizeof(T)*N+sizeof(U)-1)/sizeof(U),
+
+ // NumInlineEltsElts - The number of elements actually in this array. There
+ // is already one in the parent class, and we have to round up to avoid
+ // having a zero-element array.
+ NumInlineEltsElts = (MinUs - 1) > 0 ? (MinUs - 1) : 1,
+
+ // NumTsAvailable - The number of T's we actually have space for, which may
+ // be more than N due to rounding.
+ NumTsAvailable = (NumInlineEltsElts+1)*sizeof(U) / sizeof(T)
+ };
+ U InlineElts[NumInlineEltsElts];
+public:
+ SmallVector() : SmallVectorImpl<T>(NumTsAvailable) {
+ }
+
+ explicit SmallVector(unsigned Size, const T &Value = T())
+ : SmallVectorImpl<T>(NumTsAvailable) {
+ this->reserve(Size);
+ while (Size--)
+ push_back(Value);
+ }
+
+ template<typename ItTy>
+ SmallVector(ItTy S, ItTy E) : SmallVectorImpl<T>(NumTsAvailable) {
+ append(S, E);
+ }
+
+ SmallVector(const SmallVector &RHS) : SmallVectorImpl<T>(NumTsAvailable) {
+ operator=(RHS);
+ }
+
+ const SmallVector &operator=(const SmallVector &RHS) {
+ SmallVectorImpl<T>::operator=(RHS);
+ return *this;
+ }
+};
+
+} // End llvm namespace
+
+namespace std {
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T>
+ inline void
+ swap(llvm::SmallVectorImpl<T> &LHS, llvm::SmallVectorImpl<T> &RHS) {
+ LHS.swap(RHS);
+ }
+
+ /// Implement std::swap in terms of SmallVector swap.
+ template<typename T, unsigned N>
+ inline void
+ swap(llvm::SmallVector<T, N> &LHS, llvm::SmallVector<T, N> &RHS) {
+ LHS.swap(RHS);
+ }
+}
+
+#endif
diff --git a/include/llvm/ADT/Statistic.h b/include/llvm/ADT/Statistic.h
new file mode 100644
index 0000000..ec4fdd6
--- /dev/null
+++ b/include/llvm/ADT/Statistic.h
@@ -0,0 +1,75 @@
+//===-- llvm/ADT/Statistic.h - Easy way to expose stats ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the 'Statistic' class, which is designed to be an easy way
+// to expose various metrics from passes. These statistics are printed at the
+// end of a run (from llvm_shutdown), when the -stats command line option is
+// passed on the command line.
+//
+// This is useful for reporting information like the number of instructions
+// simplified, optimized or removed by various transformations, like this:
+//
+// static Statistic NumInstsKilled("gcse", "Number of instructions killed");
+//
+// Later, in the code: ++NumInstsKilled;
+//
+// NOTE: Statistics *must* be declared as global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STATISTIC_H
+#define LLVM_ADT_STATISTIC_H
+
+namespace llvm {
+
+class Statistic {
+public:
+ const char *Name;
+ const char *Desc;
+ unsigned Value : 31;
+ bool Initialized : 1;
+
+ unsigned getValue() const { return Value; }
+ const char *getName() const { return Name; }
+ const char *getDesc() const { return Desc; }
+
+ /// construct - This should only be called for non-global statistics.
+ void construct(const char *name, const char *desc) {
+ Name = name; Desc = desc;
+ Value = 0; Initialized = 0;
+ }
+
+ // Allow use of this class as the value itself.
+ operator unsigned() const { return Value; }
+ const Statistic &operator=(unsigned Val) { Value = Val; return init(); }
+ const Statistic &operator++() { ++Value; return init(); }
+ unsigned operator++(int) { init(); return Value++; }
+ const Statistic &operator--() { --Value; return init(); }
+ unsigned operator--(int) { init(); return Value--; }
+ const Statistic &operator+=(const unsigned &V) { Value += V; return init(); }
+ const Statistic &operator-=(const unsigned &V) { Value -= V; return init(); }
+ const Statistic &operator*=(const unsigned &V) { Value *= V; return init(); }
+ const Statistic &operator/=(const unsigned &V) { Value /= V; return init(); }
+
+protected:
+ Statistic &init() {
+ if (!Initialized) RegisterStatistic();
+ return *this;
+ }
+ void RegisterStatistic();
+};
+
+// STATISTIC - A macro to make definition of statistics really simple. This
+// automatically passes the DEBUG_TYPE of the file into the statistic.
+#define STATISTIC(VARNAME, DESC) \
+ static Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringExtras.h b/include/llvm/ADT/StringExtras.h
new file mode 100644
index 0000000..f0788a1
--- /dev/null
+++ b/include/llvm/ADT/StringExtras.h
@@ -0,0 +1,150 @@
+//===-- llvm/ADT/StringExtras.h - Useful string functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful when dealing with strings.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGEXTRAS_H
+#define LLVM_ADT_STRINGEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cctype>
+#include <cstdio>
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+static inline std::string utohexstr(uint64_t X) {
+ char Buffer[40];
+ char *BufPtr = Buffer+39;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ unsigned char Mod = static_cast<unsigned char>(X) & 15;
+ if (Mod < 10)
+ *--BufPtr = '0' + Mod;
+ else
+ *--BufPtr = 'A' + Mod-10;
+ X >>= 4;
+ }
+ return std::string(BufPtr);
+}
+
+static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
+ char Buffer[20];
+ char *BufPtr = Buffer+19;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+
+ return std::string(BufPtr);
+}
+
+static inline std::string utostr(uint64_t X, bool isNeg = false) {
+ if (X == uint32_t(X))
+ return utostr_32(uint32_t(X), isNeg);
+
+ char Buffer[40];
+ char *BufPtr = Buffer+39;
+
+ *BufPtr = 0; // Null terminate buffer...
+ if (X == 0) *--BufPtr = '0'; // Handle special case...
+
+ while (X) {
+ *--BufPtr = '0' + char(X % 10);
+ X /= 10;
+ }
+
+ if (isNeg) *--BufPtr = '-'; // Add negative sign...
+ return std::string(BufPtr);
+}
+
+
+static inline std::string itostr(int64_t X) {
+ if (X < 0)
+ return utostr(static_cast<uint64_t>(-X), true);
+ else
+ return utostr(static_cast<uint64_t>(X));
+}
+
+static inline std::string ftostr(double V) {
+ char Buffer[200];
+ sprintf(Buffer, "%20.6e", V);
+ char *B = Buffer;
+ while (*B == ' ') ++B;
+ return B;
+}
+
+static inline std::string LowercaseString(const std::string &S) {
+ std::string result(S);
+ for (unsigned i = 0; i < S.length(); ++i)
+ if (isupper(result[i]))
+ result[i] = char(tolower(result[i]));
+ return result;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const std::string &RHS) {
+ if (LHS.size() != RHS.size()) return false;
+ for (unsigned i = 0, e = LHS.size(); i != e; ++i)
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ return true;
+}
+
+/// StringsEqualNoCase - Return true if the two strings are equal, ignoring
+/// case.
+static inline bool StringsEqualNoCase(const std::string &LHS,
+ const char *RHS) {
+ for (unsigned i = 0, e = LHS.size(); i != e; ++i) {
+ if (RHS[i] == 0) return false; // RHS too short.
+ if (tolower(LHS[i]) != tolower(RHS[i])) return false;
+ }
+ return RHS[LHS.size()] == 0; // Not too long?
+}
+
+/// getToken - This function extracts one token from source, ignoring any
+/// leading characters that appear in the Delimiters string, and ending the
+/// token at any of the characters that appear in the Delimiters string. If
+/// there are no tokens in the source string, an empty string is returned.
+/// The Source source string is updated in place to remove the returned string
+/// and any delimiter prefix from it.
+std::string getToken(std::string &Source,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// SplitString - Split up the specified string according to the specified
+/// delimiters, appending the result fragments to the output list.
+void SplitString(const std::string &Source,
+ std::vector<std::string> &OutFragments,
+ const char *Delimiters = " \t\n\v\f\r");
+
+/// UnescapeString - Modify the argument string, turning two character sequences
+/// like '\\' 'n' into '\n'. This handles: \e \a \b \f \n \r \t \v \' \\ and
+/// \num (where num is a 1-3 byte octal value).
+void UnescapeString(std::string &Str);
+
+/// EscapeString - Modify the argument string, turning '\\' and anything that
+/// doesn't satisfy std::isprint into an escape sequence.
+void EscapeString(std::string &Str);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/StringMap.h b/include/llvm/ADT/StringMap.h
new file mode 100644
index 0000000..cb1dd9f
--- /dev/null
+++ b/include/llvm/ADT/StringMap.h
@@ -0,0 +1,346 @@
+//===--- StringMap.h - String Hash table map interface ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StringMap class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_STRINGMAP_H
+#define LLVM_ADT_STRINGMAP_H
+
+#include "llvm/Support/Allocator.h"
+#include <cstring>
+
+namespace llvm {
+ template<typename ValueT>
+ class StringMapConstIterator;
+ template<typename ValueT>
+ class StringMapIterator;
+
+
+/// StringMapEntryBase - Shared base class of StringMapEntry instances.
+class StringMapEntryBase {
+ unsigned StrLen;
+public:
+ StringMapEntryBase(unsigned Len) : StrLen(Len) {}
+
+ unsigned getKeyLength() const { return StrLen; }
+};
+
+/// StringMapImpl - This is the base class of StringMap that is shared among
+/// all of its instantiations.
+class StringMapImpl {
+public:
+ /// ItemBucket - The hash table consists of an array of these. If Item is
+ /// non-null, this is an extant entry, otherwise, it is a hole.
+ struct ItemBucket {
+ /// FullHashValue - This remembers the full hash value of the key for
+ /// easy scanning.
+ unsigned FullHashValue;
+
+ /// Item - This is a pointer to the actual item object.
+ StringMapEntryBase *Item;
+ };
+
+protected:
+ ItemBucket *TheTable;
+ unsigned NumBuckets;
+ unsigned NumItems;
+ unsigned NumTombstones;
+ unsigned ItemSize;
+protected:
+ StringMapImpl(unsigned itemSize) : ItemSize(itemSize) { init(16); }
+ StringMapImpl(unsigned InitSize, unsigned ItemSize);
+ void RehashTable();
+
+ /// ShouldRehash - Return true if the table should be rehashed after a new
+ /// element was recently inserted.
+ bool ShouldRehash() const {
+ // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow the table.
+ return NumItems*4 > NumBuckets*3 ||
+ NumBuckets-(NumItems+NumTombstones) < NumBuckets/8;
+ }
+
+ /// LookupBucketFor - Look up the bucket that the specified string should end
+ /// up in. If it already exists as a key in the map, the Item pointer for the
+ /// specified bucket will be non-null. Otherwise, it will be null. In either
+ /// case, the FullHashValue field of the bucket will be set to the hash value
+ /// of the string.
+ unsigned LookupBucketFor(const char *KeyStart, const char *KeyEnd);
+
+ /// FindKey - Look up the bucket that contains the specified key. If it exists
+ /// in the map, return the bucket number of the key. Otherwise return -1.
+ /// This does not modify the map.
+ int FindKey(const char *KeyStart, const char *KeyEnd) const;
+
+ /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
+ /// delete it. This aborts if the value isn't in the table.
+ void RemoveKey(StringMapEntryBase *V);
+
+ /// RemoveKey - Remove the StringMapEntry for the specified key from the
+ /// table, returning it. If the key is not in the table, this returns null.
+ StringMapEntryBase *RemoveKey(const char *KeyStart, const char *KeyEnd);
+private:
+ void init(unsigned Size);
+public:
+ static StringMapEntryBase *getTombstoneVal() {
+ return (StringMapEntryBase*)-1;
+ }
+
+ unsigned getNumBuckets() const { return NumBuckets; }
+ unsigned getNumItems() const { return NumItems; }
+
+ bool empty() const { return NumItems == 0; }
+ unsigned size() const { return NumItems; }
+};
+
+/// StringMapEntry - This is used to represent one value that is inserted into
+/// a StringMap. It contains the Value itself and the key: the string length
+/// and data.
+template<typename ValueTy>
+class StringMapEntry : public StringMapEntryBase {
+ ValueTy Val;
+public:
+ StringMapEntry(unsigned StrLen)
+ : StringMapEntryBase(StrLen), Val() {}
+ StringMapEntry(unsigned StrLen, const ValueTy &V)
+ : StringMapEntryBase(StrLen), Val(V) {}
+
+ const ValueTy &getValue() const { return Val; }
+ ValueTy &getValue() { return Val; }
+
+ void setValue(const ValueTy &V) { Val = V; }
+
+ /// getKeyData - Return the start of the string data that is the key for this
+ /// value. The string data is always stored immediately after the
+ /// StringMapEntry object.
+ const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
+
+ /// Create - Create a StringMapEntry for the specified key and default
+ /// construct the value.
+ template<typename AllocatorTy>
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd,
+ AllocatorTy &Allocator) {
+ unsigned KeyLength = KeyEnd-KeyStart;
+
+ // Okay, the item doesn't already exist, and 'Bucket' is the bucket to fill
+ // in. Allocate a new item with space for the string at the end and a null
+ // terminator.
+ unsigned AllocSize = sizeof(StringMapEntry)+KeyLength+1;
+
+#ifdef __GNUC__
+ unsigned Alignment = __alignof__(StringMapEntry);
+#else
+ // FIXME: ugly.
+ unsigned Alignment = 8;
+#endif
+ StringMapEntry *NewItem =
+ static_cast<StringMapEntry*>(Allocator.Allocate(AllocSize, Alignment));
+
+ // Default construct the value.
+ new (NewItem) StringMapEntry(KeyLength);
+
+ // Copy the string information.
+ char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
+ memcpy(StrBuffer, KeyStart, KeyLength);
+ StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
+ return NewItem;
+ }
+
+ /// Create - Create a StringMapEntry with normal malloc/free.
+ static StringMapEntry *Create(const char *KeyStart, const char *KeyEnd) {
+ MallocAllocator A;
+ return Create(KeyStart, KeyEnd, A);
+ }
+
+ /// Destroy - Destroy this StringMapEntry, releasing memory back to the
+ /// specified allocator.
+ template<typename AllocatorTy>
+ void Destroy(AllocatorTy &Allocator) {
+ // Free memory referenced by the item.
+ this->~StringMapEntry();
+ Allocator.Deallocate(this);
+ }
+
+ /// Destroy this object, releasing memory back to the malloc allocator.
+ void Destroy() {
+ MallocAllocator A;
+ Destroy(A);
+ }
+};
+
+
+/// StringMap - This is an unconventional map that is specialized for handling
+/// keys that are "strings", which are basically ranges of bytes. This does some
+/// funky memory allocation and hashing things to make it extremely efficient,
+/// storing the string data *after* the value in the map.
+template<typename ValueTy, typename AllocatorTy = MallocAllocator>
+class StringMap : public StringMapImpl {
+ AllocatorTy Allocator;
+ typedef StringMapEntry<ValueTy> MapEntryTy;
+public:
+ StringMap() : StringMapImpl(sizeof(MapEntryTy)) {}
+ StringMap(unsigned InitialSize)
+ : StringMapImpl(InitialSize, sizeof(MapEntryTy)) {}
+
+ AllocatorTy &getAllocator() { return Allocator; }
+ const AllocatorTy &getAllocator() const { return Allocator; }
+
+ typedef StringMapConstIterator<ValueTy> const_iterator;
+ typedef StringMapIterator<ValueTy> iterator;
+
+ iterator begin() {
+ return iterator(TheTable, NumBuckets == 0);
+ }
+ iterator end() {
+ return iterator(TheTable+NumBuckets, true);
+ }
+ const_iterator begin() const {
+ return const_iterator(TheTable, NumBuckets == 0);
+ }
+ const_iterator end() const {
+ return const_iterator(TheTable+NumBuckets, true);
+ }
+
+ iterator find(const char *KeyStart, const char *KeyEnd) {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return iterator(TheTable+Bucket);
+ }
+
+ const_iterator find(const char *KeyStart, const char *KeyEnd) const {
+ int Bucket = FindKey(KeyStart, KeyEnd);
+ if (Bucket == -1) return end();
+ return const_iterator(TheTable+Bucket);
+ }
+
+ /// insert - Insert the specified key/value pair into the map. If the key
+ /// already exists in the map, return false and ignore the request, otherwise
+ /// insert it and return true.
+ bool insert(MapEntryTy *KeyValue) {
+ unsigned BucketNo =
+ LookupBucketFor(KeyValue->getKeyData(),
+ KeyValue->getKeyData()+KeyValue->getKeyLength());
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return false; // Already exists in map.
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ Bucket.Item = KeyValue;
+ ++NumItems;
+
+ if (ShouldRehash())
+ RehashTable();
+ return true;
+ }
+
+ /// GetOrCreateValue - Look up the specified key in the table. If a value
+ /// exists, return it. Otherwise, default construct a value, insert it, and
+ /// return.
+ StringMapEntry<ValueTy> &GetOrCreateValue(const char *KeyStart,
+ const char *KeyEnd) {
+ unsigned BucketNo = LookupBucketFor(KeyStart, KeyEnd);
+ ItemBucket &Bucket = TheTable[BucketNo];
+ if (Bucket.Item && Bucket.Item != getTombstoneVal())
+ return *static_cast<MapEntryTy*>(Bucket.Item);
+
+ MapEntryTy *NewItem = MapEntryTy::Create(KeyStart, KeyEnd, Allocator);
+
+ if (Bucket.Item == getTombstoneVal())
+ --NumTombstones;
+ ++NumItems;
+
+ // Fill in the bucket for the hash table. The FullHashValue was already
+ // filled in by LookupBucketFor.
+ Bucket.Item = NewItem;
+
+ if (ShouldRehash())
+ RehashTable();
+ return *NewItem;
+ }
+
+ /// remove - Remove the specified key/value pair from the map, but do not
+ /// erase it. This aborts if the key is not in the map.
+ void remove(MapEntryTy *KeyValue) {
+ RemoveKey(KeyValue);
+ }
+
+ ~StringMap() {
+ for (ItemBucket *I = TheTable, *E = TheTable+NumBuckets; I != E; ++I) {
+ if (I->Item && I->Item != getTombstoneVal())
+ static_cast<MapEntryTy*>(I->Item)->Destroy(Allocator);
+ }
+ free(TheTable);
+ }
+};
+
+
+template<typename ValueTy>
+class StringMapConstIterator {
+protected:
+ StringMapImpl::ItemBucket *Ptr;
+public:
+ StringMapConstIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : Ptr(Bucket) {
+ if (!NoAdvance) AdvancePastEmptyBuckets();
+ }
+
+ const StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+ const StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(Ptr->Item);
+ }
+
+ bool operator==(const StringMapConstIterator &RHS) const {
+ return Ptr == RHS.Ptr;
+ }
+ bool operator!=(const StringMapConstIterator &RHS) const {
+ return Ptr != RHS.Ptr;
+ }
+
+ inline StringMapConstIterator& operator++() { // Preincrement
+ ++Ptr;
+ AdvancePastEmptyBuckets();
+ return *this;
+ }
+ StringMapConstIterator operator++(int) { // Postincrement
+ StringMapConstIterator tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ void AdvancePastEmptyBuckets() {
+ while (Ptr->Item == 0 || Ptr->Item == StringMapImpl::getTombstoneVal())
+ ++Ptr;
+ }
+};
+
+template<typename ValueTy>
+class StringMapIterator : public StringMapConstIterator<ValueTy> {
+public:
+ StringMapIterator(StringMapImpl::ItemBucket *Bucket,
+ bool NoAdvance = false)
+ : StringMapConstIterator<ValueTy>(Bucket, NoAdvance) {
+ }
+ StringMapEntry<ValueTy> &operator*() const {
+ return *static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+ StringMapEntry<ValueTy> *operator->() const {
+ return static_cast<StringMapEntry<ValueTy>*>(this->Ptr->Item);
+ }
+};
+
+}
+
+#endif
+
diff --git a/include/llvm/ADT/Tree.h b/include/llvm/ADT/Tree.h
new file mode 100644
index 0000000..835a001
--- /dev/null
+++ b/include/llvm/ADT/Tree.h
@@ -0,0 +1,62 @@
+//===- llvm/ADT/Tree.h - Generic n-way tree structure -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines a generic N way tree node structure. The tree structure
+// is immutable after creation, but the payload contained within it is not.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_TREE_H
+#define LLVM_ADT_TREE_H
+
+#include <vector>
+
+namespace llvm {
+
+template<class ConcreteTreeNode, class Payload>
+class Tree {
+ std::vector<ConcreteTreeNode*> Children; // This nodes children, if any
+ ConcreteTreeNode *Parent; // Parent of this node...
+ Payload Data; // Data held in this node...
+
+protected:
+ void setChildren(const std::vector<ConcreteTreeNode*> &children) {
+ Children = children;
+ }
+public:
+ inline Tree(ConcreteTreeNode *parent) : Parent(parent) {}
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par) : Children(children), Parent(par) {}
+
+ inline Tree(const std::vector<ConcreteTreeNode*> &children,
+ ConcreteTreeNode *par, const Payload &data)
+ : Children(children), Parent(par), Data(data) {}
+
+ // Tree dtor - Free all children
+ inline ~Tree() {
+ for (unsigned i = Children.size(); i > 0; --i)
+ delete Children[i-1];
+ }
+
+ // Tree manipulation/walking routines...
+ inline ConcreteTreeNode *getParent() const { return Parent; }
+ inline unsigned getNumChildren() const { return Children.size(); }
+ inline ConcreteTreeNode *getChild(unsigned i) const {
+ assert(i < Children.size() && "Tree::getChild with index out of range!");
+ return Children[i];
+ }
+
+ // Payload access...
+ inline Payload &getTreeData() { return Data; }
+ inline const Payload &getTreeData() const { return Data; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/UniqueVector.h b/include/llvm/ADT/UniqueVector.h
new file mode 100644
index 0000000..f3fd7b1
--- /dev/null
+++ b/include/llvm/ADT/UniqueVector.h
@@ -0,0 +1,89 @@
+//===-- llvm/ADT/UniqueVector.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_UNIQUEVECTOR_H
+#define LLVM_ADT_UNIQUEVECTOR_H
+
+#include <cassert>
+#include <map>
+#include <vector>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+/// UniqueVector - This class produces a sequential ID number (base 1) for each
+/// unique entry that is added. T is the type of entries in the vector. This
+/// class should have an implementation of operator== and of operator<.
+/// Entries can be fetched using operator[] with the entry ID.
+template<class T> class UniqueVector {
+private:
+ // Map - Used to handle the correspondence of entry to ID.
+ std::map<T, unsigned> Map;
+
+ // Vector - ID ordered vector of entries. Entries can be indexed by ID - 1.
+ //
+ std::vector<T> Vector;
+
+public:
+ /// insert - Append entry to the vector if it doesn't already exist. Returns
+ /// the entry's index + 1 to be used as a unique ID.
+ unsigned insert(const T &Entry) {
+ // Check if the entry is already in the map.
+ unsigned &Val = Map[Entry];
+
+ // See if entry exists, if so return prior ID.
+ if (Val) return Val;
+
+ // Compute ID for entry.
+ Val = Vector.size() + 1;
+
+ // Insert in vector.
+ Vector.push_back(Entry);
+ return Val;
+ }
+
+ /// idFor - return the ID for an existing entry. Returns 0 if the entry is
+ /// not found.
+ unsigned idFor(const T &Entry) const {
+ // Search for entry in the map.
+ typename std::map<T, unsigned>::const_iterator MI = Map.find(Entry);
+
+ // See if entry exists, if so return ID.
+ if (MI != Map.end()) return MI->second;
+
+ // No luck.
+ return 0;
+ }
+
+ /// operator[] - Returns a reference to the entry with the specified ID.
+ ///
+ const T &operator[](unsigned ID) const {
+ assert(ID-1 < size() && "ID is 0 or out of range!");
+ return Vector[ID - 1];
+ }
+
+ /// size - Returns the number of entries in the vector.
+ ///
+ size_t size() const { return Vector.size(); }
+
+ /// empty - Returns true if the vector is empty.
+ ///
+ bool empty() const { return Vector.empty(); }
+
+ /// reset - Clears all the entries.
+ ///
+ void reset() {
+ Map.clear();
+ Vector.resize(0, 0);
+ }
+};
+
+} // End of namespace llvm
+
+#endif // LLVM_ADT_UNIQUEVECTOR_H
diff --git a/include/llvm/ADT/VectorExtras.h b/include/llvm/ADT/VectorExtras.h
new file mode 100644
index 0000000..bda2ae6
--- /dev/null
+++ b/include/llvm/ADT/VectorExtras.h
@@ -0,0 +1,41 @@
+//===-- llvm/ADT/VectorExtras.h - Helpers for std::vector -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains helper functions which are useful for working with the
+// std::vector class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_VECTOREXTRAS_H
+#define LLVM_ADT_VECTOREXTRAS_H
+
+#include <cstdarg>
+#include <vector>
+
+namespace llvm {
+
+/// make_vector - Helper function which is useful for building temporary vectors
+/// to pass into type construction of CallInst ctors. This turns a null
+/// terminated list of pointers (or other value types) into a real live vector.
+///
+template<typename T>
+inline std::vector<T> make_vector(T A, ...) {
+ va_list Args;
+ va_start(Args, A);
+ std::vector<T> Result;
+ Result.push_back(A);
+ while (T Val = va_arg(Args, T))
+ Result.push_back(Val);
+ va_end(Args);
+ return Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ADT/hash_map.in b/include/llvm/ADT/hash_map.in
new file mode 100644
index 0000000..fe5c393
--- /dev/null
+++ b/include/llvm/ADT/hash_map.in
@@ -0,0 +1,150 @@
+//===-- llvm/ADT/hash_map - "Portable" wrapper around hash_map --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <hash_map> header file
+// that seems to move around between GCC releases into and out of namespaces at
+// will. #including this header will cause hash_map to be available in the
+// global namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASH_MAP
+#define LLVM_ADT_HASH_MAP
+
+// Compiler Support Matrix
+//
+// Version Namespace Header File
+// 2.95.x :: hash_map
+// 3.0.4 std ext/hash_map
+// 3.1 __gnu_cxx ext/hash_map
+// HP aCC6 std stdex/rw/hashm*ap.h
+// MS VC++ stdext hash_map
+
+#undef HAVE_GNU_EXT_HASH_MAP
+#undef HAVE_STD_EXT_HASH_MAP
+#undef HAVE_GLOBAL_HASH_MAP
+#undef HAVE_RW_STDEX_HASH_MAP_H
+
+#if HAVE_GNU_EXT_HASH_MAP
+// This is for GCC-3.1+ which puts hash in ext/hash_map
+# include <ext/hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE __gnu_cxx
+# endif
+
+// GCC 3.0.x puts hash_map in <ext/hash_map> and in the std namespace.
+#elif HAVE_STD_EXT_HASH_MAP
+# include <ext/hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Older compilers such as GCC before version 3.0 do not keep
+// extensions in the `ext' directory, and ignore the `std' namespace.
+#elif HAVE_GLOBAL_HASH_MAP
+# include <hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// HP aCC doesn't include an SGI-like hash_map. For this platform (or
+// any others using Rogue Wave Software's Tools.h++ library), we wrap
+// around them in std::
+#elif HAVE_RW_STDEX_HASH_MAP_H
+# include <rw/stdex/hashmap.h>
+# include <rw/stdex/hashmmap.h>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Support Microsoft VC++.
+#elif defined(_MSC_VER)
+# include <hash_map>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE stdext
+ using std::_Distance;
+# endif
+
+// Give a warning if we couldn't find it, instead of (or in addition to)
+// randomly doing something dumb.
+#else
+# warning "Autoconfiguration failed to find the hash_map header file."
+#endif
+
+// we wrap Rogue Wave Tools.h++ rw_hashmap into something SGI-looking, here:
+#ifdef HAVE_RW_STDEX_HASH_MAP_H
+namespace HASH_NAMESPACE {
+
+template <class DataType> struct hash {
+ unsigned int operator()(const unsigned int& x) const {
+ return x;
+ }
+};
+
+template <typename KeyType,
+ typename ValueType,
+ class _HashFcn = hash<KeyType>,
+ class _EqualKey = equal_to<KeyType>,
+ class _A = allocator <ValueType> >
+class hash_map : public rw_hashmap<KeyType, ValueType, class _HashFcn,
+ class _EqualKey, class _A> {
+};
+
+template <typename KeyType,
+ typename ValueType,
+ class _HashFcn = hash<KeyType>,
+ class _EqualKey = equal_to<KeyType>,
+ class _A = allocator <ValueType> >
+class hash_multimap : public rw_hashmultimap<KeyType, ValueType, class _HashFcn,
+ class _EqualKey, class _A> {
+};
+
+} // end HASH_NAMESPACE;
+#endif
+
+// Include vector because ext/hash_map includes stl_vector.h and leaves
+// out specializations like stl_bvector.h, causing link conflicts.
+#include <vector>
+
+#ifdef _MSC_VER
+
+// GCC and VC++ have differing ways of implementing hash_maps. As it's not
+// standardized, that's to be expected. This adapter class allows VC++
+// hash_map to use GCC's hash classes.
+namespace stdext {
+ template<class Key> struct hash;
+
+ // Provide a hash function for unsigned ints...
+ template<> struct hash<unsigned int> {
+ inline size_t operator()(unsigned int Val) const {
+ return Val;
+ }
+ };
+
+ template<class Key> class hash_compare<Key, std::less<Key> > {
+ std::less<Key> comp;
+ public:
+ enum { bucket_size = 4 };
+ enum { min_buckets = 8 };
+ hash_compare() {}
+ hash_compare(std::less<Key> pred) : comp(pred) {}
+ size_t operator()(const Key& key) const { return hash<Key>()(key); }
+ bool operator()(const Key& k1, const Key& k2) const { return comp(k1, k2); }
+ };
+}
+
+#endif
+
+using HASH_NAMESPACE::hash_map;
+using HASH_NAMESPACE::hash_multimap;
+using HASH_NAMESPACE::hash;
+
+#include "llvm/ADT/HashExtras.h"
+
+#endif
diff --git a/include/llvm/ADT/hash_set.in b/include/llvm/ADT/hash_set.in
new file mode 100644
index 0000000..aa27e5f
--- /dev/null
+++ b/include/llvm/ADT/hash_set.in
@@ -0,0 +1,111 @@
+//===-- llvm/ADT/hash_set - "Portable" wrapper around hash_set --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// vim:ft=cpp
+//
+// This file provides a wrapper around the mysterious <hash_set> header file
+// that seems to move around between GCC releases into and out of namespaces at
+// will. #including this header will cause hash_set to be available in the
+// global namespace.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_HASH_SET
+#define LLVM_ADT_HASH_SET
+
+// Compiler Support Matrix
+//
+// Version Namespace Header File
+// 2.95.x :: hash_set
+// 3.0.4 std ext/hash_set
+// 3.1 __gnu_cxx ext/hash_set
+// HP aCC6 std stdex/rw/hashset.h
+// MS VC++ stdext hash_set
+
+#undef HAVE_GNU_EXT_HASH_SET
+#undef HAVE_STD_EXT_HASH_SET
+#undef HAVE_GLOBAL_HASH_SET
+#undef HAVE_RW_STDEX_HASH_SET_H
+
+// GCC versions 3.1 and later put hash_set in <ext/hash_set> and in
+// the __gnu_cxx namespace.
+#if HAVE_GNU_EXT_HASH_SET
+# include <ext/hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE __gnu_cxx
+# endif
+
+// GCC 3.0.x puts hash_set in <ext/hash_set> and in the std namespace.
+#elif HAVE_STD_EXT_HASH_SET
+# include <ext/hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Older compilers such as GCC before version 3.0 do not keep
+// extensions in the `ext' directory, and ignore the `std' namespace.
+#elif HAVE_GLOBAL_HASH_SET
+# include <hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// HP aCC doesn't include an SGI-like hash_set. For this platform (or
+// any others using Rogue Wave Software's Tools.h++ library), we wrap
+// around them in std::
+#elif HAVE_RW_STDEX_HASH_SET_H
+# include <rw/stdex/hashset.h>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE std
+# endif
+
+// Support Microsoft VC++.
+#elif defined(_MSC_VER)
+# include <hash_set>
+# ifndef HASH_NAMESPACE
+# define HASH_NAMESPACE stdext
+# endif
+
+// Give a warning if we couldn't find it, instead of (or in addition to)
+// randomly doing something dumb.
+#else
+# warning "Autoconfiguration failed to find the hash_set header file."
+#endif
+
+// we wrap Rogue Wave Tools.h++ rw_hashset into something SGI-looking, here:
+#ifdef HAVE_RW_STDEX_HASH_SET_H
+namespace HASH_NAMESPACE {
+
+/*
+template <class DataType> struct hash {
+ unsigned int operator()(const unsigned int& x) const {
+ return x;
+ }
+};
+*/
+
+template <typename ValueType,
+ class _HashFcn = hash<ValueType>,
+ class _EqualKey = equal_to<ValueType>,
+ class _A = allocator <ValueType> >
+class hash_set :
+ public rw_hashset<ValueType, class _HashFcn, class _EqualKey, class _A> {
+};
+
+} // end HASH_NAMESPACE;
+#endif
+
+using HASH_NAMESPACE::hash_set;
+
+// Include vector because ext/hash_set includes stl_vector.h and leaves
+// out specializations like stl_bvector.h, causing link conflicts.
+#include <vector>
+
+#include "llvm/ADT/HashExtras.h"
+
+#endif
diff --git a/include/llvm/ADT/ilist b/include/llvm/ADT/ilist
new file mode 100644
index 0000000..5ca8f45
--- /dev/null
+++ b/include/llvm/ADT/ilist
@@ -0,0 +1,586 @@
+//===-- llvm/ADT/ilist - Intrusive Linked List Template ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes to implement an intrusive doubly linked list class
+// (i.e. each node of the list must contain a next and previous field for the
+// list.
+//
+// The ilist_traits trait class is used to gain access to the next and previous
+// fields of the node type that the list is instantiated with. If it is not
+// specialized, the list defaults to using the getPrev(), getNext() method calls
+// to get the next and previous pointers.
+//
+// The ilist class itself, should be a plug in replacement for list, assuming
+// that the nodes contain next/prev pointers. This list replacement does not
+// provides a constant time size() method, so be careful to use empty() when you
+// really want to know if it's empty.
+//
+// The ilist class is implemented by allocating a 'tail' node when the list is
+// created (using ilist_traits<>::createSentinel()). This tail node is
+// absolutely required because the user must be able to compute end()-1. Because
+// of this, users of the direct next/prev links will see an extra link on the
+// end of the list, which should be ignored.
+//
+// Requirements for a user of this list:
+//
+// 1. The user must provide {g|s}et{Next|Prev} methods, or specialize
+// ilist_traits to provide an alternate way of getting and setting next and
+// prev links.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ILIST
+#define LLVM_ADT_ILIST
+
+#include "llvm/ADT/iterator"
+#include <cassert>
+
+namespace llvm {
+
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+// Template traits for intrusive list. By specializing this template class, you
+// can change what next/prev fields are used to store the links...
+template<typename NodeTy>
+struct ilist_traits {
+ static NodeTy *getPrev(NodeTy *N) { return N->getPrev(); }
+ static NodeTy *getNext(NodeTy *N) { return N->getNext(); }
+ static const NodeTy *getPrev(const NodeTy *N) { return N->getPrev(); }
+ static const NodeTy *getNext(const NodeTy *N) { return N->getNext(); }
+
+ static void setPrev(NodeTy *N, NodeTy *Prev) { N->setPrev(Prev); }
+ static void setNext(NodeTy *N, NodeTy *Next) { N->setNext(Next); }
+
+ static NodeTy *createNode(const NodeTy &V) { return new NodeTy(V); }
+
+ static NodeTy *createSentinel() { return new NodeTy(); }
+ static void destroySentinel(NodeTy *N) { delete N; }
+
+ void addNodeToList(NodeTy *NTy) {}
+ void removeNodeFromList(NodeTy *NTy) {}
+ void transferNodesFromList(iplist<NodeTy, ilist_traits> &L2,
+ ilist_iterator<NodeTy> first,
+ ilist_iterator<NodeTy> last) {}
+};
+
+// Const traits are the same as nonconst traits...
+template<typename Ty>
+struct ilist_traits<const Ty> : public ilist_traits<Ty> {};
+
+
+//===----------------------------------------------------------------------===//
+// ilist_iterator<Node> - Iterator for intrusive list.
+//
+template<typename NodeTy>
+class ilist_iterator
+ : public bidirectional_iterator<NodeTy, ptrdiff_t> {
+ typedef ilist_traits<NodeTy> Traits;
+ typedef bidirectional_iterator<NodeTy, ptrdiff_t> super;
+
+public:
+ typedef size_t size_type;
+ typedef typename super::pointer pointer;
+ typedef typename super::reference reference;
+private:
+ pointer NodePtr;
+public:
+
+ ilist_iterator(pointer NP) : NodePtr(NP) {}
+ ilist_iterator(reference NR) : NodePtr(&NR) {}
+ ilist_iterator() : NodePtr(0) {}
+
+ // This is templated so that we can allow constructing a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ ilist_iterator(const ilist_iterator<node_ty> &RHS)
+ : NodePtr(RHS.getNodePtrUnchecked()) {}
+
+ // This is templated so that we can allow assigning to a const iterator from
+ // a nonconst iterator...
+ template<class node_ty>
+ const ilist_iterator &operator=(const ilist_iterator<node_ty> &RHS) {
+ NodePtr = RHS.getNodePtrUnchecked();
+ return *this;
+ }
+
+ // Accessors...
+ operator pointer() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return NodePtr;
+ }
+
+ reference operator*() const {
+ assert(Traits::getNext(NodePtr) != 0 && "Dereferencing end()!");
+ return *NodePtr;
+ }
+ pointer operator->() { return &operator*(); }
+ const pointer operator->() const { return &operator*(); }
+
+ // Comparison operators
+ bool operator==(const ilist_iterator &RHS) const {
+ return NodePtr == RHS.NodePtr;
+ }
+ bool operator!=(const ilist_iterator &RHS) const {
+ return NodePtr != RHS.NodePtr;
+ }
+
+ // Increment and decrement operators...
+ ilist_iterator &operator--() { // predecrement - Back up
+ NodePtr = Traits::getPrev(NodePtr);
+ assert(Traits::getNext(NodePtr) && "--'d off the beginning of an ilist!");
+ return *this;
+ }
+ ilist_iterator &operator++() { // preincrement - Advance
+ NodePtr = Traits::getNext(NodePtr);
+ assert(NodePtr && "++'d off the end of an ilist!");
+ return *this;
+ }
+ ilist_iterator operator--(int) { // postdecrement operators...
+ ilist_iterator tmp = *this;
+ --*this;
+ return tmp;
+ }
+ ilist_iterator operator++(int) { // postincrement operators...
+ ilist_iterator tmp = *this;
+ ++*this;
+ return tmp;
+ }
+
+ // Internal interface, do not use...
+ pointer getNodePtrUnchecked() const { return NodePtr; }
+};
+
+// do not implement. this is to catch errors when people try to use
+// them as random access iterators
+template<typename T>
+void operator-(int, ilist_iterator<T>);
+template<typename T>
+void operator-(ilist_iterator<T>,int);
+
+template<typename T>
+void operator+(int, ilist_iterator<T>);
+template<typename T>
+void operator+(ilist_iterator<T>,int);
+
+// operator!=/operator== - Allow mixed comparisons without dereferencing
+// the iterator, which could very likely be pointing to end().
+template<typename T>
+bool operator!=(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(const T* LHS, const ilist_iterator<const T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator!=(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS != RHS.getNodePtrUnchecked();
+}
+template<typename T>
+bool operator==(T* LHS, const ilist_iterator<T> &RHS) {
+ return LHS == RHS.getNodePtrUnchecked();
+}
+
+
+// Allow ilist_iterators to convert into pointers to a node automatically when
+// used by the dyn_cast, cast, isa mechanisms...
+
+template<typename From> struct simplify_type;
+
+template<typename NodeTy> struct simplify_type<ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
+ typedef NodeTy* SimpleType;
+
+ static SimpleType getSimplifiedValue(const ilist_iterator<NodeTy> &Node) {
+ return &*Node;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// iplist - The subset of list functionality that can safely be used on nodes of
+// polymorphic types, i.e. a heterogenous list with a common base class that
+// holds the next/prev pointers...
+//
+template<typename NodeTy, typename Traits=ilist_traits<NodeTy> >
+class iplist : public Traits {
+ NodeTy *Head;
+
+ // Use the prev node pointer of 'head' as the tail pointer. This is really a
+ // circularly linked list where we snip the 'next' link from the sentinel node
+ // back to the first node in the list (to preserve assertions about going off
+ // the end of the list).
+ NodeTy *getTail() { return getPrev(Head); }
+ const NodeTy *getTail() const { return getPrev(Head); }
+ void setTail(NodeTy *N) { setPrev(Head, N); }
+
+ static bool op_less(NodeTy &L, NodeTy &R) { return L < R; }
+ static bool op_equal(NodeTy &L, NodeTy &R) { return L == R; }
+public:
+ typedef NodeTy *pointer;
+ typedef const NodeTy *const_pointer;
+ typedef NodeTy &reference;
+ typedef const NodeTy &const_reference;
+ typedef NodeTy value_type;
+ typedef ilist_iterator<NodeTy> iterator;
+ typedef ilist_iterator<const NodeTy> const_iterator;
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iplist() : Head(Traits::createSentinel()) {
+ setNext(Head, 0);
+ setTail(Head);
+ }
+ ~iplist() { clear(); Traits::destroySentinel(getTail()); }
+
+ // Iterator creation methods.
+ iterator begin() { return iterator(Head); }
+ const_iterator begin() const { return const_iterator(Head); }
+ iterator end() { return iterator(getTail()); }
+ const_iterator end() const { return const_iterator(getTail()); }
+
+ // reverse iterator creation methods.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+
+ // Miscellaneous inspection routines.
+ size_type max_size() const { return size_type(-1); }
+ bool empty() const { return Head == getTail(); }
+
+ // Front and back accessor functions...
+ reference front() {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ const_reference front() const {
+ assert(!empty() && "Called front() on empty list!");
+ return *Head;
+ }
+ reference back() {
+ assert(!empty() && "Called back() on empty list!");
+ return *getPrev(getTail());
+ }
+ const_reference back() const {
+ assert(!empty() && "Called back() on empty list!");
+ return *getPrev(getTail());
+ }
+
+ void swap(iplist &RHS) {
+ abort(); // Swap does not use list traits callback correctly yet!
+ std::swap(Head, RHS.Head);
+ }
+
+ iterator insert(iterator where, NodeTy *New) {
+ NodeTy *CurNode = where.getNodePtrUnchecked(), *PrevNode = getPrev(CurNode);
+ setNext(New, CurNode);
+ setPrev(New, PrevNode);
+
+ if (CurNode != Head) // Is PrevNode off the beginning of the list?
+ setNext(PrevNode, New);
+ else
+ Head = New;
+ setPrev(CurNode, New);
+
+ addNodeToList(New); // Notify traits that we added a node...
+ return New;
+ }
+
+ NodeTy *remove(iterator &IT) {
+ assert(IT != end() && "Cannot remove end of list!");
+ NodeTy *Node = &*IT;
+ NodeTy *NextNode = getNext(Node);
+ NodeTy *PrevNode = getPrev(Node);
+
+ if (Node != Head) // Is PrevNode off the beginning of the list?
+ setNext(PrevNode, NextNode);
+ else
+ Head = NextNode;
+ setPrev(NextNode, PrevNode);
+ IT = NextNode;
+ removeNodeFromList(Node); // Notify traits that we removed a node...
+ return Node;
+ }
+
+ NodeTy *remove(const iterator &IT) {
+ iterator MutIt = IT;
+ return remove(MutIt);
+ }
+
+ // erase - remove a node from the controlled sequence... and delete it.
+ iterator erase(iterator where) {
+ delete remove(where);
+ return where;
+ }
+
+
+private:
+ // transfer - The heart of the splice function. Move linked list nodes from
+ // [first, last) into position.
+ //
+ void transfer(iterator position, iplist &L2, iterator first, iterator last) {
+ assert(first != last && "Should be checked by callers");
+
+ if (position != last) {
+ // Note: we have to be careful about the case when we move the first node
+ // in the list. This node is the list sentinel node and we can't move it.
+ NodeTy *ThisSentinel = getTail();
+ setTail(0);
+ NodeTy *L2Sentinel = L2.getTail();
+ L2.setTail(0);
+
+ // Remove [first, last) from its old position.
+ NodeTy *First = &*first, *Prev = getPrev(First);
+ NodeTy *Next = last.getNodePtrUnchecked(), *Last = getPrev(Next);
+ if (Prev)
+ setNext(Prev, Next);
+ else
+ L2.Head = Next;
+ setPrev(Next, Prev);
+
+ // Splice [first, last) into its new position.
+ NodeTy *PosNext = position.getNodePtrUnchecked();
+ NodeTy *PosPrev = getPrev(PosNext);
+
+ // Fix head of list...
+ if (PosPrev)
+ setNext(PosPrev, First);
+ else
+ Head = First;
+ setPrev(First, PosPrev);
+
+ // Fix end of list...
+ setNext(Last, PosNext);
+ setPrev(PosNext, Last);
+
+ transferNodesFromList(L2, First, PosNext);
+
+ // Now that everything is set, restore the pointers to the list sentinals.
+ L2.setTail(L2Sentinel);
+ setTail(ThisSentinel);
+ }
+ }
+
+public:
+
+ //===----------------------------------------------------------------------===
+ // Functionality derived from other functions defined above...
+ //
+
+ size_type size() const {
+#if __GNUC__ == 2
+ // GCC 2.95 has a broken std::distance
+ size_type Result = 0;
+ std::distance(begin(), end(), Result);
+ return Result;
+#else
+ return std::distance(begin(), end());
+#endif
+ }
+
+ iterator erase(iterator first, iterator last) {
+ while (first != last)
+ first = erase(first);
+ return last;
+ }
+
+ void clear() { erase(begin(), end()); }
+
+ // Front and back inserters...
+ void push_front(NodeTy *val) { insert(begin(), val); }
+ void push_back(NodeTy *val) { insert(end(), val); }
+ void pop_front() {
+ assert(!empty() && "pop_front() on empty list!");
+ erase(begin());
+ }
+ void pop_back() {
+ assert(!empty() && "pop_back() on empty list!");
+ iterator t = end(); erase(--t);
+ }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+
+ // Splice members - defined in terms of transfer...
+ void splice(iterator where, iplist &L2) {
+ if (!L2.empty())
+ transfer(where, L2, L2.begin(), L2.end());
+ }
+ void splice(iterator where, iplist &L2, iterator first) {
+ iterator last = first; ++last;
+ if (where == first || where == last) return; // No change
+ transfer(where, L2, first, last);
+ }
+ void splice(iterator where, iplist &L2, iterator first, iterator last) {
+ if (first != last) transfer(where, L2, first, last);
+ }
+
+
+
+ //===----------------------------------------------------------------------===
+ // High-Level Functionality that shouldn't really be here, but is part of list
+ //
+
+ // These two functions are actually called remove/remove_if in list<>, but
+ // they actually do the job of erase, rename them accordingly.
+ //
+ void erase(const NodeTy &val) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (*I == val) erase(I);
+ I = next;
+ }
+ }
+ template<class Pr1> void erase_if(Pr1 pred) {
+ for (iterator I = begin(), E = end(); I != E; ) {
+ iterator next = I; ++next;
+ if (pred(*I)) erase(I);
+ I = next;
+ }
+ }
+
+ template<class Pr2> void unique(Pr2 pred) {
+ if (empty()) return;
+ for (iterator I = begin(), E = end(), Next = begin(); ++Next != E;) {
+ if (pred(*I))
+ erase(Next);
+ else
+ I = Next;
+ Next = I;
+ }
+ }
+ void unique() { unique(op_equal); }
+
+ template<class Pr3> void merge(iplist &right, Pr3 pred) {
+ iterator first1 = begin(), last1 = end();
+ iterator first2 = right.begin(), last2 = right.end();
+ while (first1 != last1 && first2 != last2)
+ if (pred(*first2, *first1)) {
+ iterator next = first2;
+ transfer(first1, right, first2, ++next);
+ first2 = next;
+ } else {
+ ++first1;
+ }
+ if (first2 != last2) transfer(last1, right, first2, last2);
+ }
+ void merge(iplist &right) { return merge(right, op_less); }
+
+ template<class Pr3> void sort(Pr3 pred);
+ void sort() { sort(op_less); }
+ void reverse();
+};
+
+
+template<typename NodeTy>
+struct ilist : public iplist<NodeTy> {
+ typedef typename iplist<NodeTy>::size_type size_type;
+ typedef typename iplist<NodeTy>::iterator iterator;
+
+ ilist() {}
+ ilist(const ilist &right) {
+ insert(this->begin(), right.begin(), right.end());
+ }
+ explicit ilist(size_type count) {
+ insert(this->begin(), count, NodeTy());
+ }
+ ilist(size_type count, const NodeTy &val) {
+ insert(this->begin(), count, val);
+ }
+ template<class InIt> ilist(InIt first, InIt last) {
+ insert(this->begin(), first, last);
+ }
+
+
+ // Forwarding functions: A workaround for GCC 2.95 which does not correctly
+ // support 'using' declarations to bring a hidden member into scope.
+ //
+ iterator insert(iterator a, NodeTy *b){ return iplist<NodeTy>::insert(a, b); }
+ void push_front(NodeTy *a) { iplist<NodeTy>::push_front(a); }
+ void push_back(NodeTy *a) { iplist<NodeTy>::push_back(a); }
+
+
+ // Main implementation here - Insert for a node passed by value...
+ iterator insert(iterator where, const NodeTy &val) {
+ return insert(where, createNode(val));
+ }
+
+
+ // Front and back inserters...
+ void push_front(const NodeTy &val) { insert(this->begin(), val); }
+ void push_back(const NodeTy &val) { insert(this->end(), val); }
+
+ // Special forms of insert...
+ template<class InIt> void insert(iterator where, InIt first, InIt last) {
+ for (; first != last; ++first) insert(where, *first);
+ }
+ void insert(iterator where, size_type count, const NodeTy &val) {
+ for (; count != 0; --count) insert(where, val);
+ }
+
+ // Assign special forms...
+ void assign(size_type count, const NodeTy &val) {
+ iterator I = this->begin();
+ for (; I != this->end() && count != 0; ++I, --count)
+ *I = val;
+ if (count != 0)
+ insert(this->end(), val, val);
+ else
+ erase(I, this->end());
+ }
+ template<class InIt> void assign(InIt first1, InIt last1) {
+ iterator first2 = this->begin(), last2 = this->end();
+ for ( ; first1 != last1 && first2 != last2; ++first1, ++first2)
+ *first1 = *first2;
+ if (first2 == last2)
+ erase(first1, last1);
+ else
+ insert(last1, first2, last2);
+ }
+
+
+ // Resize members...
+ void resize(size_type newsize, NodeTy val) {
+ iterator i = this->begin();
+ size_type len = 0;
+ for ( ; i != this->end() && len < newsize; ++i, ++len) /* empty*/ ;
+
+ if (len == newsize)
+ erase(i, this->end());
+ else // i == end()
+ insert(this->end(), newsize - len, val);
+ }
+ void resize(size_type newsize) { resize(newsize, NodeTy()); }
+};
+
+} // End llvm namespace
+
+namespace std {
+ // Ensure that swap uses the fast list swap...
+ template<class Ty>
+ void swap(llvm::iplist<Ty> &Left, llvm::iplist<Ty> &Right) {
+ Left.swap(Right);
+ }
+} // End 'std' extensions...
+
+#endif
diff --git a/include/llvm/ADT/iterator.in b/include/llvm/ADT/iterator.in
new file mode 100644
index 0000000..47f70d1
--- /dev/null
+++ b/include/llvm/ADT/iterator.in
@@ -0,0 +1,76 @@
+//===-- llvm/ADT/iterator - Portable wrapper around <iterator> --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a wrapper around the mysterious <iterator> header file.
+// In GCC 2.95.3, the file defines a bidirectional_iterator class (and other
+// friends), instead of the standard iterator class. In GCC 3.1, the
+// bidirectional_iterator class got moved out and the new, standards compliant,
+// iterator<> class was added. Because there is nothing that we can do to get
+// correct behavior on both compilers, we have this header with #ifdef's. Gross
+// huh?
+//
+// By #includ'ing this file, you get the contents of <iterator> plus the
+// following classes in the global namespace:
+//
+// 1. bidirectional_iterator
+// 2. forward_iterator
+//
+// The #if directives' expressions are filled in by Autoconf.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ADT_ITERATOR
+#define LLVM_ADT_ITERATOR
+
+#include <iterator>
+
+#undef HAVE_BI_ITERATOR
+#undef HAVE_STD_ITERATOR
+#undef HAVE_FWD_ITERATOR
+
+#ifdef _MSC_VER
+# define HAVE_BI_ITERATOR 0
+# define HAVE_STD_ITERATOR 1
+# define HAVE_FWD_ITERATOR 0
+#endif
+
+#if !HAVE_BI_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the bidirectional iterator is not defined, we attempt to define it in
+/// terms of the C++ standard iterator. Otherwise, we import it with a "using"
+/// statement.
+///
+template<class Ty, class PtrDiffTy>
+struct bidirectional_iterator
+ : public std::iterator<std::bidirectional_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define bidirectional iterator!"
+# endif
+#else
+using std::bidirectional_iterator;
+#endif
+
+#if !HAVE_FWD_ITERATOR
+# if HAVE_STD_ITERATOR
+/// If the forward iterator is not defined, attempt to define it in terms of
+/// the C++ standard iterator. Otherwise, we import it with a "using" statement.
+///
+template<class Ty, class PtrDiffTy>
+struct forward_iterator
+ : public std::iterator<std::forward_iterator_tag, Ty, PtrDiffTy> {
+};
+# else
+# error "Need to have standard iterator to define forward iterator!"
+# endif
+#else
+using std::forward_iterator;
+#endif
+
+#endif
diff --git a/include/llvm/AbstractTypeUser.h b/include/llvm/AbstractTypeUser.h
new file mode 100644
index 0000000..2b643ab
--- /dev/null
+++ b/include/llvm/AbstractTypeUser.h
@@ -0,0 +1,179 @@
+//===-- llvm/AbstractTypeUser.h - AbstractTypeUser Interface ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the AbstractTypeUser class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ABSTRACT_TYPE_USER_H
+#define LLVM_ABSTRACT_TYPE_USER_H
+
+#if !defined(LLVM_TYPE_H) && !defined(LLVM_VALUE_H)
+#error Do not include this file directly. Include Type.h instead.
+#error Some versions of GCC (e.g. 3.4 and 4.1) can not handle the inlined method
+#error PATypeHolder::dropRef() correctly otherwise.
+#endif
+
+// This is the "master" include for <cassert> Whether this file needs it or not,
+// it must always include <cassert> for the files which include
+// llvm/AbstractTypeUser.h
+//
+// In this way, most every LLVM source file will have access to the assert()
+// macro without having to #include <cassert> directly.
+//
+#include <cassert>
+
+namespace llvm {
+
+class Type;
+class DerivedType;
+
+/// The AbstractTypeUser class is an interface to be implemented by classes who
+/// could possibly use an abstract type. Abstract types are denoted by the
+/// isAbstract flag set to true in the Type class. These are classes that
+/// contain an Opaque type in their structure somewhere.
+///
+/// Classes must implement this interface so that they may be notified when an
+/// abstract type is resolved. Abstract types may be resolved into more
+/// concrete types through: linking, parsing, and bitcode reading. When this
+/// happens, all of the users of the type must be updated to reference the new,
+/// more concrete type. They are notified through the AbstractTypeUser
+/// interface.
+///
+/// In addition to this, AbstractTypeUsers must keep the use list of the
+/// potentially abstract type that they reference up-to-date. To do this in a
+/// nice, transparent way, the PATypeHandle class is used to hold "Potentially
+/// Abstract Types", and keep the use list of the abstract types up-to-date.
+/// @brief LLVM Abstract Type User Representation
+class AbstractTypeUser {
+protected:
+ virtual ~AbstractTypeUser(); // Derive from me
+public:
+
+ /// refineAbstractType - The callback method invoked when an abstract type is
+ /// resolved to another type. An object must override this method to update
+ /// its internal state to reference NewType instead of OldType.
+ ///
+ virtual void refineAbstractType(const DerivedType *OldTy,
+ const Type *NewTy) = 0;
+
+ /// The other case which AbstractTypeUsers must be aware of is when a type
+ /// makes the transition from being abstract (where it has clients on it's
+ /// AbstractTypeUsers list) to concrete (where it does not). This method
+ /// notifies ATU's when this occurs for a type.
+ ///
+ virtual void typeBecameConcrete(const DerivedType *AbsTy) = 0;
+
+ // for debugging...
+ virtual void dump() const = 0;
+};
+
+
+/// PATypeHandle - Handle to a Type subclass. This class is used to keep the
+/// use list of abstract types up-to-date.
+///
+class PATypeHandle {
+ const Type *Ty;
+ AbstractTypeUser * const User;
+
+ // These functions are defined at the bottom of Type.h. See the comment there
+ // for justification.
+ void addUser();
+ void removeUser();
+public:
+ // ctor - Add use to type if abstract. Note that Ty must not be null
+ inline PATypeHandle(const Type *ty, AbstractTypeUser *user)
+ : Ty(ty), User(user) {
+ addUser();
+ }
+
+ // ctor - Add use to type if abstract.
+ inline PATypeHandle(const PATypeHandle &T) : Ty(T.Ty), User(T.User) {
+ addUser();
+ }
+
+ // dtor - Remove reference to type...
+ inline ~PATypeHandle() { removeUser(); }
+
+ // Automatic casting operator so that the handle may be used naturally
+ inline operator Type *() const { return const_cast<Type*>(Ty); }
+ inline Type *get() const { return const_cast<Type*>(Ty); }
+
+ // operator= - Allow assignment to handle
+ inline Type *operator=(const Type *ty) {
+ if (Ty != ty) { // Ensure we don't accidentally drop last ref to Ty
+ removeUser();
+ Ty = ty;
+ addUser();
+ }
+ return get();
+ }
+
+ // operator= - Allow assignment to handle
+ inline const Type *operator=(const PATypeHandle &T) {
+ return operator=(T.Ty);
+ }
+
+ inline bool operator==(const Type *ty) {
+ return Ty == ty;
+ }
+
+ // operator-> - Allow user to dereference handle naturally...
+ inline const Type *operator->() const { return Ty; }
+};
+
+
+/// PATypeHolder - Holder class for a potentially abstract type. This uses
+/// efficient union-find techniques to handle dynamic type resolution. Unless
+/// you need to do custom processing when types are resolved, you should always
+/// use PATypeHolders in preference to PATypeHandles.
+///
+class PATypeHolder {
+ mutable const Type *Ty;
+public:
+ PATypeHolder(const Type *ty) : Ty(ty) {
+ addRef();
+ }
+ PATypeHolder(const PATypeHolder &T) : Ty(T.Ty) {
+ addRef();
+ }
+
+ ~PATypeHolder() { dropRef(); }
+
+ operator Type *() const { return get(); }
+ Type *get() const;
+
+ // operator-> - Allow user to dereference handle naturally...
+ Type *operator->() const { return get(); }
+
+ // operator= - Allow assignment to handle
+ Type *operator=(const Type *ty) {
+ if (Ty != ty) { // Don't accidentally drop last ref to Ty.
+ dropRef();
+ Ty = ty;
+ addRef();
+ }
+ return get();
+ }
+ Type *operator=(const PATypeHolder &H) {
+ return operator=(H.Ty);
+ }
+
+ /// getRawType - This should only be used to implement the vmcore library.
+ ///
+ const Type *getRawType() const { return Ty; }
+
+private:
+ void addRef();
+ void dropRef();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
new file mode 100644
index 0000000..1cd6afc
--- /dev/null
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -0,0 +1,332 @@
+//===- llvm/Analysis/AliasAnalysis.h - Alias Analysis Interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the generic AliasAnalysis interface, which is used as the
+// common interface used by all clients of alias analysis information, and
+// implemented by all alias analysis implementations. Mod/Ref information is
+// also captured by this interface.
+//
+// Implementations of this interface must implement the various virtual methods,
+// which automatically provides functionality for the entire suite of client
+// APIs.
+//
+// This API represents memory as a (Pointer, Size) pair. The Pointer component
+// specifies the base memory address of the region, the Size specifies how large
+// of an area is being queried. If Size is 0, two pointers only alias if they
+// are exactly equal. If size is greater than zero, but small, the two pointers
+// alias if the areas pointed to overlap. If the size is very large (ie, ~0U),
+// then the two pointers alias if they may be pointing to components of the same
+// memory object. Pointers that point to two completely different objects in
+// memory never alias, regardless of the value of the Size component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIAS_ANALYSIS_H
+#define LLVM_ANALYSIS_ALIAS_ANALYSIS_H
+
+#include "llvm/Support/CallSite.h"
+#include "llvm/System/IncludeFile.h"
+#include <vector>
+
+namespace llvm {
+
+class LoadInst;
+class StoreInst;
+class VAArgInst;
+class TargetData;
+class Pass;
+class AnalysisUsage;
+
+class AliasAnalysis {
+protected:
+ const TargetData *TD;
+ AliasAnalysis *AA; // Previous Alias Analysis to chain to.
+
+ /// InitializeAliasAnalysis - Subclasses must call this method to initialize
+ /// the AliasAnalysis interface before any other methods are called. This is
+ /// typically called by the run* methods of these subclasses. This may be
+ /// called multiple times.
+ ///
+ void InitializeAliasAnalysis(Pass *P);
+
+ // getAnalysisUsage - All alias analysis implementations should invoke this
+ // directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
+ // TargetData is required by the pass.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+ AliasAnalysis() : TD(0), AA(0) {}
+ virtual ~AliasAnalysis(); // We want to be subclassed
+
+ /// getTargetData - Every alias analysis implementation depends on the size of
+ /// data items in the current Target. This provides a uniform way to handle
+ /// it.
+ ///
+ const TargetData &getTargetData() const { return *TD; }
+
+ //===--------------------------------------------------------------------===//
+ /// Alias Queries...
+ ///
+
+ /// Alias analysis result - Either we know for sure that it does not alias, we
+ /// know for sure it must alias, or we don't know anything: The two pointers
+ /// _might_ alias. This enum is designed so you can do things like:
+ /// if (AA.alias(P1, P2)) { ... }
+ /// to check to see if two pointers might alias.
+ ///
+ enum AliasResult { NoAlias = 0, MayAlias = 1, MustAlias = 2 };
+
+ /// alias - The main low level interface to the alias analysis implementation.
+ /// Returns a Result indicating whether the two pointers are aliased to each
+ /// other. This is the interface that must be implemented by specific alias
+ /// analysis implementations.
+ ///
+ virtual AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size);
+
+ /// getMustAliases - If there are any pointers known that must alias this
+ /// pointer, return them now. This allows alias-set based alias analyses to
+ /// perform a form a value numbering (which is exposed by load-vn). If an
+ /// alias analysis supports this, it should ADD any must aliased pointers to
+ /// the specified vector.
+ ///
+ virtual void getMustAliases(Value *P, std::vector<Value*> &RetVals);
+
+ /// pointsToConstantMemory - If the specified pointer is known to point into
+ /// constant global memory, return true. This allows disambiguation of store
+ /// instructions from constant pointers.
+ ///
+ virtual bool pointsToConstantMemory(const Value *P);
+
+ //===--------------------------------------------------------------------===//
+ /// Simple mod/ref information...
+ ///
+
+ /// ModRefResult - Represent the result of a mod/ref query. Mod and Ref are
+ /// bits which may be or'd together.
+ ///
+ enum ModRefResult { NoModRef = 0, Ref = 1, Mod = 2, ModRef = 3 };
+
+
+ /// ModRefBehavior - Summary of how a function affects memory in the program.
+ /// Loads from constant globals are not considered memory accesses for this
+ /// interface. Also, functions may freely modify stack space local to their
+ /// invocation without having to report it through these interfaces.
+ enum ModRefBehavior {
+ // DoesNotAccessMemory - This function does not perform any non-local loads
+ // or stores to memory.
+ //
+ // This property corresponds to the GCC 'const' attribute.
+ DoesNotAccessMemory,
+
+ // AccessesArguments - This function accesses function arguments in
+ // non-volatile and well known ways, but does not access any other memory.
+ //
+ // Clients may call getArgumentAccesses to get specific information about
+ // how pointer arguments are used.
+ AccessesArguments,
+
+ // AccessesArgumentsAndGlobals - This function has accesses function
+ // arguments and global variables in non-volatile and well-known ways, but
+ // does not access any other memory.
+ //
+ // Clients may call getArgumentAccesses to get specific information about
+ // how pointer arguments and globals are used.
+ AccessesArgumentsAndGlobals,
+
+ // OnlyReadsMemory - This function does not perform any non-local stores or
+ // volatile loads, but may read from any memory location.
+ //
+ // This property corresponds to the GCC 'pure' attribute.
+ OnlyReadsMemory,
+
+ // UnknownModRefBehavior - This indicates that the function could not be
+ // classified into one of the behaviors above.
+ UnknownModRefBehavior
+ };
+
+ /// PointerAccessInfo - This struct is used to return results for pointers,
+ /// globals, and the return value of a function.
+ struct PointerAccessInfo {
+ /// V - The value this record corresponds to. This may be an Argument for
+ /// the function, a GlobalVariable, or null, corresponding to the return
+ /// value for the function.
+ Value *V;
+
+ /// ModRefInfo - Whether the pointer is loaded or stored to/from.
+ ///
+ ModRefResult ModRefInfo;
+
+ /// AccessType - Specific fine-grained access information for the argument.
+ /// If none of these classifications is general enough, the
+ /// getModRefBehavior method should not return AccessesArguments*. If a
+ /// record is not returned for a particular argument, the argument is never
+ /// dead and never dereferenced.
+ enum AccessType {
+ /// ScalarAccess - The pointer is dereferenced.
+ ///
+ ScalarAccess,
+
+ /// ArrayAccess - The pointer is indexed through as an array of elements.
+ ///
+ ArrayAccess,
+
+ /// ElementAccess ?? P->F only?
+
+ /// CallsThrough - Indirect calls are made through the specified function
+ /// pointer.
+ CallsThrough
+ };
+ };
+
+ /// getModRefBehavior - Return the behavior of the specified function if
+ /// called from the specified call site. The call site may be null in which
+ /// case the most generic behavior of this function should be returned.
+ virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info = 0);
+
+ /// doesNotAccessMemory - If the specified function is known to never read or
+ /// write memory, return true. If the function only reads from known-constant
+ /// memory, it is also legal to return true. Functions that unwind the stack
+ /// are not legal for this predicate.
+ ///
+ /// Many optimizations (such as CSE and LICM) can be performed on calls to it,
+ /// without worrying about aliasing properties, and many functions have this
+ /// property (e.g. 'sin' and 'cos').
+ ///
+ /// This property corresponds to the GCC 'const' attribute.
+ ///
+ bool doesNotAccessMemory(Function *F) {
+ return getModRefBehavior(F, CallSite()) == DoesNotAccessMemory;
+ }
+
+ /// onlyReadsMemory - If the specified function is known to only read from
+ /// non-volatile memory (or not access memory at all), return true. Functions
+ /// that unwind the stack are not legal for this predicate.
+ ///
+ /// This property allows many common optimizations to be performed in the
+ /// absence of interfering store instructions, such as CSE of strlen calls.
+ ///
+ /// This property corresponds to the GCC 'pure' attribute.
+ ///
+ bool onlyReadsMemory(Function *F) {
+ /// FIXME: If the analysis returns more precise info, we can reduce it to
+ /// this.
+ ModRefBehavior MRB = getModRefBehavior(F, CallSite());
+ return MRB == DoesNotAccessMemory || MRB == OnlyReadsMemory;
+ }
+
+
+ /// getModRefInfo - Return information about whether or not an instruction may
+ /// read or write memory specified by the pointer operand. An instruction
+ /// that doesn't read or write memory may be trivially LICM'd for example.
+
+ /// getModRefInfo (for call sites) - Return whether information about whether
+ /// a particular call site modifies or reads the memory specified by the
+ /// pointer.
+ ///
+ virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+
+ /// getModRefInfo - Return information about whether two call sites may refer
+ /// to the same set of memory locations. This function returns NoModRef if
+ /// the two calls refer to disjoint memory locations, Ref if CS1 reads memory
+ /// written by CS2, Mod if CS1 writes to memory read or written by CS2, or
+ /// ModRef if CS1 might read or write memory accessed by CS2.
+ ///
+ virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
+
+ /// hasNoModRefInfoForCalls - Return true if the analysis has no mod/ref
+ /// information for pairs of function calls (other than "pure" and "const"
+ /// functions). This can be used by clients to avoid many pointless queries.
+ /// Remember that if you override this and chain to another analysis, you must
+ /// make sure that it doesn't have mod/ref info either.
+ ///
+ virtual bool hasNoModRefInfoForCalls() const;
+
+ /// Convenience functions...
+ ModRefResult getModRefInfo(LoadInst *L, Value *P, unsigned Size);
+ ModRefResult getModRefInfo(StoreInst *S, Value *P, unsigned Size);
+ ModRefResult getModRefInfo(CallInst *C, Value *P, unsigned Size) {
+ return getModRefInfo(CallSite(C), P, Size);
+ }
+ ModRefResult getModRefInfo(InvokeInst *I, Value *P, unsigned Size) {
+ return getModRefInfo(CallSite(I), P, Size);
+ }
+ ModRefResult getModRefInfo(VAArgInst* I, Value* P, unsigned Size) {
+ return AliasAnalysis::Mod;
+ }
+ ModRefResult getModRefInfo(Instruction *I, Value *P, unsigned Size) {
+ switch (I->getOpcode()) {
+ case Instruction::VAArg: return getModRefInfo((VAArgInst*)I, P, Size);
+ case Instruction::Load: return getModRefInfo((LoadInst*)I, P, Size);
+ case Instruction::Store: return getModRefInfo((StoreInst*)I, P, Size);
+ case Instruction::Call: return getModRefInfo((CallInst*)I, P, Size);
+ case Instruction::Invoke: return getModRefInfo((InvokeInst*)I, P, Size);
+ default: return NoModRef;
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// Higher level methods for querying mod/ref information.
+ ///
+
+ /// canBasicBlockModify - Return true if it is possible for execution of the
+ /// specified basic block to modify the value pointed to by Ptr.
+ ///
+ bool canBasicBlockModify(const BasicBlock &BB, const Value *P, unsigned Size);
+
+ /// canInstructionRangeModify - Return true if it is possible for the
+ /// execution of the specified instructions to modify the value pointed to by
+ /// Ptr. The instructions to consider are all of the instructions in the
+ /// range of [I1,I2] INCLUSIVE. I1 and I2 must be in the same basic block.
+ ///
+ bool canInstructionRangeModify(const Instruction &I1, const Instruction &I2,
+ const Value *Ptr, unsigned Size);
+
+ //===--------------------------------------------------------------------===//
+ /// Methods that clients should call when they transform the program to allow
+ /// alias analyses to update their internal data structures. Note that these
+ /// methods may be called on any instruction, regardless of whether or not
+ /// they have pointer-analysis implications.
+ ///
+
+ /// deleteValue - This method should be called whenever an LLVM Value is
+ /// deleted from the program, for example when an instruction is found to be
+ /// redundant and is eliminated.
+ ///
+ virtual void deleteValue(Value *V);
+
+ /// copyValue - This method should be used whenever a preexisting value in the
+ /// program is copied or cloned, introducing a new value. Note that analysis
+ /// implementations should tolerate clients that use this method to introduce
+ /// the same value multiple times: if the analysis already knows about a
+ /// value, it should ignore the request.
+ ///
+ virtual void copyValue(Value *From, Value *To);
+
+ /// replaceWithNewValue - This method is the obvious combination of the two
+ /// above, and it provided as a helper to simplify client code.
+ ///
+ void replaceWithNewValue(Value *Old, Value *New) {
+ copyValue(Old, New);
+ deleteValue(Old);
+ }
+};
+
+} // End llvm namespace
+
+// Because of the way .a files work, we must force the BasicAA implementation to
+// be pulled in if the AliasAnalysis header is included. Otherwise we run
+// the risk of AliasAnalysis being used, but the default implementation not
+// being linked into the tool that uses it.
+FORCE_DEFINING_FILE_TO_BE_LINKED(AliasAnalysis)
+FORCE_DEFINING_FILE_TO_BE_LINKED(BasicAliasAnalysis)
+
+#endif
diff --git a/include/llvm/Analysis/AliasSetTracker.h b/include/llvm/Analysis/AliasSetTracker.h
new file mode 100644
index 0000000..cd6450f
--- /dev/null
+++ b/include/llvm/Analysis/AliasSetTracker.h
@@ -0,0 +1,392 @@
+//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines two classes: AliasSetTracker and AliasSet. These interface
+// are used to classify a collection of pointer references into a maximal number
+// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
+// object refers to memory disjoint from the other sets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
+#define LLVM_ANALYSIS_ALIASSETTRACKER_H
+
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/iterator"
+#include "llvm/ADT/hash_map"
+#include "llvm/ADT/ilist"
+
+namespace llvm {
+
+class AliasAnalysis;
+class LoadInst;
+class StoreInst;
+class FreeInst;
+class AliasSetTracker;
+class AliasSet;
+
+class AliasSet {
+ friend class AliasSetTracker;
+
+ class PointerRec;
+ typedef std::pair<Value* const, PointerRec> HashNodePair;
+
+ class PointerRec {
+ HashNodePair **PrevInList, *NextInList;
+ AliasSet *AS;
+ unsigned Size;
+ public:
+ PointerRec() : PrevInList(0), NextInList(0), AS(0), Size(0) {}
+
+ HashNodePair *getNext() const { return NextInList; }
+ bool hasAliasSet() const { return AS != 0; }
+
+ HashNodePair** setPrevInList(HashNodePair **PIL) {
+ PrevInList = PIL;
+ return &NextInList;
+ }
+
+ void updateSize(unsigned NewSize) {
+ if (NewSize > Size) Size = NewSize;
+ }
+
+ unsigned getSize() const { return Size; }
+
+ AliasSet *getAliasSet(AliasSetTracker &AST) {
+ assert(AS && "No AliasSet yet!");
+ if (AS->Forward) {
+ AliasSet *OldAS = AS;
+ AS = OldAS->getForwardedTarget(AST);
+ AS->addRef();
+ OldAS->dropRef(AST);
+ }
+ return AS;
+ }
+
+ void setAliasSet(AliasSet *as) {
+ assert(AS == 0 && "Already have an alias set!");
+ AS = as;
+ }
+
+ void removeFromList() {
+ if (NextInList) NextInList->second.PrevInList = PrevInList;
+ *PrevInList = NextInList;
+ if (AS->PtrListEnd == &NextInList) {
+ AS->PtrListEnd = PrevInList;
+ assert(*AS->PtrListEnd == 0 && "List not terminated right!");
+ }
+ }
+ };
+
+ HashNodePair *PtrList, **PtrListEnd; // Doubly linked list of nodes
+ AliasSet *Forward; // Forwarding pointer
+ AliasSet *Next, *Prev; // Doubly linked list of AliasSets
+
+ std::vector<CallSite> CallSites; // All calls & invokes in this node
+
+ // RefCount - Number of nodes pointing to this AliasSet plus the number of
+ // AliasSets forwarding to it.
+ unsigned RefCount : 28;
+
+ /// AccessType - Keep track of whether this alias set merely refers to the
+ /// locations of memory, whether it modifies the memory, or whether it does
+ /// both. The lattice goes from "NoModRef" to either Refs or Mods, then to
+ /// ModRef as necessary.
+ ///
+ enum AccessType {
+ NoModRef = 0, Refs = 1, // Ref = bit 1
+ Mods = 2, ModRef = 3 // Mod = bit 2
+ };
+ unsigned AccessTy : 2;
+
+ /// AliasType - Keep track the relationships between the pointers in the set.
+ /// Lattice goes from MustAlias to MayAlias.
+ ///
+ enum AliasType {
+ MustAlias = 0, MayAlias = 1
+ };
+ unsigned AliasTy : 1;
+
+ // Volatile - True if this alias set contains volatile loads or stores.
+ bool Volatile : 1;
+
+ friend struct ilist_traits<AliasSet>;
+ AliasSet *getPrev() const { return Prev; }
+ AliasSet *getNext() const { return Next; }
+ void setPrev(AliasSet *P) { Prev = P; }
+ void setNext(AliasSet *N) { Next = N; }
+
+ void addRef() { ++RefCount; }
+ void dropRef(AliasSetTracker &AST) {
+ assert(RefCount >= 1 && "Invalid reference count detected!");
+ if (--RefCount == 0)
+ removeFromTracker(AST);
+ }
+
+public:
+ /// Accessors...
+ bool isRef() const { return AccessTy & Refs; }
+ bool isMod() const { return AccessTy & Mods; }
+ bool isMustAlias() const { return AliasTy == MustAlias; }
+ bool isMayAlias() const { return AliasTy == MayAlias; }
+
+ // isVolatile - Return true if this alias set contains volatile loads or
+ // stores.
+ bool isVolatile() const { return Volatile; }
+
+ /// isForwardingAliasSet - Return true if this alias set should be ignored as
+ /// part of the AliasSetTracker object.
+ bool isForwardingAliasSet() const { return Forward; }
+
+ /// mergeSetIn - Merge the specified alias set into this alias set...
+ ///
+ void mergeSetIn(AliasSet &AS, AliasSetTracker &AST);
+
+ // Alias Set iteration - Allow access to all of the pointer which are part of
+ // this alias set...
+ class iterator;
+ iterator begin() const { return iterator(PtrList); }
+ iterator end() const { return iterator(); }
+ bool empty() const { return PtrList == 0; }
+
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void dump() const;
+
+ /// Define an iterator for alias sets... this is just a forward iterator.
+ class iterator : public forward_iterator<HashNodePair, ptrdiff_t> {
+ HashNodePair *CurNode;
+ public:
+ iterator(HashNodePair *CN = 0) : CurNode(CN) {}
+
+ bool operator==(const iterator& x) const {
+ return CurNode == x.CurNode;
+ }
+ 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;
+ }
+ value_type *operator->() const { return &operator*(); }
+
+ Value *getPointer() const { return CurNode->first; }
+ unsigned getSize() const { return CurNode->second.getSize(); }
+
+ iterator& operator++() { // Preincrement
+ assert(CurNode && "Advancing past AliasSet.end()!");
+ CurNode = CurNode->second.getNext();
+ return *this;
+ }
+ iterator operator++(int) { // Postincrement
+ iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+private:
+ // Can only be created by AliasSetTracker
+ AliasSet() : PtrList(0), PtrListEnd(&PtrList), Forward(0), RefCount(0),
+ AccessTy(NoModRef), AliasTy(MustAlias), Volatile(false) {
+ }
+
+ AliasSet(const AliasSet &AS) {
+ assert(0 && "Copy ctor called!?!?!");
+ abort();
+ }
+
+ HashNodePair *getSomePointer() const {
+ return PtrList;
+ }
+
+ /// getForwardedTarget - Return the real alias set this represents. If this
+ /// has been merged with another set and is forwarding, return the ultimate
+ /// destination set. This also implements the union-find collapsing as well.
+ AliasSet *getForwardedTarget(AliasSetTracker &AST) {
+ if (!Forward) return this;
+
+ AliasSet *Dest = Forward->getForwardedTarget(AST);
+ if (Dest != Forward) {
+ Dest->addRef();
+ Forward->dropRef(AST);
+ Forward = Dest;
+ }
+ return Dest;
+ }
+
+ void removeFromTracker(AliasSetTracker &AST);
+
+ void addPointer(AliasSetTracker &AST, HashNodePair &Entry, unsigned Size,
+ bool KnownMustAlias = false);
+ void addCallSite(CallSite CS, AliasAnalysis &AA);
+ void removeCallSite(CallSite CS) {
+ for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
+ if (CallSites[i].getInstruction() == CS.getInstruction()) {
+ CallSites[i] = CallSites.back();
+ CallSites.pop_back();
+ }
+ }
+ void setVolatile() { Volatile = true; }
+
+ /// aliasesPointer - Return true if the specified pointer "may" (or must)
+ /// alias one of the members in the set.
+ ///
+ bool aliasesPointer(const Value *Ptr, unsigned Size, AliasAnalysis &AA) const;
+ bool aliasesCallSite(CallSite CS, AliasAnalysis &AA) const;
+};
+
+inline std::ostream& operator<<(std::ostream &OS, const AliasSet &AS) {
+ AS.print(OS);
+ return OS;
+}
+
+
+class AliasSetTracker {
+ AliasAnalysis &AA;
+ ilist<AliasSet> AliasSets;
+
+ // Map from pointers to their node
+ hash_map<Value*, AliasSet::PointerRec> PointerMap;
+public:
+ /// AliasSetTracker ctor - Create an empty collection of AliasSets, and use
+ /// the specified alias analysis object to disambiguate load and store
+ /// addresses.
+ AliasSetTracker(AliasAnalysis &aa) : AA(aa) {}
+
+ /// add methods - These methods are used to add different types of
+ /// instructions to the alias sets. Adding a new instruction can result in
+ /// one of three actions happening:
+ ///
+ /// 1. If the instruction doesn't alias any other sets, create a new set.
+ /// 2. If the instruction aliases exactly one set, add it to the set
+ /// 3. If the instruction aliases multiple sets, merge the sets, and add
+ /// the instruction to the result.
+ ///
+ /// These methods return true if inserting the instruction resulted in the
+ /// addition of a new alias set (i.e., the pointer did not alias anything).
+ ///
+ bool add(Value *Ptr, unsigned Size); // Add a location
+ bool add(LoadInst *LI);
+ bool add(StoreInst *SI);
+ bool add(FreeInst *FI);
+ bool add(CallSite CS); // Call/Invoke instructions
+ bool add(CallInst *CI) { return add(CallSite(CI)); }
+ bool add(InvokeInst *II) { return add(CallSite(II)); }
+ bool add(Instruction *I); // Dispatch to one of the other add methods...
+ void add(BasicBlock &BB); // Add all instructions in basic block
+ void add(const AliasSetTracker &AST); // Add alias relations from another AST
+
+ /// remove methods - These methods are used to remove all entries that might
+ /// be aliased by the specified instruction. These methods return true if any
+ /// alias sets were eliminated.
+ bool remove(Value *Ptr, unsigned Size); // Remove a location
+ bool remove(LoadInst *LI);
+ bool remove(StoreInst *SI);
+ bool remove(FreeInst *FI);
+ bool remove(CallSite CS);
+ bool remove(CallInst *CI) { return remove(CallSite(CI)); }
+ bool remove(InvokeInst *II) { return remove(CallSite(II)); }
+ bool remove(Instruction *I);
+ void remove(AliasSet &AS);
+
+ void clear() {
+ PointerMap.clear();
+ AliasSets.clear();
+ }
+
+ /// getAliasSets - Return the alias sets that are active.
+ ///
+ const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
+
+ /// getAliasSetForPointer - Return the alias set that the specified pointer
+ /// lives in. If the New argument is non-null, this method sets the value to
+ /// true if a new alias set is created to contain the pointer (because the
+ /// pointer didn't alias anything).
+ AliasSet &getAliasSetForPointer(Value *P, unsigned Size, bool *New = 0);
+
+ /// getAliasSetForPointerIfExists - Return the alias set containing the
+ /// location specified if one exists, otherwise return null.
+ AliasSet *getAliasSetForPointerIfExists(Value *P, unsigned Size) {
+ return findAliasSetForPointer(P, Size);
+ }
+
+ /// containsPointer - Return true if the specified location is represented by
+ /// this alias set, false otherwise. This does not modify the AST object or
+ /// alias sets.
+ bool containsPointer(Value *P, unsigned Size) const;
+
+ /// getAliasAnalysis - Return the underlying alias analysis object used by
+ /// this tracker.
+ AliasAnalysis &getAliasAnalysis() const { return AA; }
+
+ /// deleteValue method - This method is used to remove a pointer value from
+ /// the AliasSetTracker entirely. It should be used when an instruction is
+ /// deleted from the program to update the AST. If you don't use this, you
+ /// would have dangling pointers to deleted instructions.
+ ///
+ void deleteValue(Value *PtrVal);
+
+ /// copyValue - This method should be used whenever a preexisting value in the
+ /// program is copied or cloned, introducing a new value. Note that it is ok
+ /// for clients that use this method to introduce the same value multiple
+ /// times: if the tracker already knows about a value, it will ignore the
+ /// request.
+ ///
+ void copyValue(Value *From, Value *To);
+
+
+ typedef ilist<AliasSet>::iterator iterator;
+ typedef ilist<AliasSet>::const_iterator const_iterator;
+
+ const_iterator begin() const { return AliasSets.begin(); }
+ const_iterator end() const { return AliasSets.end(); }
+
+ iterator begin() { return AliasSets.begin(); }
+ iterator end() { return AliasSets.end(); }
+
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void dump() const;
+
+private:
+ friend class AliasSet;
+ void removeAliasSet(AliasSet *AS);
+
+ AliasSet::HashNodePair &getEntryFor(Value *V) {
+ // Standard operator[], except that it returns the whole pair, not just
+ // ->second.
+ return *PointerMap.insert(AliasSet::HashNodePair(V,
+ AliasSet::PointerRec())).first;
+ }
+
+ AliasSet &addPointer(Value *P, unsigned Size, AliasSet::AccessType E,
+ bool &NewSet) {
+ NewSet = false;
+ AliasSet &AS = getAliasSetForPointer(P, Size, &NewSet);
+ AS.AccessTy |= E;
+ return AS;
+ }
+ AliasSet *findAliasSetForPointer(const Value *Ptr, unsigned Size);
+
+ AliasSet *findAliasSetForCallSite(CallSite CS);
+};
+
+inline std::ostream& operator<<(std::ostream &OS, const AliasSetTracker &AST) {
+ AST.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/CFGPrinter.h b/include/llvm/Analysis/CFGPrinter.h
new file mode 100644
index 0000000..3567db1
--- /dev/null
+++ b/include/llvm/Analysis/CFGPrinter.h
@@ -0,0 +1,24 @@
+//===-- CFGPrinter.h - CFG printer external interface ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines external functions that can be called to explicitly
+// instantiate the CFG printer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CFGPRINTER_H
+#define LLVM_ANALYSIS_CFGPRINTER_H
+
+namespace llvm {
+ class FunctionPass;
+ FunctionPass *createCFGPrinterPass ();
+ FunctionPass *createCFGOnlyPrinterPass ();
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/CallGraph.h b/include/llvm/Analysis/CallGraph.h
new file mode 100644
index 0000000..4f4ce0e
--- /dev/null
+++ b/include/llvm/Analysis/CallGraph.h
@@ -0,0 +1,315 @@
+//===- CallGraph.h - Build a Module's call graph ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This interface is used to build and manipulate a call graph, which is a very
+// useful tool for interprocedural optimization.
+//
+// Every function in a module is represented as a node in the call graph. The
+// callgraph node keeps track of which functions the are called by the function
+// corresponding to the node.
+//
+// A call graph may contain nodes where the function that they correspond to is
+// null. These 'external' nodes are used to represent control flow that is not
+// represented (or analyzable) in the module. In particular, this analysis
+// builds one external node such that:
+// 1. All functions in the module without internal linkage will have edges
+// from this external node, indicating that they could be called by
+// functions outside of the module.
+// 2. All functions whose address is used for something more than a direct
+// call, for example being stored into a memory location will also have an
+// edge from this external node. Since they may be called by an unknown
+// caller later, they must be tracked as such.
+//
+// There is a second external node added for calls that leave this module.
+// Functions have a call edge to the external node iff:
+// 1. The function is external, reflecting the fact that they could call
+// anything without internal linkage or that has its address taken.
+// 2. The function contains an indirect function call.
+//
+// As an extension in the future, there may be multiple nodes with a null
+// function. These will be used when we can prove (through pointer analysis)
+// that an indirect call site can call only a specific set of functions.
+//
+// Because of these properties, the CallGraph captures a conservative superset
+// of all of the caller-callee relationships, which is useful for
+// transformations.
+//
+// The CallGraph class also attempts to figure out what the root of the
+// CallGraph is, which it currently does by looking for a function named 'main'.
+// If no function named 'main' is found, the external node is used as the entry
+// node, reflecting the fact that any function without internal linkage could
+// be called into (which is common for libraries).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CALLGRAPH_H
+#define LLVM_ANALYSIS_CALLGRAPH_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+
+namespace llvm {
+
+class Function;
+class Module;
+class CallGraphNode;
+
+//===----------------------------------------------------------------------===//
+// CallGraph class definition
+//
+class CallGraph {
+protected:
+ Module *Mod; // The module this call graph represents
+
+ typedef std::map<const Function *, CallGraphNode *> FunctionMapTy;
+ FunctionMapTy FunctionMap; // Map from a function to its node
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+ //===---------------------------------------------------------------------
+ // Accessors...
+ //
+ typedef FunctionMapTy::iterator iterator;
+ typedef FunctionMapTy::const_iterator const_iterator;
+
+ /// getModule - Return the module the call graph corresponds to.
+ ///
+ Module &getModule() const { return *Mod; }
+
+ inline iterator begin() { return FunctionMap.begin(); }
+ inline iterator end() { return FunctionMap.end(); }
+ inline const_iterator begin() const { return FunctionMap.begin(); }
+ inline const_iterator end() const { return FunctionMap.end(); }
+
+ // Subscripting operators, return the call graph node for the provided
+ // function
+ inline const CallGraphNode *operator[](const Function *F) const {
+ const_iterator I = FunctionMap.find(F);
+ assert(I != FunctionMap.end() && "Function not in callgraph!");
+ return I->second;
+ }
+ inline CallGraphNode *operator[](const Function *F) {
+ const_iterator I = FunctionMap.find(F);
+ assert(I != FunctionMap.end() && "Function not in callgraph!");
+ return I->second;
+ }
+
+ //Returns the CallGraphNode which is used to represent undetermined calls
+ // into the callgraph. Override this if you want behavioural inheritance.
+ virtual CallGraphNode* getExternalCallingNode() const { return 0; }
+
+ //Return the root/main method in the module, or some other root node, such
+ // as the externalcallingnode. Overload these if you behavioural
+ // inheritance.
+ virtual CallGraphNode* getRoot() { return 0; }
+ virtual const CallGraphNode* getRoot() const { return 0; }
+
+ //===---------------------------------------------------------------------
+ // Functions to keep a call graph up to date with a function that has been
+ // modified.
+ //
+
+ /// removeFunctionFromModule - Unlink the function from this module, returning
+ /// it. Because this removes the function from the module, the call graph
+ /// node is destroyed. This is only valid if the function does not call any
+ /// other functions (ie, there are no edges in it's CGN). The easiest way to
+ /// do this is to dropAllReferences before calling this.
+ ///
+ Function *removeFunctionFromModule(CallGraphNode *CGN);
+ Function *removeFunctionFromModule(Function *F) {
+ return removeFunctionFromModule((*this)[F]);
+ }
+
+ /// changeFunction - This method changes the function associated with this
+ /// CallGraphNode, for use by transformations that need to change the
+ /// prototype of a Function (thus they must create a new Function and move the
+ /// old code over).
+ void changeFunction(Function *OldF, Function *NewF);
+
+ /// getOrInsertFunction - This method is identical to calling operator[], but
+ /// it will insert a new CallGraphNode for the specified function if one does
+ /// not already exist.
+ CallGraphNode *getOrInsertFunction(const Function *F);
+
+ //===---------------------------------------------------------------------
+ // Pass infrastructure interface glue code...
+ //
+protected:
+ CallGraph() {}
+
+public:
+ virtual ~CallGraph() { destroy(); }
+
+ /// initialize - Call this method before calling other methods,
+ /// re/initializes the state of the CallGraph.
+ ///
+ void initialize(Module &M);
+
+ virtual void print(std::ostream &o, const Module *M) const;
+ void print(std::ostream *o, const Module *M) const { if (o) print(*o, M); }
+ void dump() const;
+
+ // stub - dummy function, just ignore it
+ static int stub;
+protected:
+
+ // destroy - Release memory for the call graph
+ virtual void destroy();
+};
+
+//===----------------------------------------------------------------------===//
+// CallGraphNode class definition
+//
+class CallGraphNode {
+ Function *F;
+ typedef std::pair<CallSite,CallGraphNode*> CallRecord;
+ std::vector<CallRecord> CalledFunctions;
+
+ CallGraphNode(const CallGraphNode &); // Do not implement
+public:
+ //===---------------------------------------------------------------------
+ // Accessor methods...
+ //
+
+ typedef std::vector<CallRecord>::iterator iterator;
+ typedef std::vector<CallRecord>::const_iterator const_iterator;
+
+ // getFunction - Return the function that this call graph node represents...
+ Function *getFunction() const { return F; }
+
+ inline iterator begin() { return CalledFunctions.begin(); }
+ inline iterator end() { return CalledFunctions.end(); }
+ inline const_iterator begin() const { return CalledFunctions.begin(); }
+ inline const_iterator end() const { return CalledFunctions.end(); }
+ inline unsigned size() const { return CalledFunctions.size(); }
+
+ // Subscripting operator - Return the i'th called function...
+ //
+ CallGraphNode *operator[](unsigned i) const {
+ return CalledFunctions[i].second;
+ }
+
+ /// dump - Print out this call graph node.
+ ///
+ void dump() const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ //===---------------------------------------------------------------------
+ // Methods to keep a call graph up to date with a function that has been
+ // modified
+ //
+
+ /// removeAllCalledFunctions - As the name implies, this removes all edges
+ /// from this CallGraphNode to any functions it calls.
+ void removeAllCalledFunctions() {
+ CalledFunctions.clear();
+ }
+
+ /// addCalledFunction add a function to the list of functions called by this
+ /// one.
+ void addCalledFunction(CallSite CS, CallGraphNode *M) {
+ CalledFunctions.push_back(std::make_pair(CS, M));
+ }
+
+ /// removeCallEdgeTo - This method removes a *single* edge to the specified
+ /// callee function. Note that this method takes linear time, so it should be
+ /// used sparingly.
+ void removeCallEdgeTo(CallGraphNode *Callee);
+
+ /// removeAnyCallEdgeTo - This method removes any call edges from this node to
+ /// the specified callee function. This takes more time to execute than
+ /// removeCallEdgeTo, so it should not be used unless necessary.
+ void removeAnyCallEdgeTo(CallGraphNode *Callee);
+
+ friend class CallGraph;
+
+ // CallGraphNode ctor - Create a node for the specified function.
+ inline CallGraphNode(Function *f) : F(f) {}
+};
+
+//===----------------------------------------------------------------------===//
+// GraphTraits specializations for call graphs so that they can be treated as
+// graphs by the generic graph algorithms.
+//
+
+// Provide graph traits for tranversing call graphs using standard graph
+// traversals.
+template <> struct GraphTraits<CallGraphNode*> {
+ typedef CallGraphNode NodeType;
+
+ typedef std::pair<CallSite, CallGraphNode*> CGNPairTy;
+ typedef std::pointer_to_unary_function<CGNPairTy, CallGraphNode*> CGNDerefFun;
+
+ static NodeType *getEntryNode(CallGraphNode *CGN) { return CGN; }
+
+ typedef mapped_iterator<NodeType::iterator, CGNDerefFun> ChildIteratorType;
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return map_iterator(N->begin(), CGNDerefFun(CGNDeref));
+ }
+ static inline ChildIteratorType child_end (NodeType *N) {
+ return map_iterator(N->end(), CGNDerefFun(CGNDeref));
+ }
+
+ static CallGraphNode *CGNDeref(CGNPairTy P) {
+ return P.second;
+ }
+
+};
+
+template <> struct GraphTraits<const CallGraphNode*> {
+ typedef const CallGraphNode NodeType;
+ typedef NodeType::const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const CallGraphNode *CGN) { return CGN; }
+ static inline ChildIteratorType child_begin(NodeType *N) { return N->begin();}
+ static inline ChildIteratorType child_end (NodeType *N) { return N->end(); }
+};
+
+template<> struct GraphTraits<CallGraph*> : public GraphTraits<CallGraphNode*> {
+ static NodeType *getEntryNode(CallGraph *CGN) {
+ return CGN->getExternalCallingNode(); // Start at the external node!
+ }
+ typedef std::pair<const Function*, CallGraphNode*> PairTy;
+ typedef std::pointer_to_unary_function<PairTy, CallGraphNode&> DerefFun;
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef mapped_iterator<CallGraph::iterator, DerefFun> nodes_iterator;
+ static nodes_iterator nodes_begin(CallGraph *CG) {
+ return map_iterator(CG->begin(), DerefFun(CGdereference));
+ }
+ static nodes_iterator nodes_end (CallGraph *CG) {
+ return map_iterator(CG->end(), DerefFun(CGdereference));
+ }
+
+ static CallGraphNode &CGdereference(PairTy P) {
+ return *P.second;
+ }
+};
+
+template<> struct GraphTraits<const CallGraph*> :
+ public GraphTraits<const CallGraphNode*> {
+ static NodeType *getEntryNode(const CallGraph *CGN) {
+ return CGN->getExternalCallingNode();
+ }
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef CallGraph::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const CallGraph *CG) { return CG->begin(); }
+ static nodes_iterator nodes_end (const CallGraph *CG) { return CG->end(); }
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in CallGraph.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(CallGraph)
+
+#endif
diff --git a/include/llvm/Analysis/ConstantFolding.h b/include/llvm/Analysis/ConstantFolding.h
new file mode 100644
index 0000000..9c19f11
--- /dev/null
+++ b/include/llvm/Analysis/ConstantFolding.h
@@ -0,0 +1,61 @@
+//===-- ConstantFolding.h - Analyze constant folding possibilities --------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions determines the possibility of performing constant
+// folding.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_CONSTANTFOLDING_H
+#define LLVM_ANALYSIS_CONSTANTFOLDING_H
+
+namespace llvm {
+ class Constant;
+ class ConstantExpr;
+ class Instruction;
+ class TargetData;
+ class Function;
+
+/// ConstantFoldInstruction - Attempt to constant fold the specified
+/// instruction. If successful, the constant result is returned, if not, null
+/// is returned. Note that 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 TargetData *TD = 0);
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified operands. If successful, the constant result is returned, if not,
+/// null is returned. Note that this function can fail when attempting to
+/// fold instructions like loads and stores, which have no constant expression
+/// form.
+///
+Constant *ConstantFoldInstOperands(
+ const Instruction *I, ///< The model instruction
+ Constant** Ops, ///< The array of constant operands to use.
+ unsigned NumOps, ///< The number of operands provided.
+ const TargetData *TD = 0 ///< Optional target information.
+);
+
+
+/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
+/// getelementptr constantexpr, return the constant value being addressed by the
+/// constant expression, or null if something is funny and we can't decide.
+Constant *ConstantFoldLoadThroughGEPConstantExpr(Constant *C, ConstantExpr *CE);
+
+/// canConstantFoldCallTo - Return true if its even possible to fold a call to
+/// the specified function.
+bool canConstantFoldCallTo(Function *F);
+
+/// ConstantFoldCall - Attempt to constant fold a call to the specified function
+/// with the specified arguments, returning null if unsuccessful.
+Constant *
+ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands);
+}
+
+#endif
diff --git a/include/llvm/Analysis/ConstantsScanner.h b/include/llvm/Analysis/ConstantsScanner.h
new file mode 100644
index 0000000..9ea9ed6
--- /dev/null
+++ b/include/llvm/Analysis/ConstantsScanner.h
@@ -0,0 +1,94 @@
+//==- llvm/Analysis/ConstantsScanner.h - Iterate over constants -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This 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/Support/InstIterator.h"
+#include "llvm/Instruction.h"
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+class Constant;
+
+class constant_iterator : public forward_iterator<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/Dominators.h b/include/llvm/Analysis/Dominators.h
new file mode 100644
index 0000000..f0b4672
--- /dev/null
+++ b/include/llvm/Analysis/Dominators.h
@@ -0,0 +1,431 @@
+//===- llvm/Analysis/Dominators.h - Dominator Info Calculation --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the following classes:
+// 1. DominatorTree: Represent dominators as an explicit tree structure.
+// 2. DominanceFrontier: Calculate and hold the dominance frontier for a
+// function.
+//
+// These data structures are listed in increasing order of complexity. It
+// takes longer to calculate the dominator frontier, for example, than the
+// DominatorTree mapping.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_DOMINATORS_H
+#define LLVM_ANALYSIS_DOMINATORS_H
+
+#include "llvm/Pass.h"
+#include <set>
+
+namespace llvm {
+
+class Instruction;
+
+template <typename GraphType> struct GraphTraits;
+
+//===----------------------------------------------------------------------===//
+/// DominatorBase - Base class that other, more interesting dominator analyses
+/// inherit from.
+///
+class DominatorBase : public FunctionPass {
+protected:
+ std::vector<BasicBlock*> Roots;
+ const bool IsPostDominators;
+ inline DominatorBase(intptr_t ID, bool isPostDom) :
+ FunctionPass(ID), Roots(), IsPostDominators(isPostDom) {}
+public:
+
+ /// getRoots - Return the root blocks of the current CFG. This may include
+ /// multiple blocks if we are computing post dominators. For forward
+ /// dominators, this will always be a single block (the entry node).
+ ///
+ inline const std::vector<BasicBlock*> &getRoots() const { return Roots; }
+
+ /// isPostDominator - Returns true if analysis based of postdoms
+ ///
+ bool isPostDominator() const { return IsPostDominators; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// DomTreeNode - Dominator Tree Node
+class DominatorTreeBase;
+class PostDominatorTree;
+class DomTreeNode {
+ BasicBlock *TheBB;
+ DomTreeNode *IDom;
+ std::vector<DomTreeNode*> Children;
+ int DFSNumIn, DFSNumOut;
+
+ friend class DominatorTreeBase;
+ friend class PostDominatorTree;
+public:
+ typedef std::vector<DomTreeNode*>::iterator iterator;
+ typedef std::vector<DomTreeNode*>::const_iterator const_iterator;
+
+ iterator begin() { return Children.begin(); }
+ iterator end() { return Children.end(); }
+ const_iterator begin() const { return Children.begin(); }
+ const_iterator end() const { return Children.end(); }
+
+ inline BasicBlock *getBlock() const { return TheBB; }
+ inline DomTreeNode *getIDom() const { return IDom; }
+ inline const std::vector<DomTreeNode*> &getChildren() const { return Children; }
+
+ inline DomTreeNode(BasicBlock *BB, DomTreeNode *iDom)
+ : TheBB(BB), IDom(iDom), DFSNumIn(-1), DFSNumOut(-1) { }
+ inline DomTreeNode *addChild(DomTreeNode *C) { Children.push_back(C); return C; }
+ void setIDom(DomTreeNode *NewIDom);
+
+private:
+ // Return true if this node is dominated by other. Use this only if DFS info is valid.
+ bool DominatedBy(const DomTreeNode *other) const {
+ return this->DFSNumIn >= other->DFSNumIn &&
+ this->DFSNumOut <= other->DFSNumOut;
+ }
+
+ /// assignDFSNumber - Assign In and Out numbers while walking dominator tree
+ /// in dfs order.
+ void assignDFSNumber(int num);
+};
+
+//===----------------------------------------------------------------------===//
+/// DominatorTree - Calculate the immediate dominator tree for a function.
+///
+class DominatorTreeBase : public DominatorBase {
+
+protected:
+ void reset();
+ typedef std::map<BasicBlock*, DomTreeNode*> DomTreeNodeMapType;
+ DomTreeNodeMapType DomTreeNodes;
+ DomTreeNode *RootNode;
+
+ bool DFSInfoValid;
+ unsigned int SlowQueries;
+ // Information record used during immediate dominators computation.
+ struct InfoRec {
+ unsigned Semi;
+ unsigned Size;
+ BasicBlock *Label, *Parent, *Child, *Ancestor;
+
+ std::vector<BasicBlock*> Bucket;
+
+ InfoRec() : Semi(0), Size(0), Label(0), Parent(0), Child(0), Ancestor(0){}
+ };
+
+ std::map<BasicBlock*, BasicBlock*> IDoms;
+
+ // Vertex - Map the DFS number to the BasicBlock*
+ std::vector<BasicBlock*> Vertex;
+
+ // Info - Collection of information used during the computation of idoms.
+ std::map<BasicBlock*, InfoRec> Info;
+
+ void updateDFSNumbers();
+
+ public:
+ DominatorTreeBase(intptr_t ID, bool isPostDom)
+ : DominatorBase(ID, isPostDom), DFSInfoValid(false), SlowQueries(0) {}
+ ~DominatorTreeBase() { reset(); }
+
+ virtual void releaseMemory() { reset(); }
+
+ /// getNode - return the (Post)DominatorTree node for the specified basic
+ /// block. This is the same as using operator[] on this class.
+ ///
+ inline DomTreeNode *getNode(BasicBlock *BB) const {
+ DomTreeNodeMapType::const_iterator i = DomTreeNodes.find(BB);
+ return (i != DomTreeNodes.end()) ? i->second : 0;
+ }
+
+ inline DomTreeNode *operator[](BasicBlock *BB) const {
+ return getNode(BB);
+ }
+
+ /// getRootNode - This returns the entry node for the CFG of the function. If
+ /// this tree represents the post-dominance relations for a function, however,
+ /// this root may be a node with the block == NULL. This is the case when
+ /// there are multiple exit nodes from a particular function. Consumers of
+ /// post-dominance information must be capable of dealing with this
+ /// possibility.
+ ///
+ DomTreeNode *getRootNode() { return RootNode; }
+ const DomTreeNode *getRootNode() const { return RootNode; }
+
+ /// properlyDominates - Returns true iff this dominates N and this != N.
+ /// Note that this is not a constant time operation!
+ ///
+ bool properlyDominates(const DomTreeNode *A, DomTreeNode *B) const {
+ if (A == 0 || B == 0) return false;
+ return dominatedBySlowTreeWalk(A, B);
+ }
+
+ inline bool properlyDominates(BasicBlock *A, BasicBlock *B) {
+ return properlyDominates(getNode(A), getNode(B));
+ }
+
+ bool dominatedBySlowTreeWalk(const DomTreeNode *A,
+ const DomTreeNode *B) const {
+ const DomTreeNode *IDom;
+ if (A == 0 || B == 0) return false;
+ while ((IDom = B->getIDom()) != 0 && IDom != A && IDom != B)
+ B = IDom; // Walk up the tree
+ return IDom != 0;
+ }
+
+
+ /// isReachableFromEntry - Return true if A is dominated by the entry
+ /// block of the function containing it.
+ const bool isReachableFromEntry(BasicBlock* A);
+
+ /// dominates - Returns true iff A dominates B. Note that this is not a
+ /// constant time operation!
+ ///
+ inline bool dominates(const DomTreeNode *A, DomTreeNode *B) {
+ if (B == A)
+ return true; // A node trivially dominates itself.
+
+ if (A == 0 || B == 0)
+ return false;
+
+ if (DFSInfoValid)
+ return B->DominatedBy(A);
+
+ // If we end up with too many slow queries, just update the
+ // DFS numbers on the theory that we are going to keep querying.
+ SlowQueries++;
+ if (SlowQueries > 32) {
+ updateDFSNumbers();
+ return B->DominatedBy(A);
+ }
+
+ return dominatedBySlowTreeWalk(A, B);
+ }
+
+ inline bool dominates(BasicBlock *A, BasicBlock *B) {
+ if (A == B)
+ return true;
+
+ return dominates(getNode(A), getNode(B));
+ }
+
+ /// findNearestCommonDominator - Find nearest common dominator basic block
+ /// for basic block A and B. If there is no such block then return NULL.
+ BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B);
+
+ // dominates - Return true if A dominates B. This performs the
+ // special checks necessary if A and B are in the same basic block.
+ bool dominates(Instruction *A, Instruction *B);
+
+ //===--------------------------------------------------------------------===//
+ // API to update (Post)DominatorTree information based on modifications to
+ // the CFG...
+
+ /// addNewBlock - Add a new node to the dominator tree information. This
+ /// creates a new node as a child of DomBB dominator node,linking it into
+ /// the children list of the immediate dominator.
+ DomTreeNode *addNewBlock(BasicBlock *BB, BasicBlock *DomBB) {
+ assert(getNode(BB) == 0 && "Block already in dominator tree!");
+ DomTreeNode *IDomNode = getNode(DomBB);
+ assert(IDomNode && "Not immediate dominator specified for block!");
+ DFSInfoValid = false;
+ return DomTreeNodes[BB] =
+ IDomNode->addChild(new DomTreeNode(BB, IDomNode));
+ }
+
+ /// changeImmediateDominator - This method is used to update the dominator
+ /// tree information when a node's immediate dominator changes.
+ ///
+ void changeImmediateDominator(DomTreeNode *N, DomTreeNode *NewIDom) {
+ assert(N && NewIDom && "Cannot change null node pointers!");
+ DFSInfoValid = false;
+ N->setIDom(NewIDom);
+ }
+
+ void changeImmediateDominator(BasicBlock *BB, BasicBlock *NewBB) {
+ changeImmediateDominator(getNode(BB), getNode(NewBB));
+ }
+
+ /// removeNode - Removes a node from the dominator tree. Block must not
+ /// dominate any other blocks. Invalidates any node pointing to removed
+ /// block.
+ void removeNode(BasicBlock *BB) {
+ assert(getNode(BB) && "Removing node that isn't in dominator tree.");
+ DomTreeNodes.erase(BB);
+ }
+
+ /// print - Convert to human readable form
+ ///
+ virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
+ virtual void dump();
+};
+
+//===-------------------------------------
+/// DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to
+/// compute a normal dominator tree.
+///
+class DominatorTree : public DominatorTreeBase {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominatorTree() : DominatorTreeBase((intptr_t)&ID, false) {}
+
+ BasicBlock *getRoot() const {
+ assert(Roots.size() == 1 && "Should always have entry node!");
+ return Roots[0];
+ }
+
+ virtual bool runOnFunction(Function &F);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ /// splitBlock
+ /// BB is split and now it has one successor. Update dominator tree to
+ /// reflect this change.
+ void splitBlock(BasicBlock *BB);
+private:
+ void calculate(Function& F);
+ DomTreeNode *getNodeForBlock(BasicBlock *BB);
+ unsigned DFSPass(BasicBlock *V, InfoRec &VInfo, unsigned N);
+ void Compress(BasicBlock *V);
+ BasicBlock *Eval(BasicBlock *v);
+ void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo);
+ inline BasicBlock *getIDom(BasicBlock *BB) const {
+ std::map<BasicBlock*, BasicBlock*>::const_iterator I = IDoms.find(BB);
+ return I != IDoms.end() ? I->second : 0;
+ }
+};
+
+//===-------------------------------------
+/// DominatorTree GraphTraits specialization so the DominatorTree can be
+/// iterable by generic graph iterators.
+///
+template <> struct GraphTraits<DomTreeNode*> {
+ typedef DomTreeNode NodeType;
+ typedef NodeType::iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(NodeType *N) {
+ return N;
+ }
+ static inline ChildIteratorType child_begin(NodeType* N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType* N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<DominatorTree*>
+ : public GraphTraits<DomTreeNode*> {
+ static NodeType *getEntryNode(DominatorTree *DT) {
+ return DT->getRootNode();
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// DominanceFrontierBase - Common base class for computing forward and inverse
+/// dominance frontiers for a function.
+///
+class DominanceFrontierBase : public DominatorBase {
+public:
+ typedef std::set<BasicBlock*> DomSetType; // Dom set for a bb
+ typedef std::map<BasicBlock*, DomSetType> DomSetMapType; // Dom set map
+protected:
+ DomSetMapType Frontiers;
+public:
+ DominanceFrontierBase(intptr_t ID, bool isPostDom)
+ : DominatorBase(ID, isPostDom) {}
+
+ virtual void releaseMemory() { Frontiers.clear(); }
+
+ // Accessor interface:
+ typedef DomSetMapType::iterator iterator;
+ typedef DomSetMapType::const_iterator const_iterator;
+ iterator begin() { return Frontiers.begin(); }
+ const_iterator begin() const { return Frontiers.begin(); }
+ iterator end() { return Frontiers.end(); }
+ const_iterator end() const { return Frontiers.end(); }
+ iterator find(BasicBlock *B) { return Frontiers.find(B); }
+ const_iterator find(BasicBlock *B) const { return Frontiers.find(B); }
+
+ void addBasicBlock(BasicBlock *BB, const DomSetType &frontier) {
+ assert(find(BB) == end() && "Block already in DominanceFrontier!");
+ Frontiers.insert(std::make_pair(BB, frontier));
+ }
+
+ void addToFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ I->second.insert(Node);
+ }
+
+ void removeFromFrontier(iterator I, BasicBlock *Node) {
+ assert(I != end() && "BB is not in DominanceFrontier!");
+ assert(I->second.count(Node) && "Node is not in DominanceFrontier of BB");
+ I->second.erase(Node);
+ }
+
+ /// print - Convert to human readable form
+ ///
+ virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
+ virtual void dump();
+};
+
+
+//===-------------------------------------
+/// DominanceFrontier Class - Concrete subclass of DominanceFrontierBase that is
+/// used to compute a forward dominator frontiers.
+///
+class DominanceFrontier : public DominanceFrontierBase {
+public:
+ static char ID; // Pass ID, replacement for typeid
+ DominanceFrontier() :
+ DominanceFrontierBase((intptr_t)& ID, false) {}
+
+ BasicBlock *getRoot() const {
+ assert(Roots.size() == 1 && "Should always have entry node!");
+ return Roots[0];
+ }
+
+ virtual bool runOnFunction(Function &) {
+ Frontiers.clear();
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+ Roots = DT.getRoots();
+ assert(Roots.size() == 1 && "Only one entry block for forward domfronts!");
+ calculate(DT, DT[Roots[0]]);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTree>();
+ }
+
+ /// splitBlock
+ /// BB is split and now it has one successor. Update dominace frontier to
+ /// reflect this change.
+ void splitBlock(BasicBlock *BB);
+
+private:
+ const DomSetType &calculate(const DominatorTree &DT,
+ const DomTreeNode *Node);
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/FindUsedTypes.h b/include/llvm/Analysis/FindUsedTypes.h
new file mode 100644
index 0000000..6cafc89
--- /dev/null
+++ b/include/llvm/Analysis/FindUsedTypes.h
@@ -0,0 +1,67 @@
+//===- llvm/Analysis/FindUsedTypes.h - Find all Types in use ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to seek out all of the types in use by the program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_FINDUSEDTYPES_H
+#define LLVM_ANALYSIS_FINDUSEDTYPES_H
+
+#include "llvm/Pass.h"
+#include <set>
+
+namespace llvm {
+
+class Type;
+
+class FindUsedTypes : public ModulePass {
+ std::set<const Type *> UsedTypes;
+public:
+ static char ID; // Pass identification, replacement for typeid
+ FindUsedTypes() : ModulePass((intptr_t)&ID) {}
+
+ /// getTypes - After the pass has been run, return the set containing all of
+ /// the types used in the module.
+ ///
+ const std::set<const Type *> &getTypes() const { return UsedTypes; }
+
+ /// Print the types found in the module. If the optional Module parameter is
+ /// passed in, then the types are printed symbolically if possible, using the
+ /// symbol table from the module.
+ ///
+ void print(std::ostream &o, const Module *M) const;
+ void print(std::ostream *o, const Module *M) const { if (o) print(*o, M); }
+
+private:
+ /// IncorporateType - Incorporate one type and all of its subtypes into the
+ /// collection of used types.
+ ///
+ void IncorporateType(const Type *Ty);
+
+ /// IncorporateValue - Incorporate all of the types used by this value.
+ ///
+ void IncorporateValue(const Value *V);
+
+public:
+ /// run - This incorporates all types used by the specified module
+ bool runOnModule(Module &M);
+
+ /// getAnalysisUsage - We do not modify anything.
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in PostDominators.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(FindUsedTypes)
+
+#endif
diff --git a/include/llvm/Analysis/Interval.h b/include/llvm/Analysis/Interval.h
new file mode 100644
index 0000000..bed815a
--- /dev/null
+++ b/include/llvm/Analysis/Interval.h
@@ -0,0 +1,154 @@
+//===- llvm/Analysis/Interval.h - Interval Class Declaration ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Interval class, which
+// represents a set of CFG nodes and is a portion of an interval partition.
+//
+// Intervals have some interesting and useful properties, including the
+// following:
+// 1. The header node of an interval dominates all of the elements of the
+// interval
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_H
+#define LLVM_INTERVAL_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+
+class BasicBlock;
+
+//===----------------------------------------------------------------------===//
+//
+/// Interval Class - An Interval is a set of nodes defined such that every node
+/// in the interval has all of its predecessors in the interval (except for the
+/// header)
+///
+class Interval {
+ /// HeaderNode - The header BasicBlock, which dominates all BasicBlocks in this
+ /// interval. Also, any loops in this interval must go through the HeaderNode.
+ ///
+ BasicBlock *HeaderNode;
+public:
+ typedef std::vector<BasicBlock*>::iterator succ_iterator;
+ typedef std::vector<BasicBlock*>::iterator pred_iterator;
+ typedef std::vector<BasicBlock*>::iterator node_iterator;
+
+ inline Interval(BasicBlock *Header) : HeaderNode(Header) {
+ Nodes.push_back(Header);
+ }
+
+ inline Interval(const Interval &I) // copy ctor
+ : HeaderNode(I.HeaderNode), Nodes(I.Nodes), Successors(I.Successors) {}
+
+ inline BasicBlock *getHeaderNode() const { return HeaderNode; }
+
+ /// Nodes - The basic blocks in this interval.
+ ///
+ std::vector<BasicBlock*> Nodes;
+
+ /// Successors - List of BasicBlocks that are reachable directly from nodes in
+ /// this interval, but are not in the interval themselves.
+ /// These nodes necessarily must be header nodes for other intervals.
+ ///
+ std::vector<BasicBlock*> Successors;
+
+ /// Predecessors - List of BasicBlocks that have this Interval's header block
+ /// as one of their successors.
+ ///
+ std::vector<BasicBlock*> Predecessors;
+
+ /// contains - Find out if a basic block is in this interval
+ inline bool contains(BasicBlock *BB) const {
+ for (unsigned i = 0; i < Nodes.size(); ++i)
+ if (Nodes[i] == BB) return true;
+ return false;
+ // I don't want the dependency on <algorithm>
+ //return find(Nodes.begin(), Nodes.end(), BB) != Nodes.end();
+ }
+
+ /// isSuccessor - find out if a basic block is a successor of this Interval
+ inline bool isSuccessor(BasicBlock *BB) const {
+ for (unsigned i = 0; i < Successors.size(); ++i)
+ if (Successors[i] == BB) return true;
+ return false;
+ // I don't want the dependency on <algorithm>
+ //return find(Successors.begin(), Successors.end(), BB) != Successors.end();
+ }
+
+ /// Equality operator. It is only valid to compare two intervals from the
+ /// same partition, because of this, all we have to check is the header node
+ /// for equality.
+ ///
+ inline bool operator==(const Interval &I) const {
+ return HeaderNode == I.HeaderNode;
+ }
+
+ /// isLoop - Find out if there is a back edge in this interval...
+ bool isLoop() const;
+
+ /// print - Show contents in human readable format...
+ void print(std::ostream &O) const;
+ void print(std::ostream *O) const { if (O) print(*O); }
+};
+
+/// succ_begin/succ_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the succ_* functions, and *::succ_iterator.
+///
+inline Interval::succ_iterator succ_begin(Interval *I) {
+ return I->Successors.begin();
+}
+inline Interval::succ_iterator succ_end(Interval *I) {
+ return I->Successors.end();
+}
+
+/// pred_begin/pred_end - define methods so that Intervals may be used
+/// just like BasicBlocks can with the pred_* functions, and *::pred_iterator.
+///
+inline Interval::pred_iterator pred_begin(Interval *I) {
+ return I->Predecessors.begin();
+}
+inline Interval::pred_iterator pred_end(Interval *I) {
+ return I->Predecessors.end();
+}
+
+template <> struct GraphTraits<Interval*> {
+ typedef Interval NodeType;
+ typedef Interval::succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Interval *I) { return I; }
+
+ /// nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<Interval*> > {
+ typedef Interval NodeType;
+ typedef Interval::pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<Interval *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/IntervalIterator.h b/include/llvm/Analysis/IntervalIterator.h
new file mode 100644
index 0000000..dfa983c
--- /dev/null
+++ b/include/llvm/Analysis/IntervalIterator.h
@@ -0,0 +1,258 @@
+//===- IntervalIterator.h - Interval Iterator Declaration -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an iterator that enumerates the intervals in a control flow
+// graph of some sort. This iterator is parametric, allowing iterator over the
+// following types of graphs:
+//
+// 1. A Function* object, composed of BasicBlock nodes.
+// 2. An IntervalPartition& object, composed of Interval nodes.
+//
+// This iterator is defined to walk the control flow graph, returning intervals
+// in depth first order. These intervals are completely filled in except for
+// the predecessor fields (the successor information is filled in however).
+//
+// By default, the intervals created by this iterator are deleted after they
+// are no longer any use to the iterator. This behavior can be changed by
+// passing a false value into the intervals_begin() function. This causes the
+// IOwnMem member to be set, and the intervals to not be deleted.
+//
+// It is only safe to use this if all of the intervals are deleted by the caller
+// and all of the intervals are processed. However, the user of the iterator is
+// not allowed to modify or delete the intervals until after the iterator has
+// been used completely. The IntervalPartition class uses this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_ITERATOR_H
+#define LLVM_INTERVAL_ITERATOR_H
+
+#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/Function.h"
+#include "llvm/Support/CFG.h"
+#include <stack>
+#include <set>
+#include <algorithm>
+
+namespace llvm {
+
+// getNodeHeader - Given a source graph node and the source graph, return the
+// BasicBlock that is the header node. This is the opposite of
+// getSourceGraphNode.
+//
+inline BasicBlock *getNodeHeader(BasicBlock *BB) { return BB; }
+inline BasicBlock *getNodeHeader(Interval *I) { return I->getHeaderNode(); }
+
+// getSourceGraphNode - Given a BasicBlock and the source graph, return the
+// source graph node that corresponds to the BasicBlock. This is the opposite
+// of getNodeHeader.
+//
+inline BasicBlock *getSourceGraphNode(Function *, BasicBlock *BB) {
+ return BB;
+}
+inline Interval *getSourceGraphNode(IntervalPartition *IP, BasicBlock *BB) {
+ return IP->getBlockInterval(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node. In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval.
+//
+inline void addNodeToInterval(Interval *Int, BasicBlock *BB) {
+ Int->Nodes.push_back(BB);
+}
+
+// addNodeToInterval - This method exists to assist the generic ProcessNode
+// with the task of adding a node to the new interval, depending on the
+// type of the source node. In the case of a CFG source graph (BasicBlock
+// case), the BasicBlock itself is added to the interval. In the case of
+// an IntervalPartition source graph (Interval case), all of the member
+// BasicBlocks are added to the interval.
+//
+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));
+}
+
+
+
+
+
+template<class NodeTy, class OrigContainer_t, class GT = GraphTraits<NodeTy*>,
+ class IGT = GraphTraits<Inverse<NodeTy*> > >
+class IntervalIterator {
+ std::stack<std::pair<Interval*, typename Interval::succ_iterator> > IntStack;
+ std::set<BasicBlock*> Visited;
+ OrigContainer_t *OrigContainer;
+ 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
+ IntervalIterator(Function *M, bool OwnMemory) : IOwnMem(OwnMemory) {
+ OrigContainer = M;
+ if (!ProcessInterval(&M->front())) {
+ assert(0 && "ProcessInterval should never fail for first interval!");
+ }
+ }
+
+ IntervalIterator(IntervalPartition &IP, bool OwnMemory) : IOwnMem(OwnMemory) {
+ OrigContainer = &IP;
+ if (!ProcessInterval(IP.getRootInterval())) {
+ assert(0 && "ProcessInterval should never fail for first interval!");
+ }
+ }
+
+ inline ~IntervalIterator() {
+ if (IOwnMem)
+ while (!IntStack.empty()) {
+ delete operator*();
+ IntStack.pop();
+ }
+ }
+
+ inline bool operator==(const _Self& x) const { return IntStack == x.IntStack;}
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline const Interval *operator*() const { return IntStack.top().first; }
+ inline Interval *operator*() { return IntStack.top().first; }
+ inline const Interval *operator->() const { return operator*(); }
+ inline Interval *operator->() { return operator*(); }
+
+ _Self& 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
+ // their successors now.
+ Interval::succ_iterator &SuccIt = IntStack.top().second,
+ EndIt = succ_end(IntStack.top().first);
+ while (SuccIt != EndIt) { // Loop over all interval succs
+ bool Done = ProcessInterval(getSourceGraphNode(OrigContainer, *SuccIt));
+ ++SuccIt; // Increment iterator
+ if (Done) return *this; // Found a new interval! Use it!
+ }
+
+ // Free interval memory... if necessary
+ if (IOwnMem) delete IntStack.top().first;
+
+ // We ran out of successors for this interval... pop off the stack
+ IntStack.pop();
+ } while (!IntStack.empty());
+
+ return *this;
+ }
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+private:
+ // ProcessInterval - This method is used during the construction of the
+ // interval graph. It walks through the source graph, recursively creating
+ // an interval per invokation until the entire graph is covered. This uses
+ // the ProcessNode method to add all of the nodes to the interval.
+ //
+ // This method is templated because it may operate on two different source
+ // graphs: a basic block graph, or a preexisting interval graph.
+ //
+ bool ProcessInterval(NodeTy *Node) {
+ BasicBlock *Header = getNodeHeader(Node);
+ if (Visited.count(Header)) return false;
+
+ Interval *Int = new Interval(Header);
+ Visited.insert(Header); // The header has now been visited!
+
+ // Check all of our successors to see if they are in the interval...
+ for (typename GT::ChildIteratorType I = GT::child_begin(Node),
+ E = GT::child_end(Node); I != E; ++I)
+ ProcessNode(Int, getSourceGraphNode(OrigContainer, *I));
+
+ IntStack.push(std::make_pair(Int, succ_begin(Int)));
+ return true;
+ }
+
+ // ProcessNode - This method is called by ProcessInterval to add nodes to the
+ // interval being constructed, and it is also called recursively as it walks
+ // the source graph. A node is added to the current interval only if all of
+ // its predecessors are already in the graph. This also takes care of keeping
+ // the successor set of an interval up to date.
+ //
+ // This method is templated because it may operate on two different source
+ // graphs: a basic block graph, or a preexisting interval graph.
+ //
+ void ProcessNode(Interval *Int, NodeTy *Node) {
+ assert(Int && "Null interval == bad!");
+ assert(Node && "Null Node == bad!");
+
+ BasicBlock *NodeHeader = getNodeHeader(Node);
+
+ if (Visited.count(NodeHeader)) { // Node already been visited?
+ if (Int->contains(NodeHeader)) { // Already in this interval...
+ return;
+ } else { // In other interval, add as successor
+ if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+ Int->Successors.push_back(NodeHeader);
+ }
+ } else { // Otherwise, not in interval yet
+ for (typename IGT::ChildIteratorType I = IGT::child_begin(Node),
+ E = IGT::child_end(Node); I != E; ++I) {
+ if (!Int->contains(*I)) { // If pred not in interval, we can't be
+ if (!Int->isSuccessor(NodeHeader)) // Add only if not already in set
+ Int->Successors.push_back(NodeHeader);
+ return; // See you later
+ }
+ }
+
+ // If we get here, then all of the predecessors of BB are in the interval
+ // already. In this case, we must add BB to the interval!
+ addNodeToInterval(Int, Node);
+ Visited.insert(NodeHeader); // The node has now been visited!
+
+ if (Int->isSuccessor(NodeHeader)) {
+ // If we were in the successor list from before... remove from succ list
+ Int->Successors.erase(std::remove(Int->Successors.begin(),
+ Int->Successors.end(), NodeHeader),
+ Int->Successors.end());
+ }
+
+ // Now that we have discovered that Node is in the interval, perhaps some
+ // of its successors are as well?
+ for (typename GT::ChildIteratorType It = GT::child_begin(Node),
+ End = GT::child_end(Node); It != End; ++It)
+ ProcessNode(Int, getSourceGraphNode(OrigContainer, *It));
+ }
+ }
+};
+
+typedef IntervalIterator<BasicBlock, Function> function_interval_iterator;
+typedef IntervalIterator<Interval, IntervalPartition> interval_part_interval_iterator;
+
+
+inline function_interval_iterator intervals_begin(Function *F,
+ bool DeleteInts = true) {
+ return function_interval_iterator(F, DeleteInts);
+}
+inline function_interval_iterator intervals_end(Function *) {
+ return function_interval_iterator();
+}
+
+inline interval_part_interval_iterator
+ intervals_begin(IntervalPartition &IP, bool DeleteIntervals = true) {
+ return interval_part_interval_iterator(IP, DeleteIntervals);
+}
+
+inline interval_part_interval_iterator intervals_end(IntervalPartition &IP) {
+ return interval_part_interval_iterator();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/IntervalPartition.h b/include/llvm/Analysis/IntervalPartition.h
new file mode 100644
index 0000000..1f985e3
--- /dev/null
+++ b/include/llvm/Analysis/IntervalPartition.h
@@ -0,0 +1,114 @@
+//===- IntervalPartition.h - Interval partition Calculation -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the IntervalPartition class, which
+// calculates and represents the interval partition of a function, or a
+// preexisting interval partition.
+//
+// In this way, the interval partition may be used to reduce a flow graph down
+// to its degenerate single node interval partition (unless it is irreducible).
+//
+// TODO: The IntervalPartition class should take a bool parameter that tells
+// whether it should add the "tails" of an interval to an interval itself or if
+// they should be represented as distinct intervals.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTERVAL_PARTITION_H
+#define LLVM_INTERVAL_PARTITION_H
+
+#include "llvm/Analysis/Interval.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+//
+// IntervalPartition - This class builds and holds an "interval partition" for
+// a function. This partition divides the control flow graph into a set of
+// maximal intervals, as defined with the properties above. Intuitively, a
+// BasicBlock is a (possibly nonexistent) loop with a "tail" of non looping
+// nodes following it.
+//
+class IntervalPartition : public FunctionPass {
+ typedef std::map<BasicBlock*, Interval*> IntervalMapTy;
+ IntervalMapTy IntervalMap;
+
+ typedef std::vector<Interval*> IntervalListTy;
+ Interval *RootInterval;
+ std::vector<Interval*> Intervals;
+
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ IntervalPartition() : FunctionPass((intptr_t)&ID), RootInterval(0) {}
+
+ // run - Calculate the interval partition for this function
+ virtual bool runOnFunction(Function &F);
+
+ // IntervalPartition ctor - Build a reduced interval partition from an
+ // existing interval graph. This takes an additional boolean parameter to
+ // distinguish it from a copy constructor. Always pass in false for now.
+ //
+ IntervalPartition(IntervalPartition &I, bool);
+
+ // Destructor - Free memory
+ ~IntervalPartition() { destroy(); }
+
+ // print - Show contents in human readable format...
+ virtual void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ // getRootInterval() - Return the root interval that contains the starting
+ // block of the function.
+ inline Interval *getRootInterval() { return RootInterval; }
+
+ // isDegeneratePartition() - Returns true if the interval partition contains
+ // a single interval, and thus cannot be simplified anymore.
+ bool isDegeneratePartition() { return Intervals.size() == 1; }
+
+ // TODO: isIrreducible - look for triangle graph.
+
+ // getBlockInterval - Return the interval that a basic block exists in.
+ inline Interval *getBlockInterval(BasicBlock *BB) {
+ IntervalMapTy::iterator I = IntervalMap.find(BB);
+ return I != IntervalMap.end() ? I->second : 0;
+ }
+
+ // getAnalysisUsage - Implement the Pass API
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ // Interface to Intervals vector...
+ const std::vector<Interval*> &getIntervals() const { return Intervals; }
+
+private:
+ // destroy - Reset state back to before function was analyzed
+ void destroy();
+
+ // addIntervalToPartition - Add an interval to the internal list of intervals,
+ // and then add mappings from all of the basic blocks in the interval to the
+ // interval itself (in the IntervalMap).
+ //
+ void addIntervalToPartition(Interval *I);
+
+ // updatePredecessors - Interval generation only sets the successor fields of
+ // the interval data structures. After interval generation is complete,
+ // run through all of the intervals and propagate successor info as
+ // predecessor info.
+ //
+ void updatePredecessors(Interval *Int);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LoadValueNumbering.h b/include/llvm/Analysis/LoadValueNumbering.h
new file mode 100644
index 0000000..b924595
--- /dev/null
+++ b/include/llvm/Analysis/LoadValueNumbering.h
@@ -0,0 +1,35 @@
+//===- llvm/Analysis/LoadValueNumbering.h - Value # Load Insts --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a value numbering pass that value #'s load instructions.
+// To do this, it finds lexically identical load instructions, and uses alias
+// analysis to determine which loads are guaranteed to produce the same value.
+//
+// This pass builds off of another value numbering pass to implement value
+// numbering for non-load instructions. It uses Alias Analysis so that it can
+// disambiguate the load instructions. The more powerful these base analyses
+// are, the more powerful the resultant analysis will be.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOAD_VALUE_NUMBERING_H
+#define LLVM_ANALYSIS_LOAD_VALUE_NUMBERING_H
+
+namespace llvm {
+
+class FunctionPass;
+
+/// createLoadValueNumberingPass - Create and return a new pass that implements
+/// the ValueNumbering interface.
+///
+FunctionPass *createLoadValueNumberingPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
new file mode 100644
index 0000000..b332fd1
--- /dev/null
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -0,0 +1,363 @@
+//===- llvm/Analysis/LoopInfo.h - Natural Loop Calculator -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LoopInfo class that is used to identify natural loops
+// and determine the loop depth of various nodes of the CFG. Note that natural
+// loops may actually be several loops that share the same header node.
+//
+// This analysis calculates the nesting structure of loops in a function. For
+// each natural loop identified, this analysis identifies natural loops
+// contained entirely within the loop and the basic blocks the make up the loop.
+//
+// It can calculate on the fly various bits of information, for example:
+//
+// * whether there is a preheader for the loop
+// * the number of back edges to the header
+// * whether or not a particular block branches out of the loop
+// * the successor blocks of the loop
+// * the loop depth
+// * the trip count
+// * etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_LOOP_INFO_H
+#define LLVM_ANALYSIS_LOOP_INFO_H
+
+#include "llvm/Pass.h"
+#include "llvm/ADT/GraphTraits.h"
+
+namespace llvm {
+
+class DominatorTree;
+class LoopInfo;
+class PHINode;
+class Instruction;
+
+//===----------------------------------------------------------------------===//
+/// Loop class - Instances of this class are used to represent loops that are
+/// detected in the flow graph
+///
+class Loop {
+ Loop *ParentLoop;
+ std::vector<Loop*> SubLoops; // Loops contained entirely within this one
+ std::vector<BasicBlock*> Blocks; // First entry is the header node
+
+ Loop(const Loop &); // DO NOT IMPLEMENT
+ const Loop &operator=(const Loop &); // DO NOT IMPLEMENT
+public:
+ /// Loop ctor - This creates an empty loop.
+ Loop() : ParentLoop(0) {}
+ ~Loop() {
+ for (unsigned i = 0, e = SubLoops.size(); i != e; ++i)
+ delete SubLoops[i];
+ }
+
+ unsigned getLoopDepth() const {
+ unsigned D = 0;
+ for (const Loop *CurLoop = this; CurLoop; CurLoop = CurLoop->ParentLoop)
+ ++D;
+ return D;
+ }
+ BasicBlock *getHeader() const { return Blocks.front(); }
+ Loop *getParentLoop() const { return ParentLoop; }
+
+ /// contains - Return true of the specified basic block is in this loop
+ ///
+ bool contains(const BasicBlock *BB) const;
+
+ /// iterator/begin/end - Return the loops contained entirely within this loop.
+ ///
+ const std::vector<Loop*> &getSubLoops() const { return SubLoops; }
+ typedef std::vector<Loop*>::const_iterator iterator;
+ iterator begin() const { return SubLoops.begin(); }
+ iterator end() const { return SubLoops.end(); }
+
+ /// getBlocks - Get a list of the basic blocks which make up this loop.
+ ///
+ const std::vector<BasicBlock*> &getBlocks() const { return Blocks; }
+ typedef std::vector<BasicBlock*>::const_iterator block_iterator;
+ block_iterator block_begin() const { return Blocks.begin(); }
+ block_iterator block_end() const { return Blocks.end(); }
+
+ /// isLoopExit - True if terminator in the block can branch to another block
+ /// that is outside of the current loop.
+ ///
+ bool isLoopExit(const BasicBlock *BB) const;
+
+ /// getNumBackEdges - Calculate the number of back edges to the loop header
+ ///
+ unsigned getNumBackEdges() const;
+
+ /// isLoopInvariant - Return true if the specified value is loop invariant
+ ///
+ bool isLoopInvariant(Value *V) const;
+
+ //===--------------------------------------------------------------------===//
+ // APIs for simple analysis of the loop.
+ //
+ // Note that all of these methods can fail on general loops (ie, there may not
+ // be a preheader, etc). For best success, the loop simplification and
+ // induction variable canonicalization pass should be used to normalize loops
+ // for easy analysis. These methods assume canonical loops.
+
+ /// getExitingBlocks - Return all blocks inside the loop that have successors
+ /// outside of the loop. These are the blocks _inside of the current loop_
+ /// which branch out. The returned list is always unique.
+ ///
+ void getExitingBlocks(std::vector<BasicBlock*> &Blocks) const;
+
+ /// getExitBlocks - Return all of the successor blocks of this loop. These
+ /// are the blocks _outside of the current loop_ which are branched to.
+ ///
+ void getExitBlocks(std::vector<BasicBlock*> &Blocks) const;
+
+ /// getUniqueExitBlocks - Return all unique successor blocks of this loop.
+ /// These are the blocks _outside of the current loop_ which are branched to.
+ /// This assumes that loop is in canonical form.
+ ///
+ void getUniqueExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const;
+
+ /// getLoopPreheader - If there is a preheader for this loop, return it. A
+ /// loop has a preheader if there is only one edge to the header of the loop
+ /// from outside of the loop. If this is the case, the block branching to the
+ /// header of the loop is the preheader node.
+ ///
+ /// This method returns null if there is no preheader for the loop.
+ ///
+ BasicBlock *getLoopPreheader() const;
+
+ /// getLoopLatch - If there is a latch block for this loop, return it. A
+ /// latch block is the canonical backedge for a loop. A loop header in normal
+ /// form has two edges into it: one from a preheader and one from a latch
+ /// block.
+ BasicBlock *getLoopLatch() const;
+
+ /// getCanonicalInductionVariable - Check to see if the loop has a canonical
+ /// induction variable: an integer recurrence that starts at 0 and increments
+ /// by one each time through the loop. If so, return the phi node that
+ /// corresponds to it.
+ ///
+ PHINode *getCanonicalInductionVariable() const;
+
+ /// getCanonicalInductionVariableIncrement - Return the LLVM value that holds
+ /// the canonical induction variable value for the "next" iteration of the
+ /// loop. This always succeeds if getCanonicalInductionVariable succeeds.
+ ///
+ Instruction *getCanonicalInductionVariableIncrement() const;
+
+ /// getTripCount - Return a loop-invariant LLVM value indicating the number of
+ /// times the loop will be executed. Note that this means that the backedge
+ /// of the loop executes N-1 times. If the trip-count cannot be determined,
+ /// this returns null.
+ ///
+ Value *getTripCount() const;
+
+ /// isLCSSAForm - Return true if the Loop is in LCSSA form
+ bool isLCSSAForm() const;
+
+ //===--------------------------------------------------------------------===//
+ // APIs for updating loop information after changing the CFG
+ //
+
+ /// addBasicBlockToLoop - This method is used by other analyses to update loop
+ /// information. NewBB is set to be a new member of the current loop.
+ /// Because of this, it is added as a member of all parent loops, and is added
+ /// to the specified LoopInfo object as being in the current basic block. It
+ /// is not valid to replace the loop header with this method.
+ ///
+ void addBasicBlockToLoop(BasicBlock *NewBB, LoopInfo &LI);
+
+ /// replaceChildLoopWith - This is used when splitting loops up. It replaces
+ /// the OldChild entry in our children list with NewChild, and updates the
+ /// parent pointer of OldChild to be null and the NewChild to be this loop.
+ /// This updates the loop depth of the new child.
+ void replaceChildLoopWith(Loop *OldChild, Loop *NewChild);
+
+ /// addChildLoop - Add the specified loop to be a child of this loop. This
+ /// updates the loop depth of the new child.
+ ///
+ void addChildLoop(Loop *NewChild);
+
+ /// removeChildLoop - This removes the specified child from being a subloop of
+ /// this loop. The loop is not deleted, as it will presumably be inserted
+ /// into another loop.
+ Loop *removeChildLoop(iterator OldChild);
+
+ /// addBlockEntry - This adds a basic block directly to the basic block list.
+ /// This should only be used by transformations that create new loops. Other
+ /// transformations should use addBasicBlockToLoop.
+ void addBlockEntry(BasicBlock *BB) {
+ Blocks.push_back(BB);
+ }
+
+ /// moveToHeader - This method is used to move BB (which must be part of this
+ /// loop) to be the loop header of the loop (the block that dominates all
+ /// others).
+ void moveToHeader(BasicBlock *BB) {
+ if (Blocks[0] == BB) return;
+ for (unsigned i = 0; ; ++i) {
+ assert(i != Blocks.size() && "Loop does not contain BB!");
+ if (Blocks[i] == BB) {
+ Blocks[i] = Blocks[0];
+ Blocks[0] = BB;
+ return;
+ }
+ }
+ }
+
+ /// removeBlockFromLoop - This removes the specified basic block from the
+ /// current loop, updating the Blocks as appropriate. This does not update
+ /// the mapping in the LoopInfo class.
+ void removeBlockFromLoop(BasicBlock *BB);
+
+ void print(std::ostream &O, unsigned Depth = 0) const;
+ void print(std::ostream *O, unsigned Depth = 0) const {
+ if (O) print(*O, Depth);
+ }
+ void dump() const;
+private:
+ friend class LoopInfo;
+ Loop(BasicBlock *BB) : ParentLoop(0) {
+ Blocks.push_back(BB);
+ }
+};
+
+
+
+//===----------------------------------------------------------------------===//
+/// LoopInfo - This class builds and contains all of the top level loop
+/// structures in the specified function.
+///
+class LoopInfo : public FunctionPass {
+ // BBMap - Mapping of basic blocks to the inner most loop they occur in
+ std::map<BasicBlock*, Loop*> BBMap;
+ std::vector<Loop*> TopLevelLoops;
+ friend class Loop;
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ LoopInfo() : FunctionPass((intptr_t)&ID) {}
+ ~LoopInfo() { releaseMemory(); }
+
+ /// iterator/begin/end - The interface to the top-level loops in the current
+ /// function.
+ ///
+ typedef std::vector<Loop*>::const_iterator iterator;
+ iterator begin() const { return TopLevelLoops.begin(); }
+ iterator end() const { return TopLevelLoops.end(); }
+
+ /// getLoopFor - Return the inner most loop that BB lives in. If a basic
+ /// block is in no loop (for example the entry node), null is returned.
+ ///
+ Loop *getLoopFor(const BasicBlock *BB) const {
+ std::map<BasicBlock *, Loop*>::const_iterator I=
+ BBMap.find(const_cast<BasicBlock*>(BB));
+ return I != BBMap.end() ? I->second : 0;
+ }
+
+ /// operator[] - same as getLoopFor...
+ ///
+ const Loop *operator[](const BasicBlock *BB) const {
+ return getLoopFor(BB);
+ }
+
+ /// getLoopDepth - Return the loop nesting level of the specified block...
+ ///
+ unsigned getLoopDepth(const BasicBlock *BB) const {
+ const Loop *L = getLoopFor(BB);
+ return L ? L->getLoopDepth() : 0;
+ }
+
+ // isLoopHeader - True if the block is a loop header node
+ bool isLoopHeader(BasicBlock *BB) const {
+ const Loop *L = getLoopFor(BB);
+ return L && L->getHeader() == BB;
+ }
+
+ /// runOnFunction - Calculate the natural loop information.
+ ///
+ virtual bool runOnFunction(Function &F);
+
+ virtual void releaseMemory();
+
+ void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// removeLoop - This removes the specified top-level loop from this loop info
+ /// object. The loop is not deleted, as it will presumably be inserted into
+ /// another loop.
+ Loop *removeLoop(iterator I);
+
+ /// changeLoopFor - Change the top-level loop that contains BB to the
+ /// specified loop. This should be used by transformations that restructure
+ /// the loop hierarchy tree.
+ void changeLoopFor(BasicBlock *BB, Loop *L);
+
+ /// changeTopLevelLoop - Replace the specified loop in the top-level loops
+ /// list with the indicated loop.
+ void changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop);
+
+ /// addTopLevelLoop - This adds the specified loop to the collection of
+ /// top-level loops.
+ void addTopLevelLoop(Loop *New) {
+ assert(New->getParentLoop() == 0 && "Loop already in subloop!");
+ TopLevelLoops.push_back(New);
+ }
+
+ /// removeBlock - This method completely removes BB from all data structures,
+ /// including all of the Loop objects it is nested in and our mapping from
+ /// BasicBlocks to loops.
+ void removeBlock(BasicBlock *BB);
+
+private:
+ void Calculate(DominatorTree &DT);
+ Loop *ConsiderForLoop(BasicBlock *BB, DominatorTree &DT);
+ void MoveSiblingLoopInto(Loop *NewChild, Loop *NewParent);
+ void InsertLoopInto(Loop *L, Loop *Parent);
+};
+
+
+// Allow clients to walk the list of nested loops...
+template <> struct GraphTraits<const Loop*> {
+ typedef const Loop NodeType;
+ typedef std::vector<Loop*>::const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const Loop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+template <> struct GraphTraits<Loop*> {
+ typedef Loop NodeType;
+ typedef std::vector<Loop*>::const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(Loop *L) { return L; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->end();
+ }
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in LoopInfo.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(LoopInfo)
+
+#endif
diff --git a/include/llvm/Analysis/LoopPass.h b/include/llvm/Analysis/LoopPass.h
new file mode 100644
index 0000000..08c2bcb
--- /dev/null
+++ b/include/llvm/Analysis/LoopPass.h
@@ -0,0 +1,132 @@
+//===- LoopPass.h - LoopPass class ----------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines LoopPass class. All loop optimization
+// and transformation passes are derived from LoopPass.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LOOP_PASS_H
+#define LLVM_LOOP_PASS_H
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManagers.h"
+#include "llvm/Function.h"
+
+namespace llvm {
+
+class LPPassManager;
+class Loop;
+class Function;
+
+class LoopPass : public Pass {
+
+ public:
+ explicit LoopPass(intptr_t pid) : Pass(pid) {}
+
+ // runOnLoop - This method should be implemented by the subclass to perform
+ // whatever action is necessary for the specfied Loop.
+ virtual bool runOnLoop (Loop *L, LPPassManager &LPM) = 0;
+ virtual bool runOnFunctionBody (Function &F, LPPassManager &LPM) {
+ return false;
+ }
+
+ // Initialization and finalization hooks.
+ virtual bool doInitialization(Loop *L, LPPassManager &LPM) {
+ return false;
+ }
+
+ // Finalization hook does not supply Loop because at this time
+ // loop nest is completely different.
+ virtual bool doFinalization() { return false; }
+
+ // Check if this pass is suitable for the current LPPassManager, if
+ // available. This pass P is not suitable for a LPPassManager if P
+ // is not preserving higher level analysis info used by other
+ // LPPassManager passes. In such case, pop LPPassManager from the
+ // stack. This will force assignPassManager() to create new
+ // LPPassManger as expected.
+ void preparePassManager(PMStack &PMS);
+
+ /// Assign pass manager to manager this pass
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType PMT = PMT_LoopPassManager);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_LoopPassManager;
+ }
+};
+
+class LPPassManager : public FunctionPass, public PMDataManager {
+
+public:
+ static char ID;
+ LPPassManager(int Depth);
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool runOnFunction(Function &F);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ // LPPassManager needs LoopInfo.
+ void getAnalysisUsage(AnalysisUsage &Info) const;
+
+ virtual const char *getPassName() const {
+ return "Loop Pass Manager";
+ }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::cerr << std::string(Offset*2, ' ') << "Loop Pass Manager\n";
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ Pass *P = getContainedPass(Index);
+ P->dumpPassStructure(Offset + 1);
+ dumpLastUses(P, Offset+1);
+ }
+ }
+
+ Pass *getContainedPass(unsigned N) {
+ assert ( N < PassVector.size() && "Pass number out of range!");
+ Pass *FP = static_cast<Pass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_LoopPassManager;
+ }
+
+public:
+ // Delete loop from the loop queue and loop nest (LoopInfo).
+ void deleteLoopFromQueue(Loop *L);
+
+ // Inset loop into the loop nest(LoopInfo) and loop queue(LQ).
+ void insertLoop(Loop *L, Loop *ParentLoop);
+
+ // Reoptimize this loop. LPPassManager will re-insert this loop into the
+ // queue. This allows LoopPass to change loop nest for the loop. This
+ // utility may send LPPassManager into infinite loops so use caution.
+ void redoLoop(Loop *L);
+
+private:
+ /// verifyLoopInfo - Verify loop nest.
+ void verifyLoopInfo();
+
+private:
+ std::deque<Loop *> LQ;
+ bool skipThisLoop;
+ bool redoThisLoop;
+ LoopInfo *LI;
+ Loop *CurrentLoop;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/MemoryDependenceAnalysis.h b/include/llvm/Analysis/MemoryDependenceAnalysis.h
new file mode 100644
index 0000000..014922e
--- /dev/null
+++ b/include/llvm/Analysis/MemoryDependenceAnalysis.h
@@ -0,0 +1,75 @@
+//===- llvm/Analysis/MemoryDependenceAnalysis.h - Memory Deps --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Owen Anderson and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an analysis that determines, for a given memory operation,
+// what preceding memory operations it depends on. It builds on alias analysis
+// information, and tries to provide a lazy, caching interface to a common kind
+// of alias information query.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
+#define LLVM_ANALYSIS_MEMORY_DEPENDENCE_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Compiler.h"
+#include <map>
+
+namespace llvm {
+
+class Function;
+class FunctionPass;
+class Instruction;
+
+class MemoryDependenceAnalysis : public FunctionPass {
+ private:
+
+ DenseMap<Instruction*, std::pair<Instruction*, bool> > depGraphLocal;
+ std::multimap<Instruction*, Instruction*> reverseDep;
+
+ Instruction* getCallSiteDependency(CallSite C, Instruction* start,
+ bool local = true);
+ public:
+
+ static Instruction* NonLocal;
+ static Instruction* None;
+
+ static char ID; // Class identification, replacement for typeinfo
+ MemoryDependenceAnalysis() : FunctionPass((intptr_t)&ID) {}
+
+ /// Pass Implementation stuff. This doesn't do any analysis.
+ ///
+ bool runOnFunction(Function &) {return false; }
+
+ /// Clean up memory in between runs
+ void releaseMemory() {
+ depGraphLocal.clear();
+ reverseDep.clear();
+ }
+
+ /// getAnalysisUsage - Does not modify anything. It uses Value Numbering
+ /// and Alias Analysis.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// getDependency - Return the instruction on which a memory operation
+ /// depends, starting with start.
+ Instruction* getDependency(Instruction* query, Instruction* start = 0,
+ bool local = true);
+
+ /// removeInstruction - Remove an instruction from the dependence analysis,
+ /// updating the dependence of instructions that previously depended on it.
+ void removeInstruction(Instruction* rem);
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h
new file mode 100644
index 0000000..854128e
--- /dev/null
+++ b/include/llvm/Analysis/Passes.h
@@ -0,0 +1,117 @@
+//===-- llvm/Analysis/Passes.h - Constructors for analyses ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the analysis libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PASSES_H
+#define LLVM_ANALYSIS_PASSES_H
+
+namespace llvm {
+ class FunctionPass;
+ class ImmutablePass;
+ class ModulePass;
+ class Pass;
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createGlobalsModRefPass - This pass provides alias and mod/ref info for
+ // global values that do not have their addresses taken.
+ //
+ Pass *createGlobalsModRefPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAliasDebugger - This pass helps debug clients of AA
+ //
+ Pass *createAliasDebugger();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAliasAnalysisCounterPass - This pass counts alias queries and how the
+ // alias analysis implementation responds.
+ //
+ ModulePass *createAliasAnalysisCounterPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAAEvalPass - This pass implements a simple N^2 alias analysis
+ // accuracy evaluator.
+ //
+ FunctionPass *createAAEvalPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoAAPass - This pass implements a "I don't know" alias analysis.
+ //
+ ImmutablePass *createNoAAPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createBasicAliasAnalysisPass - This pass implements the default alias
+ // analysis.
+ //
+ ImmutablePass *createBasicAliasAnalysisPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createAndersensPass - This pass implements Andersen's interprocedural alias
+ // analysis.
+ //
+ ModulePass *createAndersensPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createBasicVNPass - This pass walks SSA def-use chains to trivially
+ // identify lexically identical expressions.
+ //
+ ImmutablePass *createBasicVNPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createProfileLoaderPass - This pass loads information from a profile dump
+ // file.
+ //
+ ModulePass *createProfileLoaderPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createNoProfileInfoPass - This pass implements the default "no profile".
+ //
+ ImmutablePass *createNoProfileInfoPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createDSAAPass - This pass implements simple context sensitive alias
+ // analysis.
+ //
+ ModulePass *createDSAAPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createDSOptPass - This pass uses DSA to do a series of simple
+ // optimizations.
+ //
+ ModulePass *createDSOptPass();
+
+ //===--------------------------------------------------------------------===//
+ //
+ // createSteensgaardPass - This pass uses the data structure graphs to do a
+ // simple context insensitive alias analysis.
+ //
+ ModulePass *createSteensgaardPass();
+
+ // Minor pass prototypes, allowing us to expose them through bugpoint and
+ // analyze.
+ FunctionPass *createInstCountPass();
+}
+
+#endif
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
new file mode 100644
index 0000000..091925e
--- /dev/null
+++ b/include/llvm/Analysis/PostDominators.h
@@ -0,0 +1,86 @@
+//=- llvm/Analysis/PostDominators.h - Post Dominator Calculation-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes interfaces to post dominance information.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_POST_DOMINATORS_H
+#define LLVM_ANALYSIS_POST_DOMINATORS_H
+
+#include "llvm/Analysis/Dominators.h"
+
+namespace llvm {
+
+/// PostDominatorTree Class - Concrete subclass of DominatorTree that is used to
+/// compute the a post-dominator tree.
+///
+struct PostDominatorTree : public DominatorTreeBase {
+ static char ID; // Pass identification, replacement for typeid
+
+ PostDominatorTree() :
+ DominatorTreeBase((intptr_t)&ID, true) {}
+
+ virtual bool runOnFunction(Function &F) {
+ reset(); // Reset from the last time we were run...
+ calculate(F);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+private:
+ void calculate(Function &F);
+ DomTreeNode *getNodeForBlock(BasicBlock *BB);
+ unsigned DFSPass(BasicBlock *V, InfoRec &VInfo,unsigned N);
+ void Compress(BasicBlock *V, InfoRec &VInfo);
+ BasicBlock *Eval(BasicBlock *V);
+ void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo);
+
+ inline BasicBlock *getIDom(BasicBlock *BB) const {
+ std::map<BasicBlock*, BasicBlock*>::const_iterator I = IDoms.find(BB);
+ return I != IDoms.end() ? I->second : 0;
+ }
+};
+
+
+/// PostDominanceFrontier Class - Concrete subclass of DominanceFrontier that is
+/// used to compute the a post-dominance frontier.
+///
+struct PostDominanceFrontier : public DominanceFrontierBase {
+ static char ID;
+ PostDominanceFrontier()
+ : DominanceFrontierBase((intptr_t) &ID, true) {}
+
+ virtual bool runOnFunction(Function &) {
+ Frontiers.clear();
+ PostDominatorTree &DT = getAnalysis<PostDominatorTree>();
+ Roots = DT.getRoots();
+ if (const DomTreeNode *Root = DT.getRootNode())
+ calculate(DT, Root);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<PostDominatorTree>();
+ }
+
+private:
+ const DomSetType &calculate(const PostDominatorTree &DT,
+ const DomTreeNode *Node);
+};
+
+} // End llvm namespace
+
+// Make sure that any clients of this file link in PostDominators.cpp
+FORCE_DEFINING_FILE_TO_BE_LINKED(PostDominanceFrontier)
+
+#endif
diff --git a/include/llvm/Analysis/ProfileInfo.h b/include/llvm/Analysis/ProfileInfo.h
new file mode 100644
index 0000000..74e3bc2
--- /dev/null
+++ b/include/llvm/Analysis/ProfileInfo.h
@@ -0,0 +1,67 @@
+//===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the generic ProfileInfo interface, which is used as the
+// common interface used by all clients of profiling information, and
+// implemented either by making static guestimations, or by actually reading in
+// profiling information gathered by running the program.
+//
+// Note that to be useful, all profile-based optimizations should preserve
+// ProfileInfo, which requires that they notify it when changes to the CFG are
+// made.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PROFILEINFO_H
+#define LLVM_ANALYSIS_PROFILEINFO_H
+
+#include <string>
+#include <map>
+
+namespace llvm {
+ class BasicBlock;
+ class Pass;
+
+ /// ProfileInfo Class - This class holds and maintains edge profiling
+ /// information for some unit of code.
+ class ProfileInfo {
+ protected:
+ // EdgeCounts - Count the number of times a transition between two blocks is
+ // executed. As a special case, we also hold an edge from the null
+ // BasicBlock to the entry block to indicate how many times the function was
+ // entered.
+ std::map<std::pair<BasicBlock*, BasicBlock*>, unsigned> EdgeCounts;
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ virtual ~ProfileInfo(); // We want to be subclassed
+
+ //===------------------------------------------------------------------===//
+ /// Profile Information Queries
+ ///
+ unsigned getExecutionCount(BasicBlock *BB) const;
+
+ unsigned getEdgeWeight(BasicBlock *Src, BasicBlock *Dest) const {
+ std::map<std::pair<BasicBlock*, BasicBlock*>, unsigned>::const_iterator I=
+ EdgeCounts.find(std::make_pair(Src, Dest));
+ return I != EdgeCounts.end() ? I->second : 0;
+ }
+
+ //===------------------------------------------------------------------===//
+ /// Analysis Update Methods
+ ///
+
+ };
+
+ /// createProfileLoaderPass - This function returns a Pass that loads the
+ /// profiling information for the module from the specified filename, making
+ /// it available to the optimizers.
+ Pass *createProfileLoaderPass(const std::string &Filename);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/ProfileInfoLoader.h b/include/llvm/Analysis/ProfileInfoLoader.h
new file mode 100644
index 0000000..6c3c41d
--- /dev/null
+++ b/include/llvm/Analysis/ProfileInfoLoader.h
@@ -0,0 +1,89 @@
+//===- ProfileInfoLoader.h - Load & convert profile information -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ProfileInfoLoader class is used to load and represent profiling
+// information read in from the dump file. If conversions between formats are
+// needed, it can also do this.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_PROFILEINFOLOADER_H
+#define LLVM_ANALYSIS_PROFILEINFOLOADER_H
+
+#include <vector>
+#include <string>
+#include <utility>
+
+namespace llvm {
+
+class Module;
+class Function;
+class BasicBlock;
+
+class ProfileInfoLoader {
+ Module &M;
+ std::vector<std::string> CommandLines;
+ std::vector<unsigned> FunctionCounts;
+ std::vector<unsigned> BlockCounts;
+ std::vector<unsigned> EdgeCounts;
+ std::vector<unsigned> BBTrace;
+public:
+ // ProfileInfoLoader ctor - Read the specified profiling data file, exiting
+ // the program if the file is invalid or broken.
+ ProfileInfoLoader(const char *ToolName, const std::string &Filename,
+ Module &M);
+
+ unsigned getNumExecutions() const { return CommandLines.size(); }
+ const std::string &getExecution(unsigned i) const { return CommandLines[i]; }
+
+ // getFunctionCounts - This method is used by consumers of function counting
+ // information. If we do not directly have function count information, we
+ // compute it from other, more refined, types of profile information.
+ //
+ void getFunctionCounts(std::vector<std::pair<Function*, unsigned> > &Counts);
+
+ // hasAccurateBlockCounts - Return true if we can synthesize accurate block
+ // frequency information from whatever we have.
+ //
+ bool hasAccurateBlockCounts() const {
+ return !BlockCounts.empty() || !EdgeCounts.empty();
+ }
+
+ // hasAccurateEdgeCounts - Return true if we can synthesize accurate edge
+ // frequency information from whatever we have.
+ //
+ bool hasAccurateEdgeCounts() const {
+ return !EdgeCounts.empty();
+ }
+
+ // getBlockCounts - This method is used by consumers of block counting
+ // information. If we do not directly have block count information, we
+ // compute it from other, more refined, types of profile information.
+ //
+ void getBlockCounts(std::vector<std::pair<BasicBlock*, unsigned> > &Counts);
+
+ // getEdgeCounts - This method is used by consumers of edge counting
+ // information. If we do not directly have edge count information, we compute
+ // it from other, more refined, types of profile information.
+ //
+ // Edges are represented as a pair, where the first element is the basic block
+ // and the second element is the successor number.
+ //
+ typedef std::pair<BasicBlock*, unsigned> Edge;
+ void getEdgeCounts(std::vector<std::pair<Edge, unsigned> > &Counts);
+
+ // getBBTrace - This method is used by consumers of basic-block trace
+ // information.
+ //
+ void getBBTrace(std::vector<BasicBlock *> &Trace);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Analysis/ProfileInfoTypes.h b/include/llvm/Analysis/ProfileInfoTypes.h
new file mode 100644
index 0000000..c662c3c
--- /dev/null
+++ b/include/llvm/Analysis/ProfileInfoTypes.h
@@ -0,0 +1,28 @@
+/*===-- ProfileInfoTypes.h - Profiling info shared constants ------*- C -*-===*\
+|*
+|* The LLVM Compiler Infrastructure
+|*
+|* This file was developed by the LLVM research group and is distributed under
+|* the University of Illinois Open Source License. See LICENSE.TXT for details.
+|*
+|*===----------------------------------------------------------------------===*|
+|*
+|* This file defines constants shared by the various different profiling
+|* runtime libraries and the LLVM C++ profile info loader. It must be a
+|* C header because, at present, the profiling runtimes are written in C.
+|*
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_ANALYSIS_PROFILEINFOTYPES_H
+#define LLVM_ANALYSIS_PROFILEINFOTYPES_H
+
+enum ProfilingType {
+ ArgumentInfo = 1, /* The command line argument block */
+ FunctionInfo = 2, /* Function profiling information */
+ BlockInfo = 3, /* Block profiling information */
+ EdgeInfo = 4, /* Edge profiling information */
+ PathInfo = 5, /* Path profiling information */
+ BBTraceInfo = 6 /* Basic block trace information */
+};
+
+#endif /* LLVM_ANALYSIS_PROFILEINFOTYPES_H */
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
new file mode 100644
index 0000000..b6a58fe
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -0,0 +1,250 @@
+//===- llvm/Analysis/ScalarEvolution.h - Scalar Evolution -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ScalarEvolution class is an LLVM pass which can be used to analyze and
+// catagorize scalar expressions in loops. It specializes in recognizing
+// general induction variables, representing them with the abstract and opaque
+// SCEV class. Given this analysis, trip counts of loops and other important
+// properties can be obtained.
+//
+// This analysis is primarily useful for induction variable substitution and
+// strength reduction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include <set>
+
+namespace llvm {
+ class Instruction;
+ class Type;
+ class ConstantRange;
+ class Loop;
+ class LoopInfo;
+ class SCEVHandle;
+
+ /// SCEV - This class represent an analyzed expression in the program. These
+ /// are reference counted opaque objects that the client is not allowed to
+ /// do much with directly.
+ ///
+ class SCEV {
+ const unsigned SCEVType; // The SCEV baseclass this node corresponds to
+ mutable unsigned RefCount;
+
+ friend class SCEVHandle;
+ void addRef() const { ++RefCount; }
+ void dropRef() const {
+ if (--RefCount == 0)
+ delete this;
+ }
+
+ SCEV(const SCEV &); // DO NOT IMPLEMENT
+ void operator=(const SCEV &); // DO NOT IMPLEMENT
+ protected:
+ virtual ~SCEV();
+ public:
+ explicit SCEV(unsigned SCEVTy) : SCEVType(SCEVTy), RefCount(0) {}
+
+ /// getNegativeSCEV - Return the SCEV object corresponding to -V.
+ ///
+ static SCEVHandle getNegativeSCEV(const SCEVHandle &V);
+
+ /// getMinusSCEV - Return LHS-RHS.
+ ///
+ static SCEVHandle getMinusSCEV(const SCEVHandle &LHS,
+ const SCEVHandle &RHS);
+
+
+ unsigned getSCEVType() const { return SCEVType; }
+
+ /// getValueRange - Return the tightest constant bounds that this value is
+ /// known to have. This method is only valid on integer SCEV objects.
+ virtual ConstantRange getValueRange() const;
+
+ /// isLoopInvariant - Return true if the value of this SCEV is unchanging in
+ /// the specified loop.
+ virtual bool isLoopInvariant(const Loop *L) const = 0;
+
+ /// hasComputableLoopEvolution - Return true if this SCEV changes value in a
+ /// known way in the specified loop. This property being true implies that
+ /// the value is variant in the loop AND that we can emit an expression to
+ /// compute the value of the expression at any particular loop iteration.
+ virtual bool hasComputableLoopEvolution(const Loop *L) const = 0;
+
+ /// getType - Return the LLVM type of this SCEV expression.
+ ///
+ virtual const Type *getType() const = 0;
+
+ /// getBitWidth - Get the bit width of the type, if it has one, 0 otherwise.
+ ///
+ uint32_t getBitWidth() const;
+
+ /// replaceSymbolicValuesWithConcrete - If this SCEV internally references
+ /// the symbolic value "Sym", construct and return a new SCEV that produces
+ /// the same value, but which uses the concrete value Conc instead of the
+ /// symbolic value. If this SCEV does not use the symbolic value, it
+ /// returns itself.
+ virtual SCEVHandle
+ replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const = 0;
+
+ /// print - Print out the internal representation of this scalar to the
+ /// specified stream. This should really only be used for debugging
+ /// purposes.
+ virtual void print(std::ostream &OS) const = 0;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - This method is used for debugging.
+ ///
+ void dump() const;
+ };
+
+ inline std::ostream &operator<<(std::ostream &OS, const SCEV &S) {
+ S.print(OS);
+ return OS;
+ }
+
+ /// SCEVCouldNotCompute - An object of this class is returned by queries that
+ /// could not be answered. For example, if you ask for the number of
+ /// iterations of a linked-list traversal loop, you will get one of these.
+ /// None of the standard SCEV operations are valid on this class, it is just a
+ /// marker.
+ struct SCEVCouldNotCompute : public SCEV {
+ SCEVCouldNotCompute();
+
+ // None of these methods are valid for this object.
+ virtual bool isLoopInvariant(const Loop *L) const;
+ virtual const Type *getType() const;
+ virtual bool hasComputableLoopEvolution(const Loop *L) const;
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ virtual SCEVHandle
+ replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVCouldNotCompute *S) { return true; }
+ static bool classof(const SCEV *S);
+ };
+
+ /// SCEVHandle - This class is used to maintain the SCEV object's refcounts,
+ /// freeing the objects when the last reference is dropped.
+ class SCEVHandle {
+ SCEV *S;
+ SCEVHandle(); // DO NOT IMPLEMENT
+ public:
+ SCEVHandle(const SCEV *s) : S(const_cast<SCEV*>(s)) {
+ assert(S && "Cannot create a handle to a null SCEV!");
+ S->addRef();
+ }
+ SCEVHandle(const SCEVHandle &RHS) : S(RHS.S) {
+ S->addRef();
+ }
+ ~SCEVHandle() { S->dropRef(); }
+
+ operator SCEV*() const { return S; }
+
+ SCEV &operator*() const { return *S; }
+ SCEV *operator->() const { return S; }
+
+ bool operator==(SCEV *RHS) const { return S == RHS; }
+ bool operator!=(SCEV *RHS) const { return S != RHS; }
+
+ const SCEVHandle &operator=(SCEV *RHS) {
+ if (S != RHS) {
+ S->dropRef();
+ S = RHS;
+ S->addRef();
+ }
+ return *this;
+ }
+
+ const SCEVHandle &operator=(const SCEVHandle &RHS) {
+ if (S != RHS.S) {
+ S->dropRef();
+ S = RHS.S;
+ S->addRef();
+ }
+ return *this;
+ }
+ };
+
+ template<typename From> struct simplify_type;
+ template<> struct simplify_type<const SCEVHandle> {
+ typedef SCEV* SimpleType;
+ static SimpleType getSimplifiedValue(const SCEVHandle &Node) {
+ return Node;
+ }
+ };
+ template<> struct simplify_type<SCEVHandle>
+ : public simplify_type<const SCEVHandle> {};
+
+ /// ScalarEvolution - This class is the main scalar evolution driver. Because
+ /// client code (intentionally) can't do much with the SCEV objects directly,
+ /// they must ask this class for services.
+ ///
+ class ScalarEvolution : public FunctionPass {
+ void *Impl; // ScalarEvolution uses the pimpl pattern
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ ScalarEvolution() : FunctionPass((intptr_t)&ID), Impl(0) {}
+
+ /// getSCEV - Return a SCEV expression handle for the full generality of the
+ /// specified expression.
+ SCEVHandle getSCEV(Value *V) const;
+
+ /// hasSCEV - Return true if the SCEV for this value has already been
+ /// computed.
+ bool hasSCEV(Value *V) const;
+
+ /// setSCEV - Insert the specified SCEV into the map of current SCEVs for
+ /// the specified value.
+ void setSCEV(Value *V, const SCEVHandle &H);
+
+ /// getSCEVAtScope - Return a SCEV expression handle for the specified value
+ /// at the specified scope in the program. The L value specifies a loop
+ /// nest to evaluate the expression at, where null is the top-level or a
+ /// specified loop is immediately inside of the loop.
+ ///
+ /// This method can be used to compute the exit value for a variable defined
+ /// in a loop by querying what the value will hold in the parent loop.
+ ///
+ /// If this value is not computable at this scope, a SCEVCouldNotCompute
+ /// object is returned.
+ SCEVHandle getSCEVAtScope(Value *V, const Loop *L) const;
+
+ /// getIterationCount - If the specified loop has a predictable iteration
+ /// count, return it, otherwise return a SCEVCouldNotCompute object.
+ SCEVHandle getIterationCount(const Loop *L) const;
+
+ /// hasLoopInvariantIterationCount - Return true if the specified loop has
+ /// an analyzable loop-invariant iteration count.
+ bool hasLoopInvariantIterationCount(const Loop *L) const;
+
+ /// deleteValueFromRecords - This method should be called by the
+ /// client before it removes a Value from the program, to make sure
+ /// that no dangling references are left around.
+ void deleteValueFromRecords(Value *V) const;
+
+ virtual bool runOnFunction(Function &F);
+ virtual void releaseMemory();
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void print(std::ostream &OS, const Module* = 0) const;
+ void print(std::ostream *OS, const Module* M = 0) const {
+ if (OS) print(*OS, M);
+ }
+ };
+}
+
+#endif
diff --git a/include/llvm/Analysis/ScalarEvolutionExpander.h b/include/llvm/Analysis/ScalarEvolutionExpander.h
new file mode 100644
index 0000000..a5cc713
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolutionExpander.h
@@ -0,0 +1,153 @@
+//===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the classes used to generate code from scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Type.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Support/CFG.h"
+
+namespace llvm {
+ /// SCEVExpander - This class uses information about analyze scalars to
+ /// rewrite expressions in canonical form.
+ ///
+ /// Clients should create an instance of this class when rewriting is needed,
+ /// and destroy it when finished to allow the release of the associated
+ /// memory.
+ struct SCEVExpander : public SCEVVisitor<SCEVExpander, Value*> {
+ ScalarEvolution &SE;
+ LoopInfo &LI;
+ std::map<SCEVHandle, Value*> InsertedExpressions;
+ std::set<Instruction*> InsertedInstructions;
+
+ Instruction *InsertPt;
+
+ friend struct SCEVVisitor<SCEVExpander, Value*>;
+ public:
+ SCEVExpander(ScalarEvolution &se, LoopInfo &li) : SE(se), LI(li) {}
+
+ LoopInfo &getLoopInfo() const { return LI; }
+
+ /// clear - Erase the contents of the InsertedExpressions map so that users
+ /// trying to expand the same expression into multiple BasicBlocks or
+ /// different places within the same BasicBlock can do so.
+ void clear() { InsertedExpressions.clear(); }
+
+ /// isInsertedInstruction - Return true if the specified instruction was
+ /// inserted by the code rewriter. If so, the client should not modify the
+ /// instruction.
+ bool isInsertedInstruction(Instruction *I) const {
+ return InsertedInstructions.count(I);
+ }
+
+ /// getOrInsertCanonicalInductionVariable - This method returns the
+ /// canonical induction variable of the specified type for the specified
+ /// loop (inserting one if there is none). A canonical induction variable
+ /// starts at zero and steps by one on each iteration.
+ Value *getOrInsertCanonicalInductionVariable(const Loop *L, const Type *Ty){
+ assert(Ty->isInteger() && "Can only insert integer induction variables!");
+ SCEVHandle H = SCEVAddRecExpr::get(SCEVUnknown::getIntegerSCEV(0, Ty),
+ SCEVUnknown::getIntegerSCEV(1, Ty), L);
+ return expand(H);
+ }
+
+ /// addInsertedValue - Remember the specified instruction as being the
+ /// canonical form for the specified SCEV.
+ void addInsertedValue(Instruction *I, SCEV *S) {
+ InsertedExpressions[S] = (Value*)I;
+ InsertedInstructions.insert(I);
+ }
+
+ Instruction *getInsertionPoint() const { return InsertPt; }
+
+ /// expandCodeFor - Insert code to directly compute the specified SCEV
+ /// expression into the program. The inserted code is inserted into the
+ /// specified block.
+ Value *expandCodeFor(SCEVHandle SH, Instruction *IP) {
+ // Expand the code for this SCEV.
+ this->InsertPt = IP;
+ return expand(SH);
+ }
+
+ /// InsertCastOfTo - Insert a cast of V to the specified type, doing what
+ /// we can to share the casts.
+ static Value *InsertCastOfTo(Instruction::CastOps opcode, Value *V,
+ const Type *Ty);
+ /// InsertBinop - Insert the specified binary operator, doing a small amount
+ /// of work to avoid inserting an obviously redundant operation.
+ static Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
+ Value *RHS, Instruction *&InsertPt);
+ protected:
+ Value *expand(SCEV *S) {
+ // Check to see if we already expanded this.
+ std::map<SCEVHandle, Value*>::iterator I = InsertedExpressions.find(S);
+ if (I != InsertedExpressions.end())
+ return I->second;
+
+ Value *V = visit(S);
+ InsertedExpressions[S] = V;
+ return V;
+ }
+
+ Value *visitConstant(SCEVConstant *S) {
+ return S->getValue();
+ }
+
+ Value *visitTruncateExpr(SCEVTruncateExpr *S) {
+ Value *V = expand(S->getOperand());
+ return CastInst::createTruncOrBitCast(V, S->getType(), "tmp.", InsertPt);
+ }
+
+ Value *visitZeroExtendExpr(SCEVZeroExtendExpr *S) {
+ Value *V = expand(S->getOperand());
+ return CastInst::createZExtOrBitCast(V, S->getType(), "tmp.", InsertPt);
+ }
+
+ Value *visitSignExtendExpr(SCEVSignExtendExpr *S) {
+ Value *V = expand(S->getOperand());
+ return CastInst::createSExtOrBitCast(V, S->getType(), "tmp.", InsertPt);
+ }
+
+ Value *visitAddExpr(SCEVAddExpr *S) {
+ Value *V = expand(S->getOperand(S->getNumOperands()-1));
+
+ // Emit a bunch of add instructions
+ for (int i = S->getNumOperands()-2; i >= 0; --i)
+ V = InsertBinop(Instruction::Add, V, expand(S->getOperand(i)),
+ InsertPt);
+ return V;
+ }
+
+ Value *visitMulExpr(SCEVMulExpr *S);
+
+ Value *visitSDivExpr(SCEVSDivExpr *S) {
+ Value *LHS = expand(S->getLHS());
+ Value *RHS = expand(S->getRHS());
+ return InsertBinop(Instruction::SDiv, LHS, RHS, InsertPt);
+ }
+
+ Value *visitAddRecExpr(SCEVAddRecExpr *S);
+
+ Value *visitUnknown(SCEVUnknown *S) {
+ return S->getValue();
+ }
+ };
+}
+
+#endif
+
diff --git a/include/llvm/Analysis/ScalarEvolutionExpressions.h b/include/llvm/Analysis/ScalarEvolutionExpressions.h
new file mode 100644
index 0000000..af1656e
--- /dev/null
+++ b/include/llvm/Analysis/ScalarEvolutionExpressions.h
@@ -0,0 +1,580 @@
+//===- llvm/Analysis/ScalarEvolutionExpressions.h - SCEV Exprs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the classes used to represent and build scalar expressions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
+#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPRESSIONS_H
+
+#include "llvm/Analysis/ScalarEvolution.h"
+
+namespace llvm {
+ class ConstantInt;
+ class ConstantRange;
+ class APInt;
+
+ enum SCEVTypes {
+ // These should be ordered in terms of increasing complexity to make the
+ // folders simpler.
+ scConstant, scTruncate, scZeroExtend, scSignExtend, scAddExpr, scMulExpr,
+ scSDivExpr, scAddRecExpr, scUnknown, scCouldNotCompute
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVConstant - This class represents a constant integer value.
+ ///
+ class SCEVConstant : public SCEV {
+ ConstantInt *V;
+ explicit SCEVConstant(ConstantInt *v) : SCEV(scConstant), V(v) {}
+
+ virtual ~SCEVConstant();
+ public:
+ /// get method - This just gets and returns a new SCEVConstant object.
+ ///
+ static SCEVHandle get(ConstantInt *V);
+ static SCEVHandle get(const APInt& Val);
+
+ ConstantInt *getValue() const { return V; }
+
+ /// getValueRange - Return the tightest constant bounds that this value is
+ /// known to have. This method is only valid on integer SCEV objects.
+ virtual ConstantRange getValueRange() const;
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ return true;
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ return false; // Not loop variant
+ }
+
+ virtual const Type *getType() const;
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ return this;
+ }
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVConstant *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scConstant;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVTruncateExpr - This class represents a truncation of an integer value
+ /// to a smaller integer value.
+ ///
+ class SCEVTruncateExpr : public SCEV {
+ SCEVHandle Op;
+ const Type *Ty;
+ SCEVTruncateExpr(const SCEVHandle &op, const Type *ty);
+ virtual ~SCEVTruncateExpr();
+ public:
+ /// get method - This just gets and returns a new SCEVTruncate object
+ ///
+ static SCEVHandle get(const SCEVHandle &Op, const Type *Ty);
+
+ const SCEVHandle &getOperand() const { return Op; }
+ virtual const Type *getType() const { return Ty; }
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ return Op->isLoopInvariant(L);
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ return Op->hasComputableLoopEvolution(L);
+ }
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H == Op)
+ return this;
+ return get(H, Ty);
+ }
+
+ /// getValueRange - Return the tightest constant bounds that this value is
+ /// known to have. This method is only valid on integer SCEV objects.
+ virtual ConstantRange getValueRange() const;
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVTruncateExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scTruncate;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVZeroExtendExpr - This class represents a zero extension of a small
+ /// integer value to a larger integer value.
+ ///
+ class SCEVZeroExtendExpr : public SCEV {
+ SCEVHandle Op;
+ const Type *Ty;
+ SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty);
+ virtual ~SCEVZeroExtendExpr();
+ public:
+ /// get method - This just gets and returns a new SCEVZeroExtend object
+ ///
+ static SCEVHandle get(const SCEVHandle &Op, const Type *Ty);
+
+ const SCEVHandle &getOperand() const { return Op; }
+ virtual const Type *getType() const { return Ty; }
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ return Op->isLoopInvariant(L);
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ return Op->hasComputableLoopEvolution(L);
+ }
+
+ /// getValueRange - Return the tightest constant bounds that this value is
+ /// known to have. This method is only valid on integer SCEV objects.
+ virtual ConstantRange getValueRange() const;
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H == Op)
+ return this;
+ return get(H, Ty);
+ }
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVZeroExtendExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scZeroExtend;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVSignExtendExpr - This class represents a sign extension of a small
+ /// integer value to a larger integer value.
+ ///
+ class SCEVSignExtendExpr : public SCEV {
+ SCEVHandle Op;
+ const Type *Ty;
+ SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty);
+ virtual ~SCEVSignExtendExpr();
+ public:
+ /// get method - This just gets and returns a new SCEVSignExtend object
+ ///
+ static SCEVHandle get(const SCEVHandle &Op, const Type *Ty);
+
+ const SCEVHandle &getOperand() const { return Op; }
+ virtual const Type *getType() const { return Ty; }
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ return Op->isLoopInvariant(L);
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ return Op->hasComputableLoopEvolution(L);
+ }
+
+ /// getValueRange - Return the tightest constant bounds that this value is
+ /// known to have. This method is only valid on integer SCEV objects.
+ virtual ConstantRange getValueRange() const;
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle H = Op->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H == Op)
+ return this;
+ return get(H, Ty);
+ }
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVSignExtendExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scSignExtend;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVCommutativeExpr - This node is the base class for n'ary commutative
+ /// operators.
+ ///
+ class SCEVCommutativeExpr : public SCEV {
+ std::vector<SCEVHandle> Operands;
+
+ protected:
+ SCEVCommutativeExpr(enum SCEVTypes T, const std::vector<SCEVHandle> &ops)
+ : SCEV(T) {
+ Operands.reserve(ops.size());
+ Operands.insert(Operands.end(), ops.begin(), ops.end());
+ }
+ ~SCEVCommutativeExpr();
+
+ public:
+ unsigned getNumOperands() const { return Operands.size(); }
+ const SCEVHandle &getOperand(unsigned i) const {
+ assert(i < Operands.size() && "Operand index out of range!");
+ return Operands[i];
+ }
+
+ const std::vector<SCEVHandle> &getOperands() const { return Operands; }
+ typedef std::vector<SCEVHandle>::const_iterator op_iterator;
+ op_iterator op_begin() const { return Operands.begin(); }
+ op_iterator op_end() const { return Operands.end(); }
+
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (!getOperand(i)->isLoopInvariant(L)) return false;
+ return true;
+ }
+
+ // hasComputableLoopEvolution - Commutative expressions have computable loop
+ // evolutions iff they have at least one operand that varies with the loop,
+ // but that all varying operands are computable.
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ bool HasVarying = false;
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (!getOperand(i)->isLoopInvariant(L))
+ if (getOperand(i)->hasComputableLoopEvolution(L))
+ HasVarying = true;
+ else
+ return false;
+ return HasVarying;
+ }
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const;
+
+ virtual const char *getOperationStr() const = 0;
+
+ virtual const Type *getType() const { return getOperand(0)->getType(); }
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVCommutativeExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scAddExpr ||
+ S->getSCEVType() == scMulExpr;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVAddExpr - This node represents an addition of some number of SCEVs.
+ ///
+ class SCEVAddExpr : public SCEVCommutativeExpr {
+ SCEVAddExpr(const std::vector<SCEVHandle> &ops)
+ : SCEVCommutativeExpr(scAddExpr, ops) {
+ }
+
+ public:
+ static SCEVHandle get(std::vector<SCEVHandle> &Ops);
+
+ static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) {
+ std::vector<SCEVHandle> Ops;
+ Ops.push_back(LHS);
+ Ops.push_back(RHS);
+ return get(Ops);
+ }
+
+ static SCEVHandle get(const SCEVHandle &Op0, const SCEVHandle &Op1,
+ const SCEVHandle &Op2) {
+ std::vector<SCEVHandle> Ops;
+ Ops.push_back(Op0);
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ return get(Ops);
+ }
+
+ virtual const char *getOperationStr() const { return " + "; }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVAddExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scAddExpr;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVMulExpr - This node represents multiplication of some number of SCEVs.
+ ///
+ class SCEVMulExpr : public SCEVCommutativeExpr {
+ SCEVMulExpr(const std::vector<SCEVHandle> &ops)
+ : SCEVCommutativeExpr(scMulExpr, ops) {
+ }
+
+ public:
+ static SCEVHandle get(std::vector<SCEVHandle> &Ops);
+
+ static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS) {
+ std::vector<SCEVHandle> Ops;
+ Ops.push_back(LHS);
+ Ops.push_back(RHS);
+ return get(Ops);
+ }
+
+ virtual const char *getOperationStr() const { return " * "; }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVMulExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scMulExpr;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVSDivExpr - This class represents a binary signed division operation.
+ ///
+ class SCEVSDivExpr : public SCEV {
+ SCEVHandle LHS, RHS;
+ SCEVSDivExpr(const SCEVHandle &lhs, const SCEVHandle &rhs)
+ : SCEV(scSDivExpr), LHS(lhs), RHS(rhs) {}
+
+ virtual ~SCEVSDivExpr();
+ public:
+ /// get method - This just gets and returns a new SCEVSDiv object.
+ ///
+ static SCEVHandle get(const SCEVHandle &LHS, const SCEVHandle &RHS);
+
+ const SCEVHandle &getLHS() const { return LHS; }
+ const SCEVHandle &getRHS() const { return RHS; }
+
+ virtual bool isLoopInvariant(const Loop *L) const {
+ return LHS->isLoopInvariant(L) && RHS->isLoopInvariant(L);
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *L) const {
+ return LHS->hasComputableLoopEvolution(L) &&
+ RHS->hasComputableLoopEvolution(L);
+ }
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ SCEVHandle L = LHS->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ SCEVHandle R = RHS->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (L == LHS && R == RHS)
+ return this;
+ else
+ return get(L, R);
+ }
+
+
+ virtual const Type *getType() const;
+
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVSDivExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scSDivExpr;
+ }
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVAddRecExpr - This node represents a polynomial recurrence on the trip
+ /// count of the specified loop.
+ ///
+ /// All operands of an AddRec are required to be loop invariant.
+ ///
+ class SCEVAddRecExpr : public SCEV {
+ std::vector<SCEVHandle> Operands;
+ const Loop *L;
+
+ SCEVAddRecExpr(const std::vector<SCEVHandle> &ops, const Loop *l)
+ : SCEV(scAddRecExpr), Operands(ops), L(l) {
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ assert(Operands[i]->isLoopInvariant(l) &&
+ "Operands of AddRec must be loop-invariant!");
+ }
+ ~SCEVAddRecExpr();
+ public:
+ static SCEVHandle get(const SCEVHandle &Start, const SCEVHandle &Step,
+ const Loop *);
+ static SCEVHandle get(std::vector<SCEVHandle> &Operands,
+ const Loop *);
+ static SCEVHandle get(const std::vector<SCEVHandle> &Operands,
+ const Loop *L) {
+ std::vector<SCEVHandle> NewOp(Operands);
+ return get(NewOp, L);
+ }
+
+ typedef std::vector<SCEVHandle>::const_iterator op_iterator;
+ op_iterator op_begin() const { return Operands.begin(); }
+ op_iterator op_end() const { return Operands.end(); }
+
+ unsigned getNumOperands() const { return Operands.size(); }
+ const SCEVHandle &getOperand(unsigned i) const { return Operands[i]; }
+ const SCEVHandle &getStart() const { return Operands[0]; }
+ const Loop *getLoop() const { return L; }
+
+
+ /// getStepRecurrence - This method constructs and returns the recurrence
+ /// indicating how much this expression steps by. If this is a polynomial
+ /// of degree N, it returns a chrec of degree N-1.
+ SCEVHandle getStepRecurrence() const {
+ if (getNumOperands() == 2) return getOperand(1);
+ return SCEVAddRecExpr::get(std::vector<SCEVHandle>(op_begin()+1,op_end()),
+ getLoop());
+ }
+
+ virtual bool hasComputableLoopEvolution(const Loop *QL) const {
+ if (L == QL) return true;
+ return false;
+ }
+
+ virtual bool isLoopInvariant(const Loop *QueryLoop) const;
+
+ virtual const Type *getType() const { return Operands[0]->getType(); }
+
+ /// isAffine - Return true if this is an affine AddRec (i.e., it represents
+ /// an expressions A+B*x where A and B are loop invariant values.
+ bool isAffine() const {
+ // We know that the start value is invariant. This expression is thus
+ // affine iff the step is also invariant.
+ return getNumOperands() == 2;
+ }
+
+ /// isQuadratic - Return true if this is an quadratic AddRec (i.e., it
+ /// represents an expressions A+B*x+C*x^2 where A, B and C are loop
+ /// invariant values. This corresponds to an addrec of the form {L,+,M,+,N}
+ bool isQuadratic() const {
+ return getNumOperands() == 3;
+ }
+
+ /// evaluateAtIteration - Return the value of this chain of recurrences at
+ /// the specified iteration number.
+ SCEVHandle evaluateAtIteration(SCEVHandle It) const;
+
+ /// getNumIterationsInRange - Return the number of iterations of this loop
+ /// that produce values in the specified constant range. Another way of
+ /// looking at this is that it returns the first iteration number where the
+ /// value is not in the condition, thus computing the exit count. If the
+ /// iteration count can't be computed, an instance of SCEVCouldNotCompute is
+ /// returned.
+ SCEVHandle getNumIterationsInRange(ConstantRange Range) const;
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const;
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVAddRecExpr *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scAddRecExpr;
+ }
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SCEVUnknown - This means that we are dealing with an entirely unknown SCEV
+ /// value, and only represent it as it's LLVM Value. This is the "bottom"
+ /// value for the analysis.
+ ///
+ class SCEVUnknown : public SCEV {
+ Value *V;
+ SCEVUnknown(Value *v) : SCEV(scUnknown), V(v) {}
+
+ protected:
+ ~SCEVUnknown();
+ public:
+ /// get method - For SCEVUnknown, this just gets and returns a new
+ /// SCEVUnknown.
+ static SCEVHandle get(Value *V);
+
+ /// getIntegerSCEV - Given an integer or FP type, create a constant for the
+ /// specified signed integer value and return a SCEV for the constant.
+ static SCEVHandle getIntegerSCEV(int Val, const Type *Ty);
+
+ Value *getValue() const { return V; }
+
+ virtual bool isLoopInvariant(const Loop *L) const;
+ virtual bool hasComputableLoopEvolution(const Loop *QL) const {
+ return false; // not computable
+ }
+
+ SCEVHandle replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ if (&*Sym == this) return Conc;
+ return this;
+ }
+
+ virtual const Type *getType() const;
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SCEVUnknown *S) { return true; }
+ static inline bool classof(const SCEV *S) {
+ return S->getSCEVType() == scUnknown;
+ }
+ };
+
+ /// SCEVVisitor - This class defines a simple visitor class that may be used
+ /// for various SCEV analysis purposes.
+ template<typename SC, typename RetVal=void>
+ struct SCEVVisitor {
+ RetVal visit(SCEV *S) {
+ switch (S->getSCEVType()) {
+ case scConstant:
+ return ((SC*)this)->visitConstant((SCEVConstant*)S);
+ case scTruncate:
+ return ((SC*)this)->visitTruncateExpr((SCEVTruncateExpr*)S);
+ case scZeroExtend:
+ return ((SC*)this)->visitZeroExtendExpr((SCEVZeroExtendExpr*)S);
+ case scSignExtend:
+ return ((SC*)this)->visitSignExtendExpr((SCEVSignExtendExpr*)S);
+ case scAddExpr:
+ return ((SC*)this)->visitAddExpr((SCEVAddExpr*)S);
+ case scMulExpr:
+ return ((SC*)this)->visitMulExpr((SCEVMulExpr*)S);
+ case scSDivExpr:
+ return ((SC*)this)->visitSDivExpr((SCEVSDivExpr*)S);
+ case scAddRecExpr:
+ return ((SC*)this)->visitAddRecExpr((SCEVAddRecExpr*)S);
+ case scUnknown:
+ return ((SC*)this)->visitUnknown((SCEVUnknown*)S);
+ case scCouldNotCompute:
+ return ((SC*)this)->visitCouldNotCompute((SCEVCouldNotCompute*)S);
+ default:
+ assert(0 && "Unknown SCEV type!");
+ abort();
+ }
+ }
+
+ RetVal visitCouldNotCompute(SCEVCouldNotCompute *S) {
+ assert(0 && "Invalid use of SCEVCouldNotCompute!");
+ abort();
+ return RetVal();
+ }
+ };
+}
+
+#endif
+
diff --git a/include/llvm/Analysis/Trace.h b/include/llvm/Analysis/Trace.h
new file mode 100644
index 0000000..65aa593c8
--- /dev/null
+++ b/include/llvm/Analysis/Trace.h
@@ -0,0 +1,120 @@
+//===- llvm/Analysis/Trace.h - Represent one trace of LLVM code -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents a single trace of LLVM basic blocks. A trace is a
+// single entry, multiple exit, region of code that is often hot. Trace-based
+// optimizations treat traces almost like they are a large, strange, basic
+// block: because the trace path is assumed to be hot, optimizations for the
+// fall-through path are made at the expense of the non-fall-through paths.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_TRACE_H
+#define LLVM_ANALYSIS_TRACE_H
+
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class BasicBlock;
+ class Function;
+ class Module;
+
+class Trace {
+ typedef std::vector<BasicBlock *> BasicBlockListType;
+ BasicBlockListType BasicBlocks;
+
+public:
+ /// Trace ctor - Make a new trace from a vector of basic blocks,
+ /// residing in the function which is the parent of the first
+ /// basic block in the vector.
+ ///
+ Trace(const std::vector<BasicBlock *> &vBB) : BasicBlocks (vBB) {}
+
+ /// getEntryBasicBlock - Return the entry basic block (first block)
+ /// of the trace.
+ ///
+ BasicBlock *getEntryBasicBlock () const { return BasicBlocks[0]; }
+
+ /// operator[]/getBlock - Return basic block N in the trace.
+ ///
+ BasicBlock *operator[](unsigned i) const { return BasicBlocks[i]; }
+ BasicBlock *getBlock(unsigned i) const { return BasicBlocks[i]; }
+
+ /// getFunction - Return this trace's parent function.
+ ///
+ Function *getFunction () const;
+
+ /// getModule - Return this Module that contains this trace's parent
+ /// function.
+ ///
+ Module *getModule () const;
+
+ /// getBlockIndex - Return the index of the specified basic block in the
+ /// trace, or -1 if it is not in the trace.
+ int getBlockIndex(const BasicBlock *X) const {
+ for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i)
+ if (BasicBlocks[i] == X)
+ return i;
+ return -1;
+ }
+
+ /// contains - Returns true if this trace contains the given basic
+ /// block.
+ ///
+ bool contains(const BasicBlock *X) const {
+ return getBlockIndex(X) != -1;
+ }
+
+ /// Returns true if B1 occurs before B2 in the trace, or if it is the same
+ /// block as B2.. Both blocks must be in the trace.
+ ///
+ bool dominates(const BasicBlock *B1, const BasicBlock *B2) const {
+ int B1Idx = getBlockIndex(B1), B2Idx = getBlockIndex(B2);
+ assert(B1Idx != -1 && B2Idx != -1 && "Block is not in the trace!");
+ return B1Idx <= B2Idx;
+ }
+
+ // BasicBlock iterators...
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
+ const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+ reverse_iterator rend () { return BasicBlocks.rend(); }
+ const_reverse_iterator rend () const { return BasicBlocks.rend(); }
+
+ unsigned size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+
+ iterator erase(iterator q) { return BasicBlocks.erase (q); }
+ iterator erase(iterator q1, iterator q2) { return BasicBlocks.erase (q1, q2); }
+
+ /// print - Write trace to output stream.
+ ///
+ void print (std::ostream &O) const;
+ void print (std::ostream *O) const { if (O) print(*O); }
+
+ /// dump - Debugger convenience method; writes trace to standard error
+ /// output stream.
+ ///
+ void dump () const;
+};
+
+} // end namespace llvm
+
+#endif // TRACE_H
diff --git a/include/llvm/Analysis/ValueNumbering.h b/include/llvm/Analysis/ValueNumbering.h
new file mode 100644
index 0000000..64d528e
--- /dev/null
+++ b/include/llvm/Analysis/ValueNumbering.h
@@ -0,0 +1,74 @@
+//===- llvm/Analysis/ValueNumbering.h - Value #'ing Interface ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the abstract ValueNumbering interface, which is used as the
+// common interface used by all clients of value numbering information, and
+// implemented by all value numbering implementations.
+//
+// Implementations of this interface must implement the various virtual methods,
+// which automatically provides functionality for the entire suite of client
+// APIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_VALUE_NUMBERING_H
+#define LLVM_ANALYSIS_VALUE_NUMBERING_H
+
+#include <vector>
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class Value;
+class Instruction;
+
+struct ValueNumbering {
+ static char ID; // Class identification, replacement for typeinfo
+ virtual ~ValueNumbering(); // We want to be subclassed
+
+ /// getEqualNumberNodes - Return nodes with the same value number as the
+ /// specified Value. This fills in the argument vector with any equal values.
+ ///
+ virtual void getEqualNumberNodes(Value *V1,
+ std::vector<Value*> &RetVals) const = 0;
+
+ ///===-------------------------------------------------------------------===//
+ /// Interfaces to update value numbering analysis information as the client
+ /// changes the program.
+ ///
+
+ /// deleteValue - This method should be called whenever an LLVM Value is
+ /// deleted from the program, for example when an instruction is found to be
+ /// redundant and is eliminated.
+ ///
+ virtual void deleteValue(Value *V) {}
+
+ /// copyValue - This method should be used whenever a preexisting value in the
+ /// program is copied or cloned, introducing a new value. Note that analysis
+ /// implementations should tolerate clients that use this method to introduce
+ /// the same value multiple times: if the analysis already knows about a
+ /// value, it should ignore the request.
+ ///
+ virtual void copyValue(Value *From, Value *To) {}
+
+ /// replaceWithNewValue - This method is the obvious combination of the two
+ /// above, and it provided as a helper to simplify client code.
+ ///
+ void replaceWithNewValue(Value *Old, Value *New) {
+ copyValue(Old, New);
+ deleteValue(Old);
+ }
+};
+
+} // End llvm namespace
+
+// Force any file including this header to get the implementation as well
+FORCE_DEFINING_FILE_TO_BE_LINKED(BasicValueNumbering)
+
+#endif
diff --git a/include/llvm/Analysis/Verifier.h b/include/llvm/Analysis/Verifier.h
new file mode 100644
index 0000000..dd914a4
--- /dev/null
+++ b/include/llvm/Analysis/Verifier.h
@@ -0,0 +1,75 @@
+//===-- llvm/Analysis/Verifier.h - Module Verifier --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the function verifier interface, that can be used for some
+// sanity checking of input to the system, and for checking that transformations
+// haven't done something bad.
+//
+// Note that this does not provide full 'java style' security and verifications,
+// instead it just tries to ensure that code is well formed.
+//
+// To see what specifically is checked, look at the top of Verifier.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_VERIFIER_H
+#define LLVM_ANALYSIS_VERIFIER_H
+
+#include <string>
+
+namespace llvm {
+
+class FunctionPass;
+class Module;
+class Function;
+
+/// @brief An enumeration to specify the action to be taken if errors found.
+///
+/// This enumeration is used in the functions below to indicate what should
+/// happen if the verifier finds errors. Each of the functions that uses
+/// this enumeration as an argument provides a default value for it. The
+/// actions are listed below.
+enum VerifierFailureAction {
+ AbortProcessAction, ///< verifyModule will print to stderr and abort()
+ PrintMessageAction, ///< verifyModule will print to stderr and return true
+ ReturnStatusAction ///< verifyModule will just return true
+};
+
+/// @brief Create a verifier pass.
+///
+/// Check a module or function for validity. When the pass is used, the
+/// action indicated by the \p action argument will be used if errors are
+/// found.
+FunctionPass *createVerifierPass(
+ VerifierFailureAction action = AbortProcessAction ///< Action to take
+);
+
+/// @brief Check a module for errors.
+///
+/// If there are no errors, the function returns false. If an error is found,
+/// the action taken depends on the \p action parameter.
+/// This should only be used for debugging, because it plays games with
+/// PassManagers and stuff.
+
+bool verifyModule(
+ const Module &M, ///< The module to be verified
+ VerifierFailureAction action = AbortProcessAction, ///< Action to take
+ std::string *ErrorInfo = 0 ///< Information about failures.
+);
+
+// verifyFunction - Check a function for errors, useful for use when debugging a
+// pass.
+bool verifyFunction(
+ const Function &F, ///< The function to be verified
+ VerifierFailureAction action = AbortProcessAction ///< Action to take
+);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Argument.h b/include/llvm/Argument.h
new file mode 100644
index 0000000..c995043
--- /dev/null
+++ b/include/llvm/Argument.h
@@ -0,0 +1,72 @@
+//===-- llvm/Argument.h - Definition of the Argument class ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Argument class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ARGUMENT_H
+#define LLVM_ARGUMENT_H
+
+#include "llvm/Value.h"
+
+namespace llvm {
+
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+/// A class to represent an incoming formal argument to a Function. An argument
+/// is a very simple Value. It is essentially a named (optional) type. When used
+/// in the body of a function, it represents the value of the actual argument
+/// the function was called with.
+/// @brief LLVM Argument representation
+class Argument : public Value { // Defined in the Function.cpp file
+ Function *Parent;
+
+ Argument *Prev, *Next; // Next and Prev links for our intrusive linked list
+ void setNext(Argument *N) { Next = N; }
+ void setPrev(Argument *N) { Prev = N; }
+ friend class SymbolTableListTraits<Argument, Function>;
+ void setParent(Function *parent);
+
+public:
+ /// Argument ctor - If Function argument is specified, this argument is
+ /// inserted at the end of the argument list for the function.
+ ///
+ explicit Argument(const Type *Ty,
+ const std::string &Name = "",
+ Function *F = 0);
+
+ inline const Function *getParent() const { return Parent; }
+ inline Function *getParent() { return Parent; }
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const {
+ if (OS) print(*OS);
+ }
+
+ /// classof - Methods for support type inquiry through isa, cast, and
+ /// dyn_cast:
+ ///
+ static inline bool classof(const Argument *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == ArgumentVal;
+ }
+
+private:
+ // getNext/Prev - Return the next or previous argument in the list.
+ Argument *getNext() { return Next; }
+ const Argument *getNext() const { return Next; }
+ Argument *getPrev() { return Prev; }
+ const Argument *getPrev() const { return Prev; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Assembly/AsmAnnotationWriter.h b/include/llvm/Assembly/AsmAnnotationWriter.h
new file mode 100644
index 0000000..9ed285a
--- /dev/null
+++ b/include/llvm/Assembly/AsmAnnotationWriter.h
@@ -0,0 +1,53 @@
+//===-- AsmAnnotationWriter.h - Itf for annotation .ll files - --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Clients of the assembly writer can use this interface to add their own
+// special-purpose annotations to LLVM assembly language printouts. Note that
+// the assembly parser won't be able to parse these, in general, so
+// implementations are advised to print stuff as LLVM comments.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
+#define LLVM_ASSEMBLY_ASMANNOTATIONWRITER_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+class Function;
+class BasicBlock;
+class Instruction;
+
+struct AssemblyAnnotationWriter {
+
+ virtual ~AssemblyAnnotationWriter();
+
+ // emitFunctionAnnot - This may be implemented to emit a string right before
+ // the start of a function.
+ virtual void emitFunctionAnnot(const Function *F, std::ostream &OS) {}
+
+ // emitBasicBlockStartAnnot - This may be implemented to emit a string right
+ // after the basic block label, but before the first instruction in the block.
+ virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, std::ostream &OS){
+ }
+
+ // emitBasicBlockEndAnnot - This may be implemented to emit a string right
+ // after the basic block.
+ virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, std::ostream &OS){
+ }
+
+ // emitInstructionAnnot - This may be implemented to emit a string right
+ // before an instruction is emitted.
+ virtual void emitInstructionAnnot(const Instruction *I, std::ostream &OS) {}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Assembly/Parser.h b/include/llvm/Assembly/Parser.h
new file mode 100644
index 0000000..bc7995e
--- /dev/null
+++ b/include/llvm/Assembly/Parser.h
@@ -0,0 +1,97 @@
+//===-- llvm/Assembly/Parser.h - Parser for VM assembly files ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes are implemented by the lib/AsmParser library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_PARSER_H
+#define LLVM_ASSEMBLY_PARSER_H
+
+#include <string>
+
+namespace llvm {
+
+class Module;
+class ParseError;
+
+
+/// This function is the main interface to the LLVM Assembly Parse. It parses
+/// an ascii file that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a file
+Module *ParseAssemblyFile(
+ const std::string &Filename, ///< The name of the file to parse
+ ParseError* Error = 0 ///< If not null, an object to return errors in.
+);
+
+/// The function is a secondary interface to the LLVM Assembly Parse. It parses
+/// an ascii string that (presumably) contains LLVM Assembly code. It returns a
+/// Module (intermediate representation) with the corresponding features. Note
+/// that this does not verify that the generated Module is valid, so you should
+/// run the verifier after parsing the file to check that it is okay.
+/// @brief Parse LLVM Assembly from a string
+Module *ParseAssemblyString(
+ const char * AsmString, ///< The string containing assembly
+ Module * M, ///< A module to add the assembly too.
+ ParseError* Error = 0 ///< If not null, an object to return errors in.
+);
+
+//===------------------------------------------------------------------------===
+// Helper Classes
+//===------------------------------------------------------------------------===
+
+/// An instance of this class can be passed to ParseAssemblyFile or
+/// ParseAssemblyString functions in order to capture error information from
+/// the parser. It provides a standard way to print out the error message
+/// including the file name and line number where the error occurred.
+/// @brief An LLVM Assembly Parsing Error Object
+class ParseError {
+public:
+ ParseError() : Filename("unknown"), Message("none"), LineNo(0), ColumnNo(0) {}
+ ParseError(const ParseError &E);
+
+ // getMessage - Return the message passed in at construction time plus extra
+ // information extracted from the options used to parse with...
+ //
+ const std::string getMessage() const;
+
+ inline const std::string &getRawMessage() const { // Just the raw message...
+ return Message;
+ }
+
+ inline const std::string &getFilename() const {
+ return Filename;
+ }
+
+ void setError(const std::string &filename, const std::string &message,
+ int LineNo = -1, int ColNo = -1);
+
+ // getErrorLocation - Return the line and column number of the error in the
+ // input source file. The source filename can be derived from the
+ // ParserOptions in effect. If positional information is not applicable,
+ // these will return a value of -1.
+ //
+ inline const void getErrorLocation(int &Line, int &Column) const {
+ Line = LineNo; Column = ColumnNo;
+ }
+
+private :
+ std::string Filename;
+ std::string Message;
+ int LineNo, ColumnNo; // -1 if not relevant
+
+ ParseError &operator=(const ParseError &E); // objects by reference
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Assembly/PrintModulePass.h b/include/llvm/Assembly/PrintModulePass.h
new file mode 100644
index 0000000..0f65235
--- /dev/null
+++ b/include/llvm/Assembly/PrintModulePass.h
@@ -0,0 +1,81 @@
+//===- llvm/Assembly/PrintModulePass.h - Printing Pass ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines two passes to print out a module. The PrintModulePass pass
+// simply prints out the entire module when it is executed. The
+// PrintFunctionPass class is designed to be pipelined with other
+// FunctionPass's, and prints out the functions of the class as they are
+// processed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_PRINTMODULEPASS_H
+#define LLVM_ASSEMBLY_PRINTMODULEPASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+
+class PrintModulePass : public ModulePass {
+ OStream *Out; // ostream to print on
+ bool DeleteStream; // Delete the ostream in our dtor?
+public:
+ static char ID;
+ PrintModulePass() : ModulePass((intptr_t)&ID), Out(&cerr), DeleteStream(false) {}
+ PrintModulePass(OStream *o, bool DS = false)
+ : ModulePass((intptr_t)&ID), Out(o), DeleteStream(DS) {}
+
+ ~PrintModulePass() {
+ if (DeleteStream) delete Out;
+ }
+
+ bool runOnModule(Module &M) {
+ (*Out) << M << std::flush;
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+};
+
+class PrintFunctionPass : public FunctionPass {
+ std::string Banner; // String to print before each function
+ OStream *Out; // ostream to print on
+ bool DeleteStream; // Delete the ostream in our dtor?
+public:
+ static char ID;
+ PrintFunctionPass() : FunctionPass((intptr_t)&ID), Banner(""), Out(&cerr),
+ DeleteStream(false) {}
+ PrintFunctionPass(const std::string &B, OStream *o = &cout,
+ bool DS = false)
+ : FunctionPass((intptr_t)&ID), Banner(B), Out(o), DeleteStream(DS) {}
+
+ inline ~PrintFunctionPass() {
+ if (DeleteStream) delete Out;
+ }
+
+ // runOnFunction - This pass just prints a banner followed by the function as
+ // it's processed.
+ //
+ bool runOnFunction(Function &F) {
+ (*Out) << Banner << static_cast<Value&>(F);
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Assembly/Writer.h b/include/llvm/Assembly/Writer.h
new file mode 100644
index 0000000..45c9513
--- /dev/null
+++ b/include/llvm/Assembly/Writer.h
@@ -0,0 +1,45 @@
+//===-- llvm/Assembly/Writer.h - Printer for LLVM assembly files --*- C++ -*-=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This functionality is implemented by lib/VMCore/AsmWriter.cpp.
+// This library is used to print LLVM assembly language files to an iostream. It
+// can print LLVM code at a variety of granularities, including Modules,
+// BasicBlocks, and Instructions. This makes it useful for debugging.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ASSEMBLY_WRITER_H
+#define LLVM_ASSEMBLY_WRITER_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+class Type;
+class Module;
+class Value;
+
+// WriteTypeSymbolic - This attempts to write the specified type as a symbolic
+// type, iff there is an entry in the Module's symbol table for the specified
+// type or one of its component types. This is slower than a simple x << Type;
+//
+std::ostream &WriteTypeSymbolic(std::ostream &, const Type *, const Module *M);
+
+// WriteAsOperand - Write the name of the specified value out to the specified
+// ostream. This can be useful when you just want to print int %reg126, not the
+// whole instruction that generated it. If you specify a Module for context,
+// then even constants get pretty-printed; for example, the type of a null
+// pointer is printed symbolically.
+//
+std::ostream &WriteAsOperand(std::ostream &, const Value *, bool PrintTy = true,
+ const Module *Context = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h
new file mode 100644
index 0000000..f2722b0
--- /dev/null
+++ b/include/llvm/BasicBlock.h
@@ -0,0 +1,216 @@
+//===-- llvm/BasicBlock.h - Represent a basic block in the VM ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//
+// This file contains the declaration of the BasicBlock class.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BASICBLOCK_H
+#define LLVM_BASICBLOCK_H
+
+#include "llvm/Instruction.h"
+#include "llvm/SymbolTableListTraits.h"
+#include "llvm/ADT/ilist"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+class TerminatorInst;
+template <class Term, class BB> class SuccIterator; // Successor Iterator
+template <class Ptr, class USE_iterator> class PredIterator;
+
+template<> struct ilist_traits<Instruction>
+ : public SymbolTableListTraits<Instruction, BasicBlock> {
+ // createSentinel is used to create a node that marks the end of the list...
+ static Instruction *createSentinel();
+ static void destroySentinel(Instruction *I) { delete I; }
+ static iplist<Instruction> &getList(BasicBlock *BB);
+ static ValueSymbolTable *getSymTab(BasicBlock *ItemParent);
+ static int getListOffset();
+};
+
+/// This represents a single basic block in LLVM. A basic block is simply a
+/// container of instructions that execute sequentially. Basic blocks are Values
+/// because they are referenced by instructions such as branches and switch
+/// tables. The type of a BasicBlock is "Type::LabelTy" because the basic block
+/// represents a label to which a branch can jump.
+///
+/// A well formed basic block is formed of a list of non-terminating
+/// instructions followed by a single TerminatorInst instruction.
+/// TerminatorInst's may not occur in the middle of basic blocks, and must
+/// terminate the blocks. The BasicBlock class allows malformed basic blocks to
+/// occur because it may be useful in the intermediate stage of constructing or
+/// modifying a program. However, the verifier will ensure that basic blocks
+/// are "well formed".
+/// @brief LLVM Basic Block Representation
+class BasicBlock : public Value { // Basic blocks are data objects also
+public:
+ typedef iplist<Instruction> InstListType;
+private :
+ InstListType InstList;
+ BasicBlock *Prev, *Next; // Next and Prev links for our intrusive linked list
+ Function *Parent;
+
+ void setParent(Function *parent);
+ void setNext(BasicBlock *N) { Next = N; }
+ void setPrev(BasicBlock *N) { Prev = N; }
+ friend class SymbolTableListTraits<BasicBlock, Function>;
+
+ BasicBlock(const BasicBlock &); // Do not implement
+ void operator=(const BasicBlock &); // Do not implement
+
+public:
+ /// Instruction iterators...
+ typedef InstListType::iterator iterator;
+ typedef InstListType::const_iterator const_iterator;
+
+ /// BasicBlock ctor - If the function parameter is specified, the basic block
+ /// is automatically inserted at either the end of the function (if
+ /// InsertBefore is null), or before the specified basic block.
+ ///
+ explicit BasicBlock(const std::string &Name = "", Function *Parent = 0,
+ BasicBlock *InsertBefore = 0);
+ ~BasicBlock();
+
+ /// getParent - Return the enclosing method, or null if none
+ ///
+ const Function *getParent() const { return Parent; }
+ Function *getParent() { return Parent; }
+
+ /// use_back - Specialize the methods defined in Value, as we know that an
+ /// BasicBlock can only be used by Instructions (specifically PHI and terms).
+ Instruction *use_back() { return cast<Instruction>(*use_begin());}
+ const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
+
+ /// getTerminator() - If this is a well formed basic block, then this returns
+ /// a pointer to the terminator instruction. If it is not, then you get a
+ /// null pointer back.
+ ///
+ TerminatorInst *getTerminator();
+ const TerminatorInst *const getTerminator() const;
+
+ /// Returns a pointer to the first instructon in this block that is not a
+ /// PHINode instruction. When adding instruction to the beginning of the
+ /// basic block, they should be added before the returned value, not before
+ /// the first instruction, which might be PHI.
+ /// Returns 0 is there's no non-PHI instruction.
+ Instruction* getFirstNonPHI();
+
+ /// removeFromParent - This method unlinks 'this' from the containing
+ /// function, but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing function
+ /// and deletes it.
+ ///
+ void eraseFromParent();
+
+ /// moveBefore - Unlink this basic block from its current function and
+ /// insert it into the function that MovePos lives in, right before MovePos.
+ void moveBefore(BasicBlock *MovePos);
+
+ /// moveAfter - Unlink this basic block from its current function and
+ /// insert it into the function that MovePos lives in, right after MovePos.
+ void moveAfter(BasicBlock *MovePos);
+
+
+ /// getSinglePredecessor - If this basic block has a single predecessor block,
+ /// return the block, otherwise return a null pointer.
+ BasicBlock *getSinglePredecessor();
+ const BasicBlock *getSinglePredecessor() const {
+ return const_cast<BasicBlock*>(this)->getSinglePredecessor();
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// Instruction iterator methods
+ ///
+ inline iterator begin() { return InstList.begin(); }
+ inline const_iterator begin() const { return InstList.begin(); }
+ inline iterator end () { return InstList.end(); }
+ inline const_iterator end () const { return InstList.end(); }
+
+ inline size_t size() const { return InstList.size(); }
+ inline bool empty() const { return InstList.empty(); }
+ inline const Instruction &front() const { return InstList.front(); }
+ inline Instruction &front() { return InstList.front(); }
+ inline const Instruction &back() const { return InstList.back(); }
+ inline Instruction &back() { return InstList.back(); }
+
+ /// getInstList() - Return the underlying instruction list container. You
+ /// need to access it directly if you want to modify it currently.
+ ///
+ const InstListType &getInstList() const { return InstList; }
+ InstListType &getInstList() { return InstList; }
+
+ virtual void print(std::ostream &OS) const { print(OS, 0); }
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BasicBlock *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::BasicBlockVal;
+ }
+
+ /// dropAllReferences() - This function causes all the subinstructions to "let
+ /// go" of all references that they are maintaining. This allows one to
+ /// 'delete' a whole class at a time, even though there may be circular
+ /// references... first all references are dropped, and all use counts go to
+ /// zero. Then everything is delete'd for real. Note that no operations are
+ /// valid on an object that has "dropped all references", except operator
+ /// delete.
+ ///
+ void dropAllReferences();
+
+ /// removePredecessor - This method is used to notify a BasicBlock that the
+ /// specified Predecessor of the block is no longer able to reach it. This is
+ /// actually not used to update the Predecessor list, but is actually used to
+ /// update the PHI nodes that reside in the block. Note that this should be
+ /// called while the predecessor still refers to this block.
+ ///
+ void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs = false);
+
+ /// splitBasicBlock - This splits a basic block into two at the specified
+ /// instruction. Note that all instructions BEFORE the specified iterator
+ /// stay as part of the original basic block, an unconditional branch is added
+ /// to the original BB, and the rest of the instructions in the BB are moved
+ /// to the new BB, including the old terminator. The newly formed BasicBlock
+ /// is returned. This function invalidates the specified iterator.
+ ///
+ /// Note that this only works on well formed basic blocks (must have a
+ /// terminator), and 'I' must not be the end of instruction list (which would
+ /// cause a degenerate basic block to be formed, having a terminator inside of
+ /// the basic block).
+ ///
+ BasicBlock *splitBasicBlock(iterator I, const std::string &BBName = "");
+
+
+ static unsigned getInstListOffset() {
+ BasicBlock *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->InstList));
+ }
+
+private:
+ // getNext/Prev - Return the next or previous basic block in the list. Access
+ // these with Function::iterator.
+ BasicBlock *getNext() { return Next; }
+ const BasicBlock *getNext() const { return Next; }
+ BasicBlock *getPrev() { return Prev; }
+ const BasicBlock *getPrev() const { return Prev; }
+};
+
+inline int
+ilist_traits<Instruction>::getListOffset() {
+ return BasicBlock::getInstListOffset();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/Archive.h b/include/llvm/Bitcode/Archive.h
new file mode 100644
index 0000000..980bd07
--- /dev/null
+++ b/include/llvm/Bitcode/Archive.h
@@ -0,0 +1,555 @@
+//===-- llvm/Bitcode/Archive.h - LLVM Bitcode Archive -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the Archive and ArchiveMember classes that provide
+// manipulation of LLVM Archive files. The implementation is provided by the
+// lib/Bitcode/Archive library. This library is used to read and write
+// archive (*.a) files that contain LLVM bitcode files (or others).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_ARCHIVE_H
+#define LLVM_BITCODE_ARCHIVE_H
+
+#include "llvm/ADT/ilist"
+#include "llvm/System/Path.h"
+#include "llvm/System/MappedFile.h"
+#include <map>
+#include <set>
+#include <fstream>
+
+namespace llvm {
+
+// Forward declare classes
+class ModuleProvider; // From VMCore
+class Module; // From VMCore
+class Archive; // Declared below
+class ArchiveMemberHeader; // Internal implementation class
+
+/// This class is the main class manipulated by users of the Archive class. It
+/// holds information about one member of the Archive. It is also the element
+/// stored by the Archive's ilist, the Archive's main abstraction. Because of
+/// the special requirements of archive files, users are not permitted to
+/// construct ArchiveMember instances. You should obtain them from the methods
+/// of the Archive class instead.
+/// @brief This class represents a single archive member.
+class ArchiveMember {
+ /// @name Types
+ /// @{
+ public:
+ /// These flags are used internally by the archive member to specify various
+ /// characteristics of the member. The various "is" methods below provide
+ /// access to the flags. The flags are not user settable.
+ enum Flags {
+ CompressedFlag = 1, ///< Member is a normal compressed file
+ SVR4SymbolTableFlag = 2, ///< Member is a SVR4 symbol table
+ BSD4SymbolTableFlag = 4, ///< Member is a BSD4 symbol table
+ LLVMSymbolTableFlag = 8, ///< Member is an LLVM symbol table
+ BitcodeFlag = 16, ///< Member is bitcode
+ HasPathFlag = 64, ///< Member has a full or partial path
+ HasLongFilenameFlag = 128, ///< Member uses the long filename syntax
+ StringTableFlag = 256 ///< Member is an ar(1) format string table
+ };
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// @returns the parent Archive instance
+ /// @brief Get the archive associated with this member
+ Archive* getArchive() const { return parent; }
+
+ /// @returns the path to the Archive's file
+ /// @brief Get the path to the archive member
+ const sys::Path& getPath() const { return path; }
+
+ /// The "user" is the owner of the file per Unix security. This may not
+ /// have any applicability on non-Unix systems but is a required component
+ /// of the "ar" file format.
+ /// @brief Get the user associated with this archive member.
+ unsigned getUser() const { return info.getUser(); }
+
+ /// The "group" is the owning group of the file per Unix security. This
+ /// may not have any applicability on non-Unix systems but is a required
+ /// component of the "ar" file format.
+ /// @brief Get the group associated with this archive member.
+ unsigned getGroup() const { return info.getGroup(); }
+
+ /// The "mode" specifies the access permissions for the file per Unix
+ /// security. This may not have any applicabiity on non-Unix systems but is
+ /// a required component of the "ar" file format.
+ /// @brief Get the permission mode associated with this archive member.
+ unsigned getMode() const { return info.getMode(); }
+
+ /// This method returns the time at which the archive member was last
+ /// modified when it was not in the archive.
+ /// @brief Get the time of last modification of the archive member.
+ sys::TimeValue getModTime() const { return info.getTimestamp(); }
+
+ /// @returns the size of the archive member in bytes.
+ /// @brief Get the size of the archive member.
+ uint64_t getSize() const { return info.getSize(); }
+
+ /// This method returns the total size of the archive member as it
+ /// appears on disk. This includes the file content, the header, the
+ /// long file name if any, and the padding.
+ /// @brief Get total on-disk member size.
+ unsigned getMemberSize() const;
+
+ /// This method will return a pointer to the in-memory content of the
+ /// archive member, if it is available. If the data has not been loaded
+ /// into memory, the return value will be null.
+ /// @returns a pointer to the member's data.
+ /// @brief Get the data content of the archive member
+ const void* getData() const { return data; }
+
+ /// This method determines if the member is a regular compressed file.
+ /// @returns true iff the archive member is a compressed regular file.
+ /// @brief Determine if the member is a compressed regular file.
+ bool isCompressed() const { return flags&CompressedFlag; }
+
+ /// @returns true iff the member is a SVR4 (non-LLVM) symbol table
+ /// @brief Determine if this member is a SVR4 symbol table.
+ bool isSVR4SymbolTable() const { return flags&SVR4SymbolTableFlag; }
+
+ /// @returns true iff the member is a BSD4.4 (non-LLVM) symbol table
+ /// @brief Determine if this member is a BSD4.4 symbol table.
+ bool isBSD4SymbolTable() const { return flags&BSD4SymbolTableFlag; }
+
+ /// @returns true iff the archive member is the LLVM symbol table
+ /// @brief Determine if this member is the LLVM symbol table.
+ bool isLLVMSymbolTable() const { return flags&LLVMSymbolTableFlag; }
+
+ /// @returns true iff the archive member is the ar(1) string table
+ /// @brief Determine if this member is the ar(1) string table.
+ bool isStringTable() const { return flags&StringTableFlag; }
+
+ /// @returns true iff the archive member is a bitcode file.
+ /// @brief Determine if this member is a bitcode file.
+ bool isBitcode() const { return flags&BitcodeFlag; }
+
+ /// @returns true iff the file name contains a path (directory) component.
+ /// @brief Determine if the member has a path
+ bool hasPath() const { return flags&HasPathFlag; }
+
+ /// Long filenames are an artifact of the ar(1) file format which allows
+ /// up to sixteen characters in its header and doesn't allow a path
+ /// separator character (/). To avoid this, a "long format" member name is
+ /// allowed that doesn't have this restriction. This method determines if
+ /// that "long format" is used for this member.
+ /// @returns true iff the file name uses the long form
+ /// @brief Determin if the member has a long file name
+ bool hasLongFilename() const { return flags&HasLongFilenameFlag; }
+
+ /// This method returns the status info (like Unix stat(2)) for the archive
+ /// member. The status info provides the file's size, permissions, and
+ /// modification time. The contents of the Path::StatusInfo structure, other
+ /// than the size and modification time, may not have utility on non-Unix
+ /// systems.
+ /// @returns the status info for the archive member
+ /// @brief Obtain the status info for the archive member
+ const sys::FileStatus &getFileStatus() const { return info; }
+
+ /// This method causes the archive member to be replaced with the contents
+ /// of the file specified by \p File. The contents of \p this will be
+ /// updated to reflect the new data from \p File. The \p File must exist and
+ /// be readable on entry to this method.
+ /// @returns true if an error occurred, false otherwise
+ /// @brief Replace contents of archive member with a new file.
+ bool replaceWith(const sys::Path &aFile, std::string* ErrMsg);
+
+ /// @}
+ /// @name ilist methods - do not use
+ /// @{
+ public:
+ const ArchiveMember *getNext() const { return next; }
+ const ArchiveMember *getPrev() const { return prev; }
+ ArchiveMember *getNext() { return next; }
+ ArchiveMember *getPrev() { return prev; }
+ void setPrev(ArchiveMember* p) { prev = p; }
+ void setNext(ArchiveMember* n) { next = n; }
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ ArchiveMember* next; ///< Pointer to next archive member
+ ArchiveMember* prev; ///< Pointer to previous archive member
+ Archive* parent; ///< Pointer to parent archive
+ sys::PathWithStatus path; ///< Path of file containing the member
+ sys::FileStatus info; ///< Status info (size,mode,date)
+ unsigned flags; ///< Flags about the archive member
+ const void* data; ///< Data for the member
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// The default constructor is only used by the Archive's iplist when it
+ /// constructs the list's sentry node.
+ ArchiveMember();
+
+ private:
+ /// Used internally by the Archive class to construct an ArchiveMember.
+ /// The contents of the ArchiveMember are filled out by the Archive class.
+ ArchiveMember(Archive *PAR);
+
+ // So Archive can construct an ArchiveMember
+ friend class llvm::Archive;
+ /// @}
+};
+
+/// This class defines the interface to LLVM Archive files. The Archive class
+/// presents the archive file as an ilist of ArchiveMember objects. The members
+/// can be rearranged in any fashion either by directly editing the ilist or by
+/// using editing methods on the Archive class (recommended). The Archive
+/// class also provides several ways of accessing the archive file for various
+/// purposes such as editing and linking. Full symbol table support is provided
+/// for loading only those files that resolve symbols. Note that read
+/// performance of this library is _crucial_ for performance of JIT type
+/// applications and the linkers. Consequently, the implementation of the class
+/// is optimized for reading.
+class Archive {
+
+ /// @name Types
+ /// @{
+ public:
+ /// This is the ilist type over which users may iterate to examine
+ /// the contents of the archive
+ /// @brief The ilist type of ArchiveMembers that Archive contains.
+ typedef iplist<ArchiveMember> MembersList;
+
+ /// @brief Forward mutable iterator over ArchiveMember
+ typedef MembersList::iterator iterator;
+
+ /// @brief Forward immutable iterator over ArchiveMember
+ typedef MembersList::const_iterator const_iterator;
+
+ /// @brief Reverse mutable iterator over ArchiveMember
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ /// @brief Reverse immutable iterator over ArchiveMember
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+
+ /// @brief The in-memory version of the symbol table
+ typedef std::map<std::string,unsigned> SymTabType;
+
+ /// @}
+ /// @name ilist accessor methods
+ /// @{
+ public:
+ inline iterator begin() { return members.begin(); }
+ inline const_iterator begin() const { return members.begin(); }
+ inline iterator end () { return members.end(); }
+ inline const_iterator end () const { return members.end(); }
+
+ inline reverse_iterator rbegin() { return members.rbegin(); }
+ inline const_reverse_iterator rbegin() const { return members.rbegin(); }
+ inline reverse_iterator rend () { return members.rend(); }
+ inline const_reverse_iterator rend () const { return members.rend(); }
+
+ inline unsigned size() const { return members.size(); }
+ inline bool empty() const { return members.empty(); }
+ inline const ArchiveMember& front() const { return members.front(); }
+ inline ArchiveMember& front() { return members.front(); }
+ inline const ArchiveMember& back() const { return members.back(); }
+ inline ArchiveMember& back() { return members.back(); }
+
+ /// @}
+ /// @name ilist mutator methods
+ /// @{
+ public:
+ /// This method splices a \p src member from an archive (possibly \p this),
+ /// to a position just before the member given by \p dest in \p this. When
+ /// the archive is written, \p src will be written in its new location.
+ /// @brief Move a member to a new location
+ inline void splice(iterator dest, Archive& arch, iterator src)
+ { return members.splice(dest,arch.members,src); }
+
+ /// This method erases a \p target member from the archive. When the
+ /// archive is written, it will no longer contain \p target. The associated
+ /// ArchiveMember is deleted.
+ /// @brief Erase a member.
+ inline iterator erase(iterator target) { return members.erase(target); }
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Create an empty archive file and associate it with the \p Filename. This
+ /// method does not actually create the archive disk file. It creates an
+ /// empty Archive object. If the writeToDisk method is called, the archive
+ /// file \p Filename will be created at that point, with whatever content
+ /// the returned Archive object has at that time.
+ /// @returns An Archive* that represents the new archive file.
+ /// @brief Create an empty Archive.
+ static Archive* CreateEmpty(
+ const sys::Path& Filename ///< Name of the archive to (eventually) create.
+ );
+
+ /// Open an existing archive and load its contents in preparation for
+ /// editing. After this call, the member ilist is completely populated based
+ /// on the contents of the archive file. You should use this form of open if
+ /// you intend to modify the archive or traverse its contents (e.g. for
+ /// printing).
+ /// @brief Open and load an archive file
+ static Archive* OpenAndLoad(
+ const sys::Path& filePath, ///< The file path to open and load
+ std::string* ErrorMessage ///< An optional error string
+ );
+
+ /// This method opens an existing archive file from \p Filename and reads in
+ /// its symbol table without reading in any of the archive's members. This
+ /// reduces both I/O and cpu time in opening the archive if it is to be used
+ /// solely for symbol lookup (e.g. during linking). The \p Filename must
+ /// exist and be an archive file or an exception will be thrown. This form
+ /// of opening the archive is intended for read-only operations that need to
+ /// locate members via the symbol table for link editing. Since the archve
+ /// members are not read by this method, the archive will appear empty upon
+ /// return. If editing operations are performed on the archive, they will
+ /// completely replace the contents of the archive! It is recommended that
+ /// if this form of opening the archive is used that only the symbol table
+ /// lookup methods (getSymbolTable, findModuleDefiningSymbol, and
+ /// findModulesDefiningSymbols) be used.
+ /// @throws std::string if an error occurs opening the file
+ /// @returns an Archive* that represents the archive file.
+ /// @brief Open an existing archive and load its symbols.
+ static Archive* OpenAndLoadSymbols(
+ const sys::Path& Filename, ///< Name of the archive file to open
+ std::string* ErrorMessage=0 ///< An optional error string
+ );
+
+ /// This destructor cleans up the Archive object, releases all memory, and
+ /// closes files. It does nothing with the archive file on disk. If you
+ /// haven't used the writeToDisk method by the time the destructor is
+ /// called, all changes to the archive will be lost.
+ /// @throws std::string if an error occurs
+ /// @brief Destruct in-memory archive
+ ~Archive();
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// @returns the path to the archive file.
+ /// @brief Get the archive path.
+ const sys::Path& getPath() { return archPath; }
+
+ /// This method is provided so that editing methods can be invoked directly
+ /// on the Archive's iplist of ArchiveMember. However, it is recommended
+ /// that the usual STL style iterator interface be used instead.
+ /// @returns the iplist of ArchiveMember
+ /// @brief Get the iplist of the members
+ MembersList& getMembers() { return members; }
+
+ /// This method allows direct query of the Archive's symbol table. The
+ /// symbol table is a std::map of std::string (the symbol) to unsigned (the
+ /// file offset). Note that for efficiency reasons, the offset stored in
+ /// the symbol table is not the actual offset. It is the offset from the
+ /// beginning of the first "real" file member (after the symbol table). Use
+ /// the getFirstFileOffset() to obtain that offset and add this value to the
+ /// offset in the symbol table to obtain the real file offset. Note that
+ /// there is purposefully no interface provided by Archive to look up
+ /// members by their offset. Use the findModulesDefiningSymbols and
+ /// findModuleDefiningSymbol methods instead.
+ /// @returns the Archive's symbol table.
+ /// @brief Get the archive's symbol table
+ const SymTabType& getSymbolTable() { return symTab; }
+
+ /// This method returns the offset in the archive file to the first "real"
+ /// file member. Archive files, on disk, have a signature and might have a
+ /// symbol table that precedes the first actual file member. This method
+ /// allows you to determine what the size of those fields are.
+ /// @returns the offset to the first "real" file member in the archive.
+ /// @brief Get the offset to the first "real" file member in the archive.
+ unsigned getFirstFileOffset() { return firstFileOffset; }
+
+ /// This method will scan the archive for bitcode modules, interpret them
+ /// and return a vector of the instantiated modules in \p Modules. If an
+ /// error occurs, this method will return true. If \p ErrMessage is not null
+ /// and an error occurs, \p *ErrMessage will be set to a string explaining
+ /// the error that occurred.
+ /// @returns true if an error occurred
+ /// @brief Instantiate all the bitcode modules located in the archive
+ bool getAllModules(std::vector<Module*>& Modules, std::string* ErrMessage);
+
+ /// This accessor looks up the \p symbol in the archive's symbol table and
+ /// returns the associated module that defines that symbol. This method can
+ /// be called as many times as necessary. This is handy for linking the
+ /// archive into another module based on unresolved symbols. Note that the
+ /// ModuleProvider returned by this accessor should not be deleted by the
+ /// caller. It is managed internally by the Archive class. It is possible
+ /// that multiple calls to this accessor will return the same ModuleProvider
+ /// instance because the associated module defines multiple symbols.
+ /// @returns The ModuleProvider* found or null if the archive does not
+ /// contain a module that defines the \p symbol.
+ /// @brief Look up a module by symbol name.
+ ModuleProvider* findModuleDefiningSymbol(
+ const std::string& symbol, ///< Symbol to be sought
+ std::string* ErrMessage ///< Error message storage, if non-zero
+ );
+
+ /// This method is similar to findModuleDefiningSymbol but allows lookup of
+ /// more than one symbol at a time. If \p symbols contains a list of
+ /// undefined symbols in some module, then calling this method is like
+ /// making one complete pass through the archive to resolve symbols but is
+ /// more efficient than looking at the individual members. Note that on
+ /// exit, the symbols resolved by this method will be removed from \p
+ /// symbols to ensure they are not re-searched on a subsequent call. If
+ /// you need to retain the list of symbols, make a copy.
+ /// @brief Look up multiple symbols in the archive.
+ bool findModulesDefiningSymbols(
+ std::set<std::string>& symbols, ///< Symbols to be sought
+ std::set<ModuleProvider*>& modules, ///< The modules matching \p symbols
+ std::string* ErrMessage ///< Error msg storage, if non-zero
+ );
+
+ /// This method determines whether the archive is a properly formed llvm
+ /// bitcode archive. It first makes sure the symbol table has been loaded
+ /// and has a non-zero size. If it does, then it is an archive. If not,
+ /// then it tries to load all the bitcode modules of the archive. Finally,
+ /// it returns whether it was successfull.
+ /// @returns true if the archive is a proper llvm bitcode archive
+ /// @brief Determine whether the archive is a proper llvm bitcode archive.
+ bool isBitcodeArchive();
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// This method is the only way to get the archive written to disk. It
+ /// creates or overwrites the file specified when \p this was created
+ /// or opened. The arguments provide options for writing the archive. If
+ /// \p CreateSymbolTable is true, the archive is scanned for bitcode files
+ /// and a symbol table of the externally visible function and global
+ /// variable names is created. If \p TruncateNames is true, the names of the
+ /// archive members will have their path component stripped and the file
+ /// name will be truncated at 15 characters. If \p Compress is specified,
+ /// all archive members will be compressed before being written. If
+ /// \p PrintSymTab is true, the symbol table will be printed to std::cout.
+ /// @returns true if an error occurred, \p error set to error message
+ /// @returns false if the writing succeeded.
+ /// @brief Write (possibly modified) archive contents to disk
+ bool writeToDisk(
+ bool CreateSymbolTable=false, ///< Create Symbol table
+ bool TruncateNames=false, ///< Truncate the filename to 15 chars
+ bool Compress=false, ///< Compress files
+ std::string* ErrMessage=0 ///< If non-null, where error msg is set
+ );
+
+ /// This method adds a new file to the archive. The \p filename is examined
+ /// to determine just enough information to create an ArchiveMember object
+ /// which is then inserted into the Archive object's ilist at the location
+ /// given by \p where.
+ /// @returns true if an error occured, false otherwise
+ /// @brief Add a file to the archive.
+ bool addFileBefore(
+ const sys::Path& filename, ///< The file to be added
+ iterator where, ///< Insertion point
+ std::string* ErrMsg ///< Optional error message location
+ );
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ protected:
+ /// @brief Construct an Archive for \p filename and optionally map it
+ /// into memory.
+ Archive(const sys::Path& filename);
+
+ /// @param error Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Parse the symbol table at \p data.
+ bool parseSymbolTable(const void* data,unsigned len,std::string* error);
+
+ /// @returns A fully populated ArchiveMember or 0 if an error occurred.
+ /// @brief Parse the header of a member starting at \p At
+ ArchiveMember* parseMemberHeader(
+ const char*&At, ///< The pointer to the location we're parsing
+ const char*End, ///< The pointer to the end of the archive
+ std::string* error ///< Optional error message catcher
+ );
+
+ /// @param error Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Check that the archive signature is correct
+ bool checkSignature(std::string* ErrMessage);
+
+ /// @param error Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Load the entire archive.
+ bool loadArchive(std::string* ErrMessage);
+
+ /// @param error Set to address of a std::string to get error messages
+ /// @returns false on error
+ /// @brief Load just the symbol table.
+ bool loadSymbolTable(std::string* ErrMessage);
+
+ /// @brief Write the symbol table to an ofstream.
+ void writeSymbolTable(std::ofstream& ARFile);
+
+ /// Writes one ArchiveMember to an ofstream. If an error occurs, returns
+ /// false, otherwise true. If an error occurs and error is non-null then
+ /// it will be set to an error message.
+ /// @returns false Writing member succeeded
+ /// @returns true Writing member failed, \p error set to error message
+ bool writeMember(
+ const ArchiveMember& member, ///< The member to be written
+ std::ofstream& ARFile, ///< The file to write member onto
+ bool CreateSymbolTable, ///< Should symbol table be created?
+ bool TruncateNames, ///< Should names be truncated to 11 chars?
+ bool ShouldCompress, ///< Should the member be compressed?
+ std::string* ErrMessage ///< If non-null, place were error msg is set
+ );
+
+ /// @brief Fill in an ArchiveMemberHeader from ArchiveMember.
+ bool fillHeader(const ArchiveMember&mbr,
+ ArchiveMemberHeader& hdr,int sz, bool TruncateNames) const;
+
+ /// @brief Maps archive into memory
+ bool mapToMemory(std::string* ErrMsg);
+
+ /// @brief Frees all the members and unmaps the archive file.
+ void cleanUpMemory();
+
+ /// This type is used to keep track of bitcode modules loaded from the
+ /// symbol table. It maps the file offset to a pair that consists of the
+ /// associated ArchiveMember and the ModuleProvider.
+ /// @brief Module mapping type
+ typedef std::map<unsigned,std::pair<ModuleProvider*,ArchiveMember*> >
+ ModuleMap;
+
+
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ sys::Path archPath; ///< Path to the archive file we read/write
+ MembersList members; ///< The ilist of ArchiveMember
+ sys::MappedFile* mapfile; ///< Raw Archive contents mapped into memory
+ const char* base; ///< Base of the memory mapped file data
+ SymTabType symTab; ///< The symbol table
+ std::string strtab; ///< The string table for long file names
+ unsigned symTabSize; ///< Size in bytes of symbol table
+ unsigned firstFileOffset; ///< Offset to first normal file.
+ ModuleMap modules; ///< The modules loaded via symbol lookup.
+ ArchiveMember* foreignST; ///< This holds the foreign symbol table.
+ /// @}
+ /// @name Hidden
+ /// @{
+ private:
+ Archive(); ///< Do not implement
+ Archive(const Archive&); ///< Do not implement
+ Archive& operator=(const Archive&); ///< Do not implement
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitCodes.h b/include/llvm/Bitcode/BitCodes.h
new file mode 100644
index 0000000..59d57e7
--- /dev/null
+++ b/include/llvm/Bitcode/BitCodes.h
@@ -0,0 +1,179 @@
+//===- BitCodes.h - Enum values for the bitcode format ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header Bitcode enum values.
+//
+// The enum values defined in this file should be considered permanent. If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_BITCODES_H
+#define LLVM_BITCODE_BITCODES_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+namespace bitc {
+ enum StandardWidths {
+ BlockIDWidth = 8, // We use VBR-8 for block IDs.
+ CodeLenWidth = 4, // Codelen are VBR-4.
+ BlockSizeWidth = 32 // BlockSize up to 2^32 32-bit words = 32GB per block.
+ };
+
+ // The standard abbrev namespace always has a way to exit a block, enter a
+ // nested block, define abbrevs, and define an unabbreviated record.
+ enum FixedAbbrevIDs {
+ END_BLOCK = 0, // Must be zero to guarantee termination for broken bitcode.
+ ENTER_SUBBLOCK = 1,
+
+ /// DEFINE_ABBREV - Defines an abbrev for the current block. It consists
+ /// of a vbr5 for # operand infos. Each operand info is emitted with a
+ /// single bit to indicate if it is a literal encoding. If so, the value is
+ /// emitted with a vbr8. If not, the encoding is emitted as 3 bits followed
+ /// by the info value as a vbr5 if needed.
+ DEFINE_ABBREV = 2,
+
+ // UNABBREV_RECORDs are emitted with a vbr6 for the record code, followed by
+ // a vbr6 for the # operands, followed by vbr6's for each operand.
+ UNABBREV_RECORD = 3,
+
+ // This is not a code, this is a marker for the first abbrev assignment.
+ FIRST_APPLICATION_ABBREV = 4
+ };
+
+ /// StandardBlockIDs - All bitcode files can optionally include a BLOCKINFO
+ /// block, which contains metadata about other blocks in the file.
+ enum StandardBlockIDs {
+ /// BLOCKINFO_BLOCK is used to define metadata about blocks, for example,
+ /// standard abbrevs that should be available to all blocks of a specified
+ /// ID.
+ BLOCKINFO_BLOCK_ID = 0,
+
+ // Block IDs 1-7 are reserved for future expansion.
+ FIRST_APPLICATION_BLOCKID = 8
+ };
+
+ /// BlockInfoCodes - The blockinfo block contains metadata about user-defined
+ /// blocks.
+ enum BlockInfoCodes {
+ BLOCKINFO_CODE_SETBID = 1 // SETBID: [blockid#]
+ // DEFINE_ABBREV has magic semantics here, applying to the current SETBID'd
+ // block, instead of the BlockInfo block.
+ // BLOCKNAME: give string name to block, if desired.
+ };
+
+} // End bitc namespace
+
+/// BitCodeAbbrevOp - This describes one or more operands in an abbreviation.
+/// This is actually a union of two different things:
+/// 1. It could be a literal integer value ("the operand is always 17").
+/// 2. It could be an encoding specification ("this operand encoded like so").
+///
+class BitCodeAbbrevOp {
+ uint64_t Val; // A literal value or data for an encoding.
+ bool IsLiteral : 1; // Indicate whether this is a literal value or not.
+ unsigned Enc : 3; // The encoding to use.
+public:
+ enum Encoding {
+ Fixed = 1, // A fixed width field, Val specifies number of bits.
+ VBR = 2, // A VBR field where Val specifies the width of each chunk.
+ Array = 3, // A sequence of fields, next field species elt encoding.
+ Char6 = 4 // A 6-bit fixed field which maps to [a-zA-Z0-9._].
+ };
+
+ BitCodeAbbrevOp(uint64_t V) : Val(V), IsLiteral(true) {}
+ BitCodeAbbrevOp(Encoding E, uint64_t Data = 0)
+ : Val(Data), IsLiteral(false), Enc(E) {}
+
+ bool isLiteral() const { return IsLiteral; }
+ bool isEncoding() const { return !IsLiteral; }
+
+ // Accessors for literals.
+ uint64_t getLiteralValue() const { assert(isLiteral()); return Val; }
+
+ // Accessors for encoding info.
+ Encoding getEncoding() const { assert(isEncoding()); return (Encoding)Enc; }
+ uint64_t getEncodingData() const {
+ assert(isEncoding() && hasEncodingData());
+ return Val;
+ }
+
+ bool hasEncodingData() const { return hasEncodingData(getEncoding()); }
+ static bool hasEncodingData(Encoding E) {
+ switch (E) {
+ default: assert(0 && "Unknown encoding");
+ case Fixed:
+ case VBR:
+ return true;
+ case Array:
+ case Char6:
+ return false;
+ }
+ }
+
+ /// isChar6 - Return true if this character is legal in the Char6 encoding.
+ static bool isChar6(char C) {
+ if (C >= 'a' && C <= 'z') return true;
+ if (C >= 'A' && C <= 'Z') return true;
+ if (C >= '0' && C <= '9') return true;
+ if (C == '.' || C == '_') return true;
+ return false;
+ }
+ static unsigned EncodeChar6(char C) {
+ if (C >= 'a' && C <= 'z') return C-'a';
+ if (C >= 'A' && C <= 'Z') return C-'A'+26;
+ if (C >= '0' && C <= '9') return C-'0'+26+26;
+ if (C == '.') return 62;
+ if (C == '_') return 63;
+ assert(0 && "Not a value Char6 character!");
+ return 0;
+ }
+
+ static char DecodeChar6(unsigned V) {
+ assert((V & ~63) == 0 && "Not a Char6 encoded character!");
+ if (V < 26) return V+'a';
+ if (V < 26+26) return V-26+'A';
+ if (V < 26+26+10) return V-26-26+'0';
+ if (V == 62) return '.';
+ if (V == 63) return '_';
+ assert(0 && "Not a value Char6 character!");
+ return ' ';
+ }
+
+};
+
+/// BitCodeAbbrev - This class represents an abbreviation record. An
+/// abbreviation allows a complex record that has redundancy to be stored in a
+/// specialized format instead of the fully-general, fully-vbr, format.
+class BitCodeAbbrev {
+ SmallVector<BitCodeAbbrevOp, 8> OperandList;
+ unsigned char RefCount; // Number of things using this.
+ ~BitCodeAbbrev() {}
+public:
+ BitCodeAbbrev() : RefCount(1) {}
+
+ void addRef() { ++RefCount; }
+ void dropRef() { if (--RefCount == 0) delete this; }
+
+ unsigned getNumOperandInfos() const { return OperandList.size(); }
+ const BitCodeAbbrevOp &getOperandInfo(unsigned N) const {
+ return OperandList[N];
+ }
+
+ void Add(const BitCodeAbbrevOp &OpInfo) {
+ OperandList.push_back(OpInfo);
+ }
+};
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitstreamReader.h b/include/llvm/Bitcode/BitstreamReader.h
new file mode 100644
index 0000000..86a26c2
--- /dev/null
+++ b/include/llvm/Bitcode/BitstreamReader.h
@@ -0,0 +1,465 @@
+//===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitstreamReader class. This class can be used to
+// read an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITSTREAM_READER_H
+#define BITSTREAM_READER_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include <vector>
+
+namespace llvm {
+
+class BitstreamReader {
+ const unsigned char *NextChar;
+ const unsigned char *LastChar;
+
+ /// CurWord - This is the current data we have pulled from the stream but have
+ /// not returned to the client.
+ uint32_t CurWord;
+
+ /// BitsInCurWord - This is the number of bits in CurWord that are valid. This
+ /// is always from [0...31] inclusive.
+ unsigned BitsInCurWord;
+
+ // CurCodeSize - This is the declared size of code values used for the current
+ // block, in bits.
+ unsigned CurCodeSize;
+
+ /// CurAbbrevs - Abbrevs installed at in this block.
+ std::vector<BitCodeAbbrev*> CurAbbrevs;
+
+ struct Block {
+ unsigned PrevCodeSize;
+ std::vector<BitCodeAbbrev*> PrevAbbrevs;
+ explicit Block(unsigned PCS) : PrevCodeSize(PCS) {}
+ };
+
+ /// BlockScope - This tracks the codesize of parent blocks.
+ SmallVector<Block, 8> BlockScope;
+
+ /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+ /// These describe abbreviations that all blocks of the specified ID inherit.
+ struct BlockInfo {
+ unsigned BlockID;
+ std::vector<BitCodeAbbrev*> Abbrevs;
+ };
+ std::vector<BlockInfo> BlockInfoRecords;
+
+ /// FirstChar - This remembers the first byte of the stream.
+ const unsigned char *FirstChar;
+public:
+ BitstreamReader() {
+ NextChar = FirstChar = LastChar = 0;
+ CurWord = 0;
+ BitsInCurWord = 0;
+ CurCodeSize = 0;
+ }
+
+ BitstreamReader(const unsigned char *Start, const unsigned char *End) {
+ init(Start, End);
+ }
+
+ void init(const unsigned char *Start, const unsigned char *End) {
+ NextChar = FirstChar = Start;
+ LastChar = End;
+ assert(((End-Start) & 3) == 0 &&"Bitcode stream not a multiple of 4 bytes");
+ CurWord = 0;
+ BitsInCurWord = 0;
+ CurCodeSize = 2;
+ }
+
+ ~BitstreamReader() {
+ // Abbrevs could still exist if the stream was broken. If so, don't leak
+ // them.
+ for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+
+ for (unsigned S = 0, e = BlockScope.size(); S != e; ++S) {
+ std::vector<BitCodeAbbrev*> &Abbrevs = BlockScope[S].PrevAbbrevs;
+ for (unsigned i = 0, e = Abbrevs.size(); i != e; ++i)
+ Abbrevs[i]->dropRef();
+ }
+
+ // Free the BlockInfoRecords.
+ while (!BlockInfoRecords.empty()) {
+ BlockInfo &Info = BlockInfoRecords.back();
+ // Free blockinfo abbrev info.
+ for (unsigned i = 0, e = Info.Abbrevs.size(); i != e; ++i)
+ Info.Abbrevs[i]->dropRef();
+ BlockInfoRecords.pop_back();
+ }
+ }
+
+ bool AtEndOfStream() const {
+ return NextChar == LastChar && BitsInCurWord == 0;
+ }
+
+ /// GetCurrentBitNo - Return the bit # of the bit we are reading.
+ uint64_t GetCurrentBitNo() const {
+ return (NextChar-FirstChar)*8 + ((32-BitsInCurWord) & 31);
+ }
+
+ /// JumpToBit - Reset the stream to the specified bit number.
+ void JumpToBit(uint64_t BitNo) {
+ uintptr_t ByteNo = uintptr_t(BitNo/8) & ~3;
+ uintptr_t WordBitNo = uintptr_t(BitNo) & 31;
+ assert(ByteNo < (uintptr_t)(LastChar-FirstChar) && "Invalid location");
+
+ // Move the cursor to the right word.
+ NextChar = FirstChar+ByteNo;
+ BitsInCurWord = 0;
+
+ // Skip over any bits that are already consumed.
+ if (WordBitNo) {
+ NextChar -= 4;
+ Read(WordBitNo);
+ }
+ }
+
+ /// GetAbbrevIDWidth - Return the number of bits used to encode an abbrev #.
+ unsigned GetAbbrevIDWidth() const { return CurCodeSize; }
+
+ uint32_t Read(unsigned NumBits) {
+ // If the field is fully contained by CurWord, return it quickly.
+ if (BitsInCurWord >= NumBits) {
+ uint32_t R = CurWord & ((1U << NumBits)-1);
+ CurWord >>= NumBits;
+ BitsInCurWord -= NumBits;
+ return R;
+ }
+
+ // If we run out of data, stop at the end of the stream.
+ if (LastChar == NextChar) {
+ CurWord = 0;
+ BitsInCurWord = 0;
+ return 0;
+ }
+
+ unsigned R = CurWord;
+
+ // Read the next word from the stream.
+ CurWord = (NextChar[0] << 0) | (NextChar[1] << 8) |
+ (NextChar[2] << 16) | (NextChar[3] << 24);
+ NextChar += 4;
+
+ // Extract NumBits-BitsInCurWord from what we just read.
+ unsigned BitsLeft = NumBits-BitsInCurWord;
+
+ // Be careful here, BitsLeft is in the range [1..32] inclusive.
+ R |= (CurWord & (~0U >> (32-BitsLeft))) << BitsInCurWord;
+
+ // BitsLeft bits have just been used up from CurWord.
+ if (BitsLeft != 32)
+ CurWord >>= BitsLeft;
+ else
+ CurWord = 0;
+ BitsInCurWord = 32-BitsLeft;
+ return R;
+ }
+
+ uint64_t Read64(unsigned NumBits) {
+ if (NumBits <= 32) return Read(NumBits);
+
+ uint64_t V = Read(32);
+ return V | (uint64_t)Read(NumBits-32) << 32;
+ }
+
+ uint32_t ReadVBR(unsigned NumBits) {
+ uint32_t Piece = Read(NumBits);
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Piece;
+
+ uint32_t Result = 0;
+ unsigned NextBit = 0;
+ while (1) {
+ Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Result;
+
+ NextBit += NumBits-1;
+ Piece = Read(NumBits);
+ }
+ }
+
+ uint64_t ReadVBR64(unsigned NumBits) {
+ uint64_t Piece = Read(NumBits);
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Piece;
+
+ uint64_t Result = 0;
+ unsigned NextBit = 0;
+ while (1) {
+ Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit;
+
+ if ((Piece & (1U << (NumBits-1))) == 0)
+ return Result;
+
+ NextBit += NumBits-1;
+ Piece = Read(NumBits);
+ }
+ }
+
+ void SkipToWord() {
+ BitsInCurWord = 0;
+ CurWord = 0;
+ }
+
+
+ unsigned ReadCode() {
+ return Read(CurCodeSize);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Block Manipulation
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// getBlockInfo - If there is block info for the specified ID, return it,
+ /// otherwise return null.
+ BlockInfo *getBlockInfo(unsigned BlockID) {
+ // Common case, the most recent entry matches BlockID.
+ if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+ return &BlockInfoRecords.back();
+
+ for (unsigned i = 0, e = BlockInfoRecords.size(); i != e; ++i)
+ if (BlockInfoRecords[i].BlockID == BlockID)
+ return &BlockInfoRecords[i];
+ return 0;
+ }
+public:
+
+
+ // Block header:
+ // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+
+ /// ReadSubBlockID - Having read the ENTER_SUBBLOCK code, read the BlockID for
+ /// the block.
+ unsigned ReadSubBlockID() {
+ return ReadVBR(bitc::BlockIDWidth);
+ }
+
+ /// SkipBlock - Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip
+ /// over the body of this block. If the block record is malformed, return
+ /// true.
+ bool SkipBlock() {
+ // Read and ignore the codelen value. Since we are skipping this block, we
+ // don't care what code widths are used inside of it.
+ ReadVBR(bitc::CodeLenWidth);
+ SkipToWord();
+ unsigned NumWords = Read(bitc::BlockSizeWidth);
+
+ // Check that the block wasn't partially defined, and that the offset isn't
+ // bogus.
+ if (AtEndOfStream() || NextChar+NumWords*4 > LastChar)
+ return true;
+
+ NextChar += NumWords*4;
+ return false;
+ }
+
+ /// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, read and enter
+ /// the block, returning the BlockID of the block we just entered.
+ bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = 0) {
+ // Save the current block's state on BlockScope.
+ BlockScope.push_back(Block(CurCodeSize));
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+ // Add the abbrevs specific to this block to the CurAbbrevs list.
+ if (BlockInfo *Info = getBlockInfo(BlockID)) {
+ for (unsigned i = 0, e = Info->Abbrevs.size(); i != e; ++i) {
+ CurAbbrevs.push_back(Info->Abbrevs[i]);
+ CurAbbrevs.back()->addRef();
+ }
+ }
+
+ // Get the codesize of this block.
+ CurCodeSize = ReadVBR(bitc::CodeLenWidth);
+ SkipToWord();
+ unsigned NumWords = Read(bitc::BlockSizeWidth);
+ if (NumWordsP) *NumWordsP = NumWords;
+
+ // Validate that this block is sane.
+ if (CurCodeSize == 0 || AtEndOfStream() || NextChar+NumWords*4 > LastChar)
+ return true;
+
+ return false;
+ }
+
+ bool ReadBlockEnd() {
+ if (BlockScope.empty()) return true;
+
+ // Block tail:
+ // [END_BLOCK, <align4bytes>]
+ SkipToWord();
+ CurCodeSize = BlockScope.back().PrevCodeSize;
+
+ // Delete abbrevs from popped scope.
+ for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+ BlockScope.pop_back();
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Record Processing
+ //===--------------------------------------------------------------------===//
+
+private:
+ void ReadAbbreviatedField(const BitCodeAbbrevOp &Op,
+ SmallVectorImpl<uint64_t> &Vals) {
+ if (Op.isLiteral()) {
+ // If the abbrev specifies the literal value to use, use it.
+ Vals.push_back(Op.getLiteralValue());
+ } else {
+ // Decode the value as we are commanded.
+ switch (Op.getEncoding()) {
+ default: assert(0 && "Unknown encoding!");
+ case BitCodeAbbrevOp::Fixed:
+ Vals.push_back(Read((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::VBR:
+ Vals.push_back(ReadVBR64((unsigned)Op.getEncodingData()));
+ break;
+ case BitCodeAbbrevOp::Char6:
+ Vals.push_back(BitCodeAbbrevOp::DecodeChar6(Read(6)));
+ break;
+ }
+ }
+ }
+public:
+ unsigned ReadRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals) {
+ if (AbbrevID == bitc::UNABBREV_RECORD) {
+ unsigned Code = ReadVBR(6);
+ unsigned NumElts = ReadVBR(6);
+ for (unsigned i = 0; i != NumElts; ++i)
+ Vals.push_back(ReadVBR64(6));
+ return Code;
+ }
+
+ unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV;
+ assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+ BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
+
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
+ ReadAbbreviatedField(Op, Vals);
+ } else {
+ // Array case. Read the number of elements as a vbr6.
+ unsigned NumElts = ReadVBR(6);
+
+ // Get the element encoding.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // Read all the elements.
+ for (; NumElts; --NumElts)
+ ReadAbbreviatedField(EltEnc, Vals);
+ }
+ }
+
+ unsigned Code = (unsigned)Vals[0];
+ Vals.erase(Vals.begin());
+ return Code;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Abbrev Processing
+ //===--------------------------------------------------------------------===//
+
+ void ReadAbbrevRecord() {
+ BitCodeAbbrev *Abbv = new BitCodeAbbrev();
+ unsigned NumOpInfo = ReadVBR(5);
+ for (unsigned i = 0; i != NumOpInfo; ++i) {
+ bool IsLiteral = Read(1);
+ if (IsLiteral) {
+ Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));
+ continue;
+ }
+
+ BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);
+ if (BitCodeAbbrevOp::hasEncodingData(E))
+ Abbv->Add(BitCodeAbbrevOp(E, ReadVBR64(5)));
+ else
+ Abbv->Add(BitCodeAbbrevOp(E));
+ }
+ CurAbbrevs.push_back(Abbv);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // BlockInfo Block Reading
+ //===--------------------------------------------------------------------===//
+
+private:
+ BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+ if (BlockInfo *BI = getBlockInfo(BlockID))
+ return *BI;
+
+ // Otherwise, add a new record.
+ BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.back().BlockID = BlockID;
+ return BlockInfoRecords.back();
+ }
+
+public:
+
+ bool ReadBlockInfoBlock() {
+ if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true;
+
+ SmallVector<uint64_t, 64> Record;
+ BlockInfo *CurBlockInfo = 0;
+
+ // Read all the records for this module.
+ while (1) {
+ unsigned Code = ReadCode();
+ if (Code == bitc::END_BLOCK)
+ return ReadBlockEnd();
+ if (Code == bitc::ENTER_SUBBLOCK) {
+ ReadSubBlockID();
+ if (SkipBlock()) return true;
+ continue;
+ }
+
+ // Read abbrev records, associate them with CurBID.
+ if (Code == bitc::DEFINE_ABBREV) {
+ if (!CurBlockInfo) return true;
+ ReadAbbrevRecord();
+
+ // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the
+ // appropriate BlockInfo.
+ BitCodeAbbrev *Abbv = CurAbbrevs.back();
+ CurAbbrevs.pop_back();
+ CurBlockInfo->Abbrevs.push_back(Abbv);
+ continue;
+ }
+
+ // Read a record.
+ Record.clear();
+ switch (ReadRecord(Code, Record)) {
+ default: break; // Default behavior, ignore unknown content.
+ case bitc::BLOCKINFO_CODE_SETBID:
+ if (Record.size() < 1) return true;
+ CurBlockInfo = &getOrCreateBlockInfo((unsigned)Record[0]);
+ break;
+ }
+ }
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/BitstreamWriter.h b/include/llvm/Bitcode/BitstreamWriter.h
new file mode 100644
index 0000000..64598ed
--- /dev/null
+++ b/include/llvm/Bitcode/BitstreamWriter.h
@@ -0,0 +1,398 @@
+//===- BitstreamWriter.h - Low-level bitstream writer interface -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the BitstreamWriter class. This class can be used to
+// write an arbitrary bitstream, regardless of its contents.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef BITSTREAM_WRITER_H
+#define BITSTREAM_WRITER_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include <vector>
+
+namespace llvm {
+
+class BitstreamWriter {
+ std::vector<unsigned char> &Out;
+
+ /// CurBit - Always between 0 and 31 inclusive, specifies the next bit to use.
+ unsigned CurBit;
+
+ /// CurValue - The current value. Only bits < CurBit are valid.
+ uint32_t CurValue;
+
+ /// CurCodeSize - This is the declared size of code values used for the
+ /// current block, in bits.
+ unsigned CurCodeSize;
+
+ /// BlockInfoCurBID - When emitting a BLOCKINFO_BLOCK, this is the currently
+ /// selected BLOCK ID.
+ unsigned BlockInfoCurBID;
+
+ /// CurAbbrevs - Abbrevs installed at in this block.
+ std::vector<BitCodeAbbrev*> CurAbbrevs;
+
+ struct Block {
+ unsigned PrevCodeSize;
+ unsigned StartSizeWord;
+ std::vector<BitCodeAbbrev*> PrevAbbrevs;
+ Block(unsigned PCS, unsigned SSW) : PrevCodeSize(PCS), StartSizeWord(SSW) {}
+ };
+
+ /// BlockScope - This tracks the current blocks that we have entered.
+ std::vector<Block> BlockScope;
+
+ /// BlockInfo - This contains information emitted to BLOCKINFO_BLOCK blocks.
+ /// These describe abbreviations that all blocks of the specified ID inherit.
+ struct BlockInfo {
+ unsigned BlockID;
+ std::vector<BitCodeAbbrev*> Abbrevs;
+ };
+ std::vector<BlockInfo> BlockInfoRecords;
+
+public:
+ BitstreamWriter(std::vector<unsigned char> &O)
+ : Out(O), CurBit(0), CurValue(0), CurCodeSize(2) {}
+
+ ~BitstreamWriter() {
+ assert(CurBit == 0 && "Unflused data remaining");
+ assert(BlockScope.empty() && CurAbbrevs.empty() && "Block imbalance");
+
+ // Free the BlockInfoRecords.
+ while (!BlockInfoRecords.empty()) {
+ BlockInfo &Info = BlockInfoRecords.back();
+ // Free blockinfo abbrev info.
+ for (unsigned i = 0, e = Info.Abbrevs.size(); i != e; ++i)
+ Info.Abbrevs[i]->dropRef();
+ BlockInfoRecords.pop_back();
+ }
+ }
+ //===--------------------------------------------------------------------===//
+ // Basic Primitives for emitting bits to the stream.
+ //===--------------------------------------------------------------------===//
+
+ void Emit(uint32_t Val, unsigned NumBits) {
+ assert(NumBits <= 32 && "Invalid value size!");
+ assert((Val & ~(~0U >> (32-NumBits))) == 0 && "High bits set!");
+ CurValue |= Val << CurBit;
+ if (CurBit + NumBits < 32) {
+ CurBit += NumBits;
+ return;
+ }
+
+ // Add the current word.
+ unsigned V = CurValue;
+ Out.push_back((unsigned char)(V >> 0));
+ Out.push_back((unsigned char)(V >> 8));
+ Out.push_back((unsigned char)(V >> 16));
+ Out.push_back((unsigned char)(V >> 24));
+
+ if (CurBit)
+ CurValue = Val >> (32-CurBit);
+ else
+ CurValue = 0;
+ CurBit = (CurBit+NumBits) & 31;
+ }
+
+ void Emit64(uint64_t Val, unsigned NumBits) {
+ if (NumBits <= 32)
+ Emit((uint32_t)Val, NumBits);
+ else {
+ Emit((uint32_t)Val, 32);
+ Emit((uint32_t)(Val >> 32), NumBits-32);
+ }
+ }
+
+ void FlushToWord() {
+ if (CurBit) {
+ unsigned V = CurValue;
+ Out.push_back((unsigned char)(V >> 0));
+ Out.push_back((unsigned char)(V >> 8));
+ Out.push_back((unsigned char)(V >> 16));
+ Out.push_back((unsigned char)(V >> 24));
+ CurBit = 0;
+ CurValue = 0;
+ }
+ }
+
+ void EmitVBR(uint32_t Val, unsigned NumBits) {
+ uint32_t Threshold = 1U << (NumBits-1);
+
+ // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+ while (Val >= Threshold) {
+ Emit((Val & ((1 << (NumBits-1))-1)) | (1 << (NumBits-1)), NumBits);
+ Val >>= NumBits-1;
+ }
+
+ Emit(Val, NumBits);
+ }
+
+ void EmitVBR64(uint64_t Val, unsigned NumBits) {
+ if ((uint32_t)Val == Val)
+ return EmitVBR((uint32_t)Val, NumBits);
+
+ uint64_t Threshold = 1U << (NumBits-1);
+
+ // Emit the bits with VBR encoding, NumBits-1 bits at a time.
+ while (Val >= Threshold) {
+ Emit(((uint32_t)Val & ((1 << (NumBits-1))-1)) |
+ (1 << (NumBits-1)), NumBits);
+ Val >>= NumBits-1;
+ }
+
+ Emit((uint32_t)Val, NumBits);
+ }
+
+ /// EmitCode - Emit the specified code.
+ void EmitCode(unsigned Val) {
+ Emit(Val, CurCodeSize);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Block Manipulation
+ //===--------------------------------------------------------------------===//
+
+ /// getBlockInfo - If there is block info for the specified ID, return it,
+ /// otherwise return null.
+ BlockInfo *getBlockInfo(unsigned BlockID) {
+ // Common case, the most recent entry matches BlockID.
+ if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID)
+ return &BlockInfoRecords.back();
+
+ for (unsigned i = 0, e = BlockInfoRecords.size(); i != e; ++i)
+ if (BlockInfoRecords[i].BlockID == BlockID)
+ return &BlockInfoRecords[i];
+ return 0;
+ }
+
+ void EnterSubblock(unsigned BlockID, unsigned CodeLen) {
+ // Block header:
+ // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen]
+ EmitCode(bitc::ENTER_SUBBLOCK);
+ EmitVBR(BlockID, bitc::BlockIDWidth);
+ EmitVBR(CodeLen, bitc::CodeLenWidth);
+ FlushToWord();
+
+ unsigned BlockSizeWordLoc = Out.size();
+ unsigned OldCodeSize = CurCodeSize;
+
+ // Emit a placeholder, which will be replaced when the block is popped.
+ Emit(0, bitc::BlockSizeWidth);
+
+ CurCodeSize = CodeLen;
+
+ // Push the outer block's abbrev set onto the stack, start out with an
+ // empty abbrev set.
+ BlockScope.push_back(Block(OldCodeSize, BlockSizeWordLoc/4));
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+
+ // If there is a blockinfo for this BlockID, add all the predefined abbrevs
+ // to the abbrev list.
+ if (BlockInfo *Info = getBlockInfo(BlockID)) {
+ for (unsigned i = 0, e = Info->Abbrevs.size(); i != e; ++i) {
+ CurAbbrevs.push_back(Info->Abbrevs[i]);
+ Info->Abbrevs[i]->addRef();
+ }
+ }
+ }
+
+ void ExitBlock() {
+ assert(!BlockScope.empty() && "Block scope imbalance!");
+
+ // Delete all abbrevs.
+ for (unsigned i = 0, e = CurAbbrevs.size(); i != e; ++i)
+ CurAbbrevs[i]->dropRef();
+
+ const Block &B = BlockScope.back();
+
+ // Block tail:
+ // [END_BLOCK, <align4bytes>]
+ EmitCode(bitc::END_BLOCK);
+ FlushToWord();
+
+ // Compute the size of the block, in words, not counting the size field.
+ unsigned SizeInWords = Out.size()/4-B.StartSizeWord - 1;
+ unsigned ByteNo = B.StartSizeWord*4;
+
+ // Update the block size field in the header of this sub-block.
+ Out[ByteNo++] = (unsigned char)(SizeInWords >> 0);
+ Out[ByteNo++] = (unsigned char)(SizeInWords >> 8);
+ Out[ByteNo++] = (unsigned char)(SizeInWords >> 16);
+ Out[ByteNo++] = (unsigned char)(SizeInWords >> 24);
+
+ // Restore the inner block's code size and abbrev table.
+ CurCodeSize = B.PrevCodeSize;
+ BlockScope.back().PrevAbbrevs.swap(CurAbbrevs);
+ BlockScope.pop_back();
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Record Emission
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// EmitAbbreviatedField - Emit a single scalar field value with the specified
+ /// encoding.
+ template<typename uintty>
+ void EmitAbbreviatedField(const BitCodeAbbrevOp &Op, uintty V) {
+ if (Op.isLiteral()) {
+ // If the abbrev specifies the literal value to use, don't emit
+ // anything.
+ assert(V == Op.getLiteralValue() &&
+ "Invalid abbrev for record!");
+ return;
+ }
+
+ // Encode the value as we are commanded.
+ switch (Op.getEncoding()) {
+ default: assert(0 && "Unknown encoding!");
+ case BitCodeAbbrevOp::Fixed:
+ Emit((unsigned)V, (unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::VBR:
+ EmitVBR64(V, (unsigned)Op.getEncodingData());
+ break;
+ case BitCodeAbbrevOp::Char6:
+ Emit(BitCodeAbbrevOp::EncodeChar6((char)V), 6);
+ break;
+ }
+ }
+public:
+
+ /// EmitRecord - Emit the specified record to the stream, using an abbrev if
+ /// we have one to compress the output.
+ template<typename uintty>
+ void EmitRecord(unsigned Code, SmallVectorImpl<uintty> &Vals,
+ unsigned Abbrev = 0) {
+ if (Abbrev) {
+ unsigned AbbrevNo = Abbrev-bitc::FIRST_APPLICATION_ABBREV;
+ assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+ BitCodeAbbrev *Abbv = CurAbbrevs[AbbrevNo];
+
+ EmitCode(Abbrev);
+
+ // Insert the code into Vals to treat it uniformly.
+ Vals.insert(Vals.begin(), Code);
+
+ unsigned RecordIdx = 0;
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ if (Op.isLiteral() || Op.getEncoding() != BitCodeAbbrevOp::Array) {
+ assert(RecordIdx < Vals.size() && "Invalid abbrev/record");
+ EmitAbbreviatedField(Op, Vals[RecordIdx]);
+ ++RecordIdx;
+ } else {
+ // Array case.
+ assert(i+2 == e && "array op not second to last?");
+ const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i);
+
+ // Emit a vbr6 to indicate the number of elements present.
+ EmitVBR(Vals.size()-RecordIdx, 6);
+
+ // Emit each field.
+ for (; RecordIdx != Vals.size(); ++RecordIdx)
+ EmitAbbreviatedField(EltEnc, Vals[RecordIdx]);
+ }
+ }
+ assert(RecordIdx == Vals.size() && "Not all record operands emitted!");
+ } else {
+ // If we don't have an abbrev to use, emit this in its fully unabbreviated
+ // form.
+ EmitCode(bitc::UNABBREV_RECORD);
+ EmitVBR(Code, 6);
+ EmitVBR(Vals.size(), 6);
+ for (unsigned i = 0, e = Vals.size(); i != e; ++i)
+ EmitVBR64(Vals[i], 6);
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Abbrev Emission
+ //===--------------------------------------------------------------------===//
+
+private:
+ // Emit the abbreviation as a DEFINE_ABBREV record.
+ void EncodeAbbrev(BitCodeAbbrev *Abbv) {
+ EmitCode(bitc::DEFINE_ABBREV);
+ EmitVBR(Abbv->getNumOperandInfos(), 5);
+ for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) {
+ const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i);
+ Emit(Op.isLiteral(), 1);
+ if (Op.isLiteral()) {
+ EmitVBR64(Op.getLiteralValue(), 8);
+ } else {
+ Emit(Op.getEncoding(), 3);
+ if (Op.hasEncodingData())
+ EmitVBR64(Op.getEncodingData(), 5);
+ }
+ }
+ }
+public:
+
+ /// EmitAbbrev - This emits an abbreviation to the stream. Note that this
+ /// method takes ownership of the specified abbrev.
+ unsigned EmitAbbrev(BitCodeAbbrev *Abbv) {
+ // Emit the abbreviation as a record.
+ EncodeAbbrev(Abbv);
+ CurAbbrevs.push_back(Abbv);
+ return CurAbbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // BlockInfo Block Emission
+ //===--------------------------------------------------------------------===//
+
+ /// EnterBlockInfoBlock - Start emitting the BLOCKINFO_BLOCK.
+ void EnterBlockInfoBlock(unsigned CodeWidth) {
+ EnterSubblock(bitc::BLOCKINFO_BLOCK_ID, CodeWidth);
+ BlockInfoCurBID = -1U;
+ }
+private:
+ /// SwitchToBlockID - If we aren't already talking about the specified block
+ /// ID, emit a BLOCKINFO_CODE_SETBID record.
+ void SwitchToBlockID(unsigned BlockID) {
+ if (BlockInfoCurBID == BlockID) return;
+ SmallVector<unsigned, 2> V;
+ V.push_back(BlockID);
+ EmitRecord(bitc::BLOCKINFO_CODE_SETBID, V);
+ BlockInfoCurBID = BlockID;
+ }
+
+ BlockInfo &getOrCreateBlockInfo(unsigned BlockID) {
+ if (BlockInfo *BI = getBlockInfo(BlockID))
+ return *BI;
+
+ // Otherwise, add a new record.
+ BlockInfoRecords.push_back(BlockInfo());
+ BlockInfoRecords.back().BlockID = BlockID;
+ return BlockInfoRecords.back();
+ }
+
+public:
+
+ /// EmitBlockInfoAbbrev - Emit a DEFINE_ABBREV record for the specified
+ /// BlockID.
+ unsigned EmitBlockInfoAbbrev(unsigned BlockID, BitCodeAbbrev *Abbv) {
+ SwitchToBlockID(BlockID);
+ EncodeAbbrev(Abbv);
+
+ // Add the abbrev to the specified block record.
+ BlockInfo &Info = getOrCreateBlockInfo(BlockID);
+ Info.Abbrevs.push_back(Abbv);
+
+ return Info.Abbrevs.size()-1+bitc::FIRST_APPLICATION_ABBREV;
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h
new file mode 100644
index 0000000..24e6729
--- /dev/null
+++ b/include/llvm/Bitcode/LLVMBitCodes.h
@@ -0,0 +1,195 @@
+//===- LLVMBitCodes.h - Enum values for the LLVM bitcode format -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines Bitcode enum values for LLVM IR bitcode files.
+//
+// The enum values defined in this file should be considered permanent. If
+// new features are added, they should have values added at the end of the
+// respective lists.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_LLVMBITCODES_H
+#define LLVM_BITCODE_LLVMBITCODES_H
+
+#include "llvm/Bitcode/BitCodes.h"
+
+namespace llvm {
+namespace bitc {
+ // The only top-level block type defined is for a module.
+ enum BlockIDs {
+ // Blocks
+ MODULE_BLOCK_ID = FIRST_APPLICATION_BLOCKID,
+
+ // Module sub-block id's.
+ PARAMATTR_BLOCK_ID,
+ TYPE_BLOCK_ID,
+ CONSTANTS_BLOCK_ID,
+ FUNCTION_BLOCK_ID,
+ TYPE_SYMTAB_BLOCK_ID,
+ VALUE_SYMTAB_BLOCK_ID
+ };
+
+
+ /// MODULE blocks have a number of optional fields and subblocks.
+ enum ModuleCodes {
+ MODULE_CODE_VERSION = 1, // VERSION: [version#]
+ MODULE_CODE_TRIPLE = 2, // TRIPLE: [strchr x N]
+ MODULE_CODE_DATALAYOUT = 3, // DATALAYOUT: [strchr x N]
+ MODULE_CODE_ASM = 4, // ASM: [strchr x N]
+ MODULE_CODE_SECTIONNAME = 5, // SECTIONNAME: [strchr x N]
+ MODULE_CODE_DEPLIB = 6, // DEPLIB: [strchr x N]
+
+ // GLOBALVAR: [type, isconst, initid,
+ // linkage, alignment, section, visibility, threadlocal]
+ MODULE_CODE_GLOBALVAR = 7,
+
+ // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment,
+ // section, visibility]
+ MODULE_CODE_FUNCTION = 8,
+
+ // ALIAS: [alias type, aliasee val#, linkage]
+ MODULE_CODE_ALIAS = 9,
+
+ /// MODULE_CODE_PURGEVALS: [numvals]
+ MODULE_CODE_PURGEVALS = 10
+ };
+
+ /// PARAMATTR blocks have code for defining a parameter attribute set.
+ enum ParamAttrCodes {
+ PARAMATTR_CODE_ENTRY = 1 // ENTRY: [paramidx0, attr0, paramidx1, attr1...]
+ };
+
+ /// TYPE blocks have codes for each type primitive they use.
+ enum TypeCodes {
+ TYPE_CODE_NUMENTRY = 1, // NUMENTRY: [numentries]
+
+ // Type Codes
+ TYPE_CODE_VOID = 2, // VOID
+ TYPE_CODE_FLOAT = 3, // FLOAT
+ TYPE_CODE_DOUBLE = 4, // DOUBLE
+ TYPE_CODE_LABEL = 5, // LABEL
+ TYPE_CODE_OPAQUE = 6, // OPAQUE
+ TYPE_CODE_INTEGER = 7, // INTEGER: [width]
+ TYPE_CODE_POINTER = 8, // POINTER: [pointee type]
+ TYPE_CODE_FUNCTION = 9, // FUNCTION: [vararg, retty, paramty x N]
+ TYPE_CODE_STRUCT = 10, // STRUCT: [ispacked, eltty x N]
+ TYPE_CODE_ARRAY = 11, // ARRAY: [numelts, eltty]
+ TYPE_CODE_VECTOR = 12 // VECTOR: [numelts, eltty]
+ // Any other type code is assumed to be an unknown type.
+ };
+
+ // The type symbol table only has one code (TST_ENTRY_CODE).
+ enum TypeSymtabCodes {
+ TST_CODE_ENTRY = 1 // TST_ENTRY: [typeid, namechar x N]
+ };
+
+ // The value symbol table only has one code (VST_ENTRY_CODE).
+ enum ValueSymtabCodes {
+ VST_CODE_ENTRY = 1, // VST_ENTRY: [valid, namechar x N]
+ VST_CODE_BBENTRY = 2 // VST_BBENTRY: [bbid, namechar x N]
+ };
+
+ // The constants block (CONSTANTS_BLOCK_ID) describes emission for each
+ // constant and maintains an implicit current type value.
+ enum ConstantsCodes {
+ CST_CODE_SETTYPE = 1, // SETTYPE: [typeid]
+ CST_CODE_NULL = 2, // NULL
+ CST_CODE_UNDEF = 3, // UNDEF
+ CST_CODE_INTEGER = 4, // INTEGER: [intval]
+ CST_CODE_WIDE_INTEGER = 5, // WIDE_INTEGER: [n x intval]
+ CST_CODE_FLOAT = 6, // FLOAT: [fpval]
+ CST_CODE_AGGREGATE = 7, // AGGREGATE: [n x value number]
+ CST_CODE_STRING = 8, // STRING: [values]
+ CST_CODE_CSTRING = 9, // CSTRING: [values]
+ CST_CODE_CE_BINOP = 10, // CE_BINOP: [opcode, opval, opval]
+ CST_CODE_CE_CAST = 11, // CE_CAST: [opcode, opty, opval]
+ CST_CODE_CE_GEP = 12, // CE_GEP: [n x operands]
+ CST_CODE_CE_SELECT = 13, // CE_SELECT: [opval, opval, opval]
+ CST_CODE_CE_EXTRACTELT = 14, // CE_EXTRACTELT: [opty, opval, opval]
+ CST_CODE_CE_INSERTELT = 15, // CE_INSERTELT: [opval, opval, opval]
+ CST_CODE_CE_SHUFFLEVEC = 16, // CE_SHUFFLEVEC: [opval, opval, opval]
+ CST_CODE_CE_CMP = 17, // CE_CMP: [opty, opval, opval, pred]
+ CST_CODE_INLINEASM = 18 // INLINEASM: [sideeffect,asmstr,conststr]
+ };
+
+ /// CastOpcodes - These are values used in the bitcode files to encode which
+ /// cast a CST_CODE_CE_CAST or a XXX refers to. The values of these enums
+ /// have no fixed relation to the LLVM IR enum values. Changing these will
+ /// break compatibility with old files.
+ enum CastOpcodes {
+ CAST_TRUNC = 0,
+ CAST_ZEXT = 1,
+ CAST_SEXT = 2,
+ CAST_FPTOUI = 3,
+ CAST_FPTOSI = 4,
+ CAST_UITOFP = 5,
+ CAST_SITOFP = 6,
+ CAST_FPTRUNC = 7,
+ CAST_FPEXT = 8,
+ CAST_PTRTOINT = 9,
+ CAST_INTTOPTR = 10,
+ CAST_BITCAST = 11
+ };
+
+ /// BinaryOpcodes - These are values used in the bitcode files to encode which
+ /// binop a CST_CODE_CE_BINOP or a XXX refers to. The values of these enums
+ /// have no fixed relation to the LLVM IR enum values. Changing these will
+ /// break compatibility with old files.
+ enum BinaryOpcodes {
+ BINOP_ADD = 0,
+ BINOP_SUB = 1,
+ BINOP_MUL = 2,
+ BINOP_UDIV = 3,
+ BINOP_SDIV = 4, // overloaded for FP
+ BINOP_UREM = 5,
+ BINOP_SREM = 6, // overloaded for FP
+ BINOP_SHL = 7,
+ BINOP_LSHR = 8,
+ BINOP_ASHR = 9,
+ BINOP_AND = 10,
+ BINOP_OR = 11,
+ BINOP_XOR = 12
+ };
+
+
+ // The function body block (FUNCTION_BLOCK_ID) describes function bodies. It
+ // can contain a constant block (CONSTANTS_BLOCK_ID).
+ enum FunctionCodes {
+ FUNC_CODE_DECLAREBLOCKS = 1, // DECLAREBLOCKS: [n]
+
+ FUNC_CODE_INST_BINOP = 2, // BINOP: [opcode, ty, opval, opval]
+ FUNC_CODE_INST_CAST = 3, // CAST: [opcode, ty, opty, opval]
+ FUNC_CODE_INST_GEP = 4, // GEP: [n x operands]
+ FUNC_CODE_INST_SELECT = 5, // SELECT: [ty, opval, opval, opval]
+ FUNC_CODE_INST_EXTRACTELT = 6, // EXTRACTELT: [opty, opval, opval]
+ FUNC_CODE_INST_INSERTELT = 7, // INSERTELT: [ty, opval, opval, opval]
+ FUNC_CODE_INST_SHUFFLEVEC = 8, // SHUFFLEVEC: [ty, opval, opval, opval]
+ FUNC_CODE_INST_CMP = 9, // CMP: [opty, opval, opval, pred]
+
+ FUNC_CODE_INST_RET = 10, // RET: [opty,opval<both optional>]
+ FUNC_CODE_INST_BR = 11, // BR: [bb#, bb#, cond] or [bb#]
+ FUNC_CODE_INST_SWITCH = 12, // SWITCH: [opty, opval, n, n x ops]
+ FUNC_CODE_INST_INVOKE = 13, // INVOKE: [attr, fnty, op0,op1, ...]
+ FUNC_CODE_INST_UNWIND = 14, // UNWIND
+ FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE
+
+ FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...]
+ FUNC_CODE_INST_MALLOC = 17, // MALLOC: [instty, op, align]
+ FUNC_CODE_INST_FREE = 18, // FREE: [opty, op]
+ FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align]
+ FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol]
+ FUNC_CODE_INST_STORE = 21, // STORE: [ptrty,val,ptr, align, vol]
+ FUNC_CODE_INST_CALL = 22, // CALL: [attr, fnty, fnid, args...]
+ FUNC_CODE_INST_VAARG = 23 // VAARG: [valistty, valist, instty]
+ };
+} // End bitc namespace
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Bitcode/ReaderWriter.h b/include/llvm/Bitcode/ReaderWriter.h
new file mode 100644
index 0000000..7898385
--- /dev/null
+++ b/include/llvm/Bitcode/ReaderWriter.h
@@ -0,0 +1,48 @@
+//===-- llvm/Bitcode/ReaderWriter.h - Bitcode reader/writers ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines interfaces to read and write LLVM bitcode files/streams.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_BITCODE_H
+#define LLVM_BITCODE_H
+
+#include <iosfwd>
+#include <string>
+
+namespace llvm {
+ class Module;
+ class ModuleProvider;
+ class MemoryBuffer;
+ class ModulePass;
+
+ /// getBitcodeModuleProvider - Read the header of the specified bitcode buffer
+ /// and prepare for lazy deserialization of function bodies. If successful,
+ /// this takes ownership of 'buffer' and returns a non-null pointer. On
+ /// error, this returns null, *does not* take ownership of Buffer, and fills
+ /// in *ErrMsg with an error description if ErrMsg is non-null.
+ ModuleProvider *getBitcodeModuleProvider(MemoryBuffer *Buffer,
+ std::string *ErrMsg = 0);
+
+ /// ParseBitcodeFile - Read the specified bitcode file, returning the module.
+ /// If an error occurs, this returns null and fills in *ErrMsg if it is
+ /// non-null. This method *never* takes ownership of Buffer.
+ Module *ParseBitcodeFile(MemoryBuffer *Buffer, std::string *ErrMsg = 0);
+
+ /// WriteBitcodeToFile - Write the specified module to the specified output
+ /// stream.
+ void WriteBitcodeToFile(const Module *M, std::ostream &Out);
+
+ /// CreateBitcodeWriterPass - Create and return a pass that writes the module
+ /// to the specified ostream.
+ ModulePass *CreateBitcodeWriterPass(std::ostream &Str);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CallGraphSCCPass.h b/include/llvm/CallGraphSCCPass.h
new file mode 100644
index 0000000..2bc163d
--- /dev/null
+++ b/include/llvm/CallGraphSCCPass.h
@@ -0,0 +1,72 @@
+//===- CallGraphSCCPass.h - Pass that operates BU on call graph -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CallGraphSCCPass class, which is used for passes which
+// are implemented as bottom-up traversals on the call graph. Because there may
+// be cycles in the call graph, passes of this type operate on the call-graph in
+// SCC order: that is, they process function bottom-up, except for recursive
+// functions, which they process all at once.
+//
+// These passes are inherently interprocedural, and are required to keep the
+// call graph up-to-date if they do anything which could modify it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CALL_GRAPH_SCC_PASS_H
+#define LLVM_CALL_GRAPH_SCC_PASS_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class CallGraphNode;
+class CallGraph;
+class PMStack;
+
+struct CallGraphSCCPass : public Pass {
+
+ explicit CallGraphSCCPass(intptr_t pid) : Pass(pid) {}
+
+ /// doInitialization - This method is called before the SCC's of the program
+ /// has been processed, allowing the pass to do initialization as necessary.
+ virtual bool doInitialization(CallGraph &CG) {
+ return false;
+ }
+
+ /// runOnSCC - This method should be implemented by the subclass to perform
+ /// whatever action is necessary for the specified SCC. Note that
+ /// non-recursive (or only self-recursive) functions will have an SCC size of
+ /// 1, where recursive portions of the call graph will have SCC size > 1.
+ ///
+ virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC) = 0;
+
+ /// doFinalization - This method is called after the SCC's of the program has
+ /// been processed, allowing the pass to do final cleanup as necessary.
+ virtual bool doFinalization(CallGraph &CG) {
+ return false;
+ }
+
+ /// Assign pass manager to manager this pass
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType PMT = PMT_CallGraphPassManager);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_CallGraphPassManager;
+ }
+
+ /// getAnalysisUsage - For this class, we declare that we require and preserve
+ /// the call graph. If the derived class implements this method, it should
+ /// always explicitly call the implementation here.
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CallingConv.h b/include/llvm/CallingConv.h
new file mode 100644
index 0000000..a10bc39
--- /dev/null
+++ b/include/llvm/CallingConv.h
@@ -0,0 +1,66 @@
+//===-- llvm/CallingConv.h - LLVM Calling Conventions -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines LLVM's set of calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CALLINGCONV_H
+#define LLVM_CALLINGCONV_H
+
+namespace llvm {
+
+/// CallingConv Namespace - This namespace contains an enum with a value for
+/// the well-known calling conventions.
+///
+namespace CallingConv {
+ /// A set of enums which specify the assigned numeric values for known llvm
+ /// calling conventions.
+ /// @brief LLVM Calling Convention Representation
+ enum ID {
+ /// C - The default llvm calling convention, compatible with C. This
+ /// convention is the only calling convention that supports varargs calls.
+ /// As with typical C calling conventions, the callee/caller have to
+ /// tolerate certain amounts of prototype mismatch.
+ C = 0,
+
+ // Generic LLVM calling conventions. None of these calling conventions
+ // support varargs calls, and all assume that the caller and callee
+ // prototype exactly match.
+
+ /// Fast - This calling convention attempts to make calls as fast as
+ /// possible /// (e.g. by passing things in registers).
+ Fast = 8,
+
+ // Cold - This calling convention attempts to make code in the caller as
+ // efficient as possible under the assumption that the call is not commonly
+ // executed. As such, these calls often preserve all registers so that the
+ // call does not break any live ranges in the caller side.
+ Cold = 9,
+
+ // Target - This is the start of the target-specific calling conventions,
+ // e.g. fastcall and thiscall on X86.
+ FirstTargetCC = 64,
+
+ /// X86_StdCall - stdcall is the calling conventions mostly used by the
+ /// Win32 API. It is basically the same as the C convention with the
+ /// difference in that the callee is responsible for popping the arguments
+ /// from the stack.
+ X86_StdCall = 64,
+
+ /// X86_FastCall - 'fast' analog of X86_StdCall. Passes first two arguments
+ /// in ECX:EDX registers, others - via stack. Callee is responsible for
+ /// stack cleaning.
+ X86_FastCall = 65
+ };
+} // End CallingConv namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
new file mode 100644
index 0000000..954b9bc
--- /dev/null
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -0,0 +1,316 @@
+//===-- llvm/CodeGen/AsmPrinter.h - AsmPrinter Framework --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the base class for target specific
+// asm writers. This class primarily handles common functionality used by
+// all asm writers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ASMPRINTER_H
+#define LLVM_CODEGEN_ASMPRINTER_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/DataTypes.h"
+#include <set>
+
+namespace llvm {
+ class Constant;
+ class ConstantArray;
+ class GlobalVariable;
+ class GlobalAlias;
+ class MachineConstantPoolEntry;
+ class MachineConstantPoolValue;
+ class Mangler;
+ class TargetAsmInfo;
+
+
+ /// AsmPrinter - This class is intended to be used as a driving class for all
+ /// asm writers.
+ class AsmPrinter : public MachineFunctionPass {
+ static char ID;
+
+ /// FunctionNumber - This provides a unique ID for each function emitted in
+ /// this translation unit. It is autoincremented by SetupMachineFunction,
+ /// and can be accessed with getFunctionNumber() and
+ /// IncrementFunctionNumber().
+ ///
+ unsigned FunctionNumber;
+
+ protected:
+ // Necessary for external weak linkage support
+ std::set<const GlobalValue*> ExtWeakSymbols;
+
+ public:
+ /// Output stream on which we're printing assembly code.
+ ///
+ std::ostream &O;
+
+ /// Target machine description.
+ ///
+ TargetMachine &TM;
+
+ /// Target Asm Printer information.
+ ///
+ const TargetAsmInfo *TAI;
+
+ /// Name-mangler for global names.
+ ///
+ Mangler *Mang;
+
+ /// Cache of mangled name for current function. This is recalculated at the
+ /// beginning of each call to runOnMachineFunction().
+ ///
+ std::string CurrentFnName;
+
+ /// CurrentSection - The current section we are emitting to. This is
+ /// controlled and used by the SwitchSection method.
+ std::string CurrentSection;
+
+ protected:
+ AsmPrinter(std::ostream &o, TargetMachine &TM, const TargetAsmInfo *T);
+
+ public:
+ /// SwitchToTextSection - Switch to the specified section of the executable
+ /// if we are not already in it! If GV is non-null and if the global has an
+ /// explicitly requested section, we switch to the section indicated for the
+ /// global instead of NewSection.
+ ///
+ /// If the new section is an empty string, this method forgets what the
+ /// current section is, but does not emit a .section directive.
+ ///
+ /// This method is used when about to emit executable code.
+ ///
+ void SwitchToTextSection(const char *NewSection, const GlobalValue *GV = NULL);
+
+ /// SwitchToDataSection - Switch to the specified section of the executable
+ /// if we are not already in it! If GV is non-null and if the global has an
+ /// explicitly requested section, we switch to the section indicated for the
+ /// global instead of NewSection.
+ ///
+ /// If the new section is an empty string, this method forgets what the
+ /// current section is, but does not emit a .section directive.
+ ///
+ /// This method is used when about to emit data. For most assemblers, this
+ /// is the same as the SwitchToTextSection method, but not all assemblers
+ /// are the same.
+ ///
+ void SwitchToDataSection(const char *NewSection, const GlobalValue *GV = NULL);
+
+ /// getGlobalLinkName - Returns the asm/link name of of the specified
+ /// global variable. Should be overridden by each target asm printer to
+ /// generate the appropriate value.
+ virtual const std::string getGlobalLinkName(const GlobalVariable *GV) const;
+
+ /// EmitExternalGlobal - Emit the external reference to a global variable.
+ /// Should be overridden if an indirect reference should be used.
+ virtual void EmitExternalGlobal(const GlobalVariable *GV);
+
+ protected:
+ /// doInitialization - Set up the AsmPrinter when we are working on a new
+ /// module. If your pass overrides this, it must make sure to explicitly
+ /// call this implementation.
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Shut down the asmprinter. If you override this in your
+ /// pass, you must make sure to call it explicitly.
+ bool doFinalization(Module &M);
+
+ /// PrintSpecial - Print information related to the specified machine instr
+ /// that is independent of the operand, and may be independent of the instr
+ /// itself. This can be useful for portably encoding the comment character
+ /// or other bits of target-specific knowledge into the asmstrings. The
+ /// syntax used is ${:comment}. Targets can override this to add support
+ /// for their own strange codes.
+ virtual void PrintSpecial(const MachineInstr *MI, const char *Code);
+
+ /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant. Targets should
+ /// override this to format as appropriate. This method can return true if
+ /// the operand is erroneous.
+ virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode);
+
+ /// PrintAsmMemoryOperand - Print the specified operand of MI, an INLINEASM
+ /// instruction, using the specified assembler variant as an address.
+ /// Targets should override this to format as appropriate. This method can
+ /// return true if the operand is erroneous.
+ virtual bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode);
+
+ /// getSectionForFunction - Return the section that we should emit the
+ /// specified function body into. This defaults to 'TextSection'. This
+ /// should most likely be overridden by the target to put linkonce/weak
+ /// functions into special sections.
+ virtual std::string getSectionForFunction(const Function &F) const;
+
+ /// SetupMachineFunction - This should be called when a new MachineFunction
+ /// is being processed from runOnMachineFunction.
+ void SetupMachineFunction(MachineFunction &MF);
+
+ /// getFunctionNumber - Return a unique ID for the current function.
+ ///
+ unsigned getFunctionNumber() const { return FunctionNumber; }
+
+ /// IncrementFunctionNumber - Increase Function Number. AsmPrinters should
+ /// not normally call this, as the counter is automatically bumped by
+ /// SetupMachineFunction.
+ void IncrementFunctionNumber() { FunctionNumber++; }
+
+ /// EmitConstantPool - Print to the current output stream assembly
+ /// representations of the constants in the constant pool MCP. This is
+ /// used to print out constants which have been "spilled to memory" by
+ /// the code generator.
+ ///
+ void EmitConstantPool(MachineConstantPool *MCP);
+
+ /// EmitJumpTableInfo - Print assembly representations of the jump tables
+ /// used by the current function to the current output stream.
+ ///
+ void EmitJumpTableInfo(MachineJumpTableInfo *MJTI, MachineFunction &MF);
+
+ /// EmitSpecialLLVMGlobal - Check to see if the specified global is a
+ /// special global used by LLVM. If so, emit it and return true, otherwise
+ /// do nothing and return false.
+ bool EmitSpecialLLVMGlobal(const GlobalVariable *GV);
+
+ public:
+ //===------------------------------------------------------------------===//
+ /// LEB 128 number encoding.
+
+ /// PrintULEB128 - Print a series of hexidecimal values(separated by commas)
+ /// representing an unsigned leb128 value.
+ void PrintULEB128(unsigned Value) const;
+
+ /// SizeULEB128 - Compute the number of bytes required for an unsigned
+ /// leb128 value.
+ static unsigned SizeULEB128(unsigned Value);
+
+ /// PrintSLEB128 - Print a series of hexidecimal values(separated by commas)
+ /// representing a signed leb128 value.
+ void PrintSLEB128(int Value) const;
+
+ /// SizeSLEB128 - Compute the number of bytes required for a signed leb128
+ /// value.
+ static unsigned SizeSLEB128(int Value);
+
+ //===------------------------------------------------------------------===//
+ // Emission and print routines
+ //
+
+ /// PrintHex - Print a value as a hexidecimal value.
+ ///
+ void PrintHex(int Value) const;
+
+ /// EOL - Print a newline character to asm stream. If a comment is present
+ /// then it will be printed first. Comments should not contain '\n'.
+ void EOL() const;
+ void EOL(const std::string &Comment) const;
+
+ /// EmitULEB128Bytes - Emit an assembler byte data directive to compose an
+ /// unsigned leb128 value.
+ void EmitULEB128Bytes(unsigned Value) const;
+
+ /// EmitSLEB128Bytes - print an assembler byte data directive to compose a
+ /// signed leb128 value.
+ void EmitSLEB128Bytes(int Value) const;
+
+ /// EmitInt8 - Emit a byte directive and value.
+ ///
+ void EmitInt8(int Value) const;
+
+ /// EmitInt16 - Emit a short directive and value.
+ ///
+ void EmitInt16(int Value) const;
+
+ /// EmitInt32 - Emit a long directive and value.
+ ///
+ void EmitInt32(int Value) const;
+
+ /// EmitInt64 - Emit a long long directive and value.
+ ///
+ void EmitInt64(uint64_t Value) const;
+
+ /// EmitString - Emit a string with quotes and a null terminator.
+ /// Special characters are emitted properly.
+ /// \literal (Eg. '\t') \endliteral
+ void EmitString(const std::string &String) const;
+
+ //===------------------------------------------------------------------===//
+
+ /// EmitAlignment - Emit an alignment directive to the specified power of
+ /// two boundary. For example, if you pass in 3 here, you will get an 8
+ /// byte alignment. If a global value is specified, and if that global has
+ /// an explicit alignment requested, it will unconditionally override the
+ /// alignment request. However, if ForcedAlignBits is specified, this value
+ /// has final say: the ultimate alignment will be the max of ForcedAlignBits
+ /// and the alignment computed with NumBits and the global.
+ ///
+ /// The algorithm is:
+ /// Align = NumBits;
+ /// if (GV && GV->hasalignment) Align = GV->getalignment();
+ /// Align = std::max(Align, ForcedAlignBits);
+ ///
+ void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0,
+ unsigned ForcedAlignBits = 0) const;
+
+ protected:
+ /// EmitZeros - Emit a block of zeros.
+ ///
+ void EmitZeros(uint64_t NumZeros) const;
+
+ /// EmitString - Emit a zero-byte-terminated string constant.
+ ///
+ virtual void EmitString(const ConstantArray *CVA) const;
+
+ /// EmitConstantValueOnly - Print out the specified constant, without a
+ /// storage class. Only constants of first-class type are allowed here.
+ void EmitConstantValueOnly(const Constant *CV);
+
+ /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
+ ///
+ void EmitGlobalConstant(const Constant* CV);
+
+ virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
+
+ /// printInlineAsm - This method formats and prints the specified machine
+ /// instruction that is an inline asm.
+ void printInlineAsm(const MachineInstr *MI) const;
+
+ /// printLabel - This method prints a local label used by debug and
+ /// exception handling tables.
+ void printLabel(const MachineInstr *MI) const;
+
+ /// printBasicBlockLabel - This method prints the label for the specified
+ /// MachineBasicBlock
+ virtual void printBasicBlockLabel(const MachineBasicBlock *MBB,
+ bool printColon = false,
+ bool printComment = true) const;
+
+ /// printSetLabel - This method prints a set label for the specified
+ /// MachineBasicBlock
+ void printSetLabel(unsigned uid, const MachineBasicBlock *MBB) const;
+ void printSetLabel(unsigned uid, unsigned uid2,
+ const MachineBasicBlock *MBB) const;
+
+ /// printDataDirective - This method prints the asm directive for the
+ /// specified type.
+ void printDataDirective(const Type *type);
+
+ private:
+ void EmitLLVMUsedList(Constant *List);
+ void EmitXXStructorList(Constant *List);
+ void EmitConstantPool(unsigned Alignment, const char *Section,
+ std::vector<std::pair<MachineConstantPoolEntry,unsigned> > &CP);
+
+ };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/CallingConvLower.h b/include/llvm/CodeGen/CallingConvLower.h
new file mode 100644
index 0000000..959d052
--- /dev/null
+++ b/include/llvm/CodeGen/CallingConvLower.h
@@ -0,0 +1,202 @@
+//===-- llvm/CallingConvLower.h - Calling Conventions -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the CCState and CCValAssign classes, used for lowering
+// and implementing calling conventions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_CALLINGCONVLOWER_H
+#define LLVM_CODEGEN_CALLINGCONVLOWER_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/ValueTypes.h"
+
+namespace llvm {
+ class MRegisterInfo;
+ class TargetMachine;
+ class CCState;
+ class SDNode;
+
+/// CCValAssign - Represent assignment of one arg/retval to a location.
+class CCValAssign {
+public:
+ enum LocInfo {
+ Full, // The value fills the full location.
+ SExt, // The value is sign extended in the location.
+ ZExt, // The value is zero extended in the location.
+ AExt // The value is extended with undefined upper bits.
+ // TODO: a subset of the value is in the location.
+ };
+private:
+ /// ValNo - This is the value number begin assigned (e.g. an argument number).
+ unsigned ValNo;
+
+ /// Loc is either a stack offset or a register number.
+ unsigned Loc;
+
+ /// isMem - True if this is a memory loc, false if it is a register loc.
+ bool isMem : 1;
+
+ /// Information about how the value is assigned.
+ LocInfo HTP : 7;
+
+ /// ValVT - The type of the value being assigned.
+ MVT::ValueType ValVT;
+
+ /// LocVT - The type of the location being assigned to.
+ MVT::ValueType LocVT;
+public:
+
+ static CCValAssign getReg(unsigned ValNo, MVT::ValueType ValVT,
+ unsigned RegNo, MVT::ValueType LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = RegNo;
+ Ret.isMem = false;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+ static CCValAssign getMem(unsigned ValNo, MVT::ValueType ValVT,
+ unsigned Offset, MVT::ValueType LocVT,
+ LocInfo HTP) {
+ CCValAssign Ret;
+ Ret.ValNo = ValNo;
+ Ret.Loc = Offset;
+ Ret.isMem = true;
+ Ret.HTP = HTP;
+ Ret.ValVT = ValVT;
+ Ret.LocVT = LocVT;
+ return Ret;
+ }
+
+ unsigned getValNo() const { return ValNo; }
+ MVT::ValueType getValVT() const { return ValVT; }
+
+ bool isRegLoc() const { return !isMem; }
+ bool isMemLoc() const { return isMem; }
+
+ unsigned getLocReg() const { assert(isRegLoc()); return Loc; }
+ unsigned getLocMemOffset() const { assert(isMemLoc()); return Loc; }
+ MVT::ValueType getLocVT() const { return LocVT; }
+
+ LocInfo getLocInfo() const { return HTP; }
+};
+
+
+/// CCAssignFn - This function assigns a location for Val, updating State to
+/// reflect the change.
+typedef bool CCAssignFn(unsigned ValNo, MVT::ValueType ValVT,
+ MVT::ValueType LocVT, CCValAssign::LocInfo LocInfo,
+ unsigned ArgFlags, CCState &State);
+
+
+/// CCState - This class holds information needed while lowering arguments and
+/// return values. It captures which registers are already assigned and which
+/// stack slots are used. It provides accessors to allocate these values.
+class CCState {
+ unsigned CallingConv;
+ bool IsVarArg;
+ const TargetMachine &TM;
+ const MRegisterInfo &MRI;
+ SmallVector<CCValAssign, 16> &Locs;
+
+ unsigned StackOffset;
+ SmallVector<uint32_t, 16> UsedRegs;
+public:
+ CCState(unsigned CC, bool isVarArg, const TargetMachine &TM,
+ SmallVector<CCValAssign, 16> &locs);
+
+ void addLoc(const CCValAssign &V) {
+ Locs.push_back(V);
+ }
+
+ const TargetMachine &getTarget() const { return TM; }
+ unsigned getCallingConv() const { return CallingConv; }
+ bool isVarArg() const { return IsVarArg; }
+
+ unsigned getNextStackOffset() const { return StackOffset; }
+
+ /// isAllocated - Return true if the specified register (or an alias) is
+ /// allocated.
+ bool isAllocated(unsigned Reg) const {
+ return UsedRegs[Reg/32] & (1 << (Reg&31));
+ }
+
+ /// AnalyzeFormalArguments - Analyze an ISD::FORMAL_ARGUMENTS node,
+ /// incorporating info about the formals into this state.
+ void AnalyzeFormalArguments(SDNode *TheArgs, CCAssignFn Fn);
+
+ /// AnalyzeReturn - Analyze the returned values of an ISD::RET node,
+ /// incorporating info about the result values into this state.
+ void AnalyzeReturn(SDNode *TheRet, CCAssignFn Fn);
+
+ /// AnalyzeCallOperands - Analyze an ISD::CALL node, incorporating info
+ /// about the passed values into this state.
+ void AnalyzeCallOperands(SDNode *TheCall, CCAssignFn Fn);
+
+ /// AnalyzeCallResult - Analyze the return values of an ISD::CALL node,
+ /// incorporating info about the passed values into this state.
+ void AnalyzeCallResult(SDNode *TheCall, CCAssignFn Fn);
+
+
+ /// getFirstUnallocated - Return the first unallocated register in the set, or
+ /// NumRegs if they are all allocated.
+ unsigned getFirstUnallocated(const unsigned *Regs, unsigned NumRegs) const {
+ for (unsigned i = 0; i != NumRegs; ++i)
+ if (!isAllocated(Regs[i]))
+ return i;
+ return NumRegs;
+ }
+
+ /// AllocateReg - Attempt to allocate one register. If it is not available,
+ /// return zero. Otherwise, return the register, marking it and any aliases
+ /// as allocated.
+ unsigned AllocateReg(unsigned Reg) {
+ if (isAllocated(Reg)) return 0;
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// AllocateReg - Attempt to allocate one of the specified registers. If none
+ /// are available, return zero. Otherwise, return the first one available,
+ /// marking it and any aliases as allocated.
+ unsigned AllocateReg(const unsigned *Regs, unsigned NumRegs) {
+ unsigned FirstUnalloc = getFirstUnallocated(Regs, NumRegs);
+ if (FirstUnalloc == NumRegs)
+ return 0; // Didn't find the reg.
+
+ // Mark the register and any aliases as allocated.
+ unsigned Reg = Regs[FirstUnalloc];
+ MarkAllocated(Reg);
+ return Reg;
+ }
+
+ /// AllocateStack - Allocate a chunk of stack space with the specified size
+ /// and alignment.
+ unsigned AllocateStack(unsigned Size, unsigned Align) {
+ assert(Align && ((Align-1) & Align) == 0); // Align is power of 2.
+ StackOffset = ((StackOffset + Align-1) & ~(Align-1));
+ unsigned Result = StackOffset;
+ StackOffset += Size;
+ return Result;
+ }
+private:
+ /// MarkAllocated - Mark a register and all of its aliases as allocated.
+ void MarkAllocated(unsigned Reg);
+};
+
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
new file mode 100644
index 0000000..d5d6925
--- /dev/null
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -0,0 +1,82 @@
+//===-- llvm/CodeGen/DwarfWriter.h - Dwarf Framework ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for writing Dwarf debug and exception info into
+// asm files. For Details on the Dwarf 3 specfication see DWARF Debugging
+// Information Format V.3 reference manual http://dwarf.freestandards.org ,
+//
+// The role of the Dwarf Writer class is to extract information from the
+// MachineModuleInfo object, organize it in Dwarf form and then emit it into asm
+// the current asm file using data and high level Dwarf directives.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_DWARFWRITER_H
+#define LLVM_CODEGEN_DWARFWRITER_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+class AsmPrinter;
+class DwarfDebug;
+class DwarfException;
+class MachineModuleInfo;
+class MachineFunction;
+class Module;
+class TargetAsmInfo;
+
+//===----------------------------------------------------------------------===//
+// DwarfWriter - Emits Dwarf debug and exception handling directives.
+//
+
+class DwarfWriter {
+private:
+ /// DD - Provides the DwarfWriter debug implementation.
+ ///
+ DwarfDebug *DD;
+
+ /// DE - Provides the DwarfWriter exception implementation.
+ ///
+ DwarfException *DE;
+
+public:
+
+ DwarfWriter(std::ostream &OS, AsmPrinter *A, const TargetAsmInfo *T);
+ virtual ~DwarfWriter();
+
+ /// SetModuleInfo - Set machine module info when it's known that pass manager
+ /// has created it. Set by the target AsmPrinter.
+ void SetModuleInfo(MachineModuleInfo *MMI);
+
+ //===--------------------------------------------------------------------===//
+ // Main entry points.
+ //
+
+ /// BeginModule - Emit all Dwarf sections that should come prior to the
+ /// content.
+ void BeginModule(Module *M);
+
+ /// EndModule - Emit all Dwarf sections that should come after the content.
+ ///
+ void EndModule();
+
+ /// BeginFunction - Gather pre-function debug information. Assumes being
+ /// emitted immediately after the function entry point.
+ void BeginFunction(MachineFunction *MF);
+
+ /// EndFunction - Gather and emit post-function debug information.
+ ///
+ void EndFunction();
+};
+
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ELFRelocation.h b/include/llvm/CodeGen/ELFRelocation.h
new file mode 100644
index 0000000..1c0b3e9
--- /dev/null
+++ b/include/llvm/CodeGen/ELFRelocation.h
@@ -0,0 +1,52 @@
+//=== ELFRelocation.h - ELF Relocation Info ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Christopher Lamb and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ELFRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_ELF_RELOCATION_H
+#define LLVM_CODEGEN_ELF_RELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+ /// ELFRelocation - This class contains all the information necessary to
+ /// to generate any 32-bit or 64-bit ELF relocation entry.
+ class ELFRelocation {
+ uint64_t r_offset; // offset in the section of the object this applies to
+ uint32_t r_symidx; // symbol table index of the symbol to use
+ uint32_t r_type; // machine specific relocation type
+ int64_t r_add; // explicit relocation addend
+ bool r_rela; // if true then the addend is part of the entry
+ // otherwise the addend is at the location specified
+ // by r_offset
+ public:
+
+ uint64_t getInfo(bool is64Bit = false) const {
+ if (is64Bit)
+ return ((uint64_t)r_symidx << 32) + ((uint64_t)r_type & 0xFFFFFFFFL);
+ else
+ return (r_symidx << 8) + (r_type & 0xFFL);
+ }
+
+ uint64_t getOffset() const { return r_offset; }
+ uint64_t getAddress() const { return r_add; }
+
+ ELFRelocation(uint64_t off, uint32_t sym, uint32_t type,
+ bool rela = true, int64_t addend = 0) :
+ r_offset(off), r_symidx(sym), r_type(type),
+ r_add(addend), r_rela(rela) {}
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_ELF_RELOCATION_H
+
diff --git a/include/llvm/CodeGen/FileWriters.h b/include/llvm/CodeGen/FileWriters.h
new file mode 100644
index 0000000..6baa89f
--- /dev/null
+++ b/include/llvm/CodeGen/FileWriters.h
@@ -0,0 +1,32 @@
+//===-- FileWriters.h - File Writers Creation Functions ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Functions to add the various file writer passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_FILEWRITERS_H
+#define LLVM_CODEGEN_FILEWRITERS_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+ class FunctionPassManager;
+ class MachineCodeEmitter;
+ class TargetMachine;
+
+ MachineCodeEmitter *AddELFWriter(FunctionPassManager &FPM, std::ostream &O,
+ TargetMachine &TM);
+ MachineCodeEmitter *AddMachOWriter(FunctionPassManager &FPM, std::ostream &O,
+ TargetMachine &TM);
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_FILEWRITERS_H
diff --git a/include/llvm/CodeGen/IntrinsicLowering.h b/include/llvm/CodeGen/IntrinsicLowering.h
new file mode 100644
index 0000000..bff1b39
--- /dev/null
+++ b/include/llvm/CodeGen/IntrinsicLowering.h
@@ -0,0 +1,50 @@
+//===-- IntrinsicLowering.h - Intrinsic Function Lowering -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the IntrinsicLowering interface. This interface allows
+// addition of domain-specific or front-end specific intrinsics to LLVM without
+// having to modify all of the C backend or interpreter.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_INTRINSICLOWERING_H
+#define LLVM_CODEGEN_INTRINSICLOWERING_H
+
+#include "llvm/Intrinsics.h"
+
+namespace llvm {
+ class CallInst;
+ class Module;
+ class TargetData;
+
+ class IntrinsicLowering {
+ const TargetData& TD;
+ public:
+ explicit IntrinsicLowering(const TargetData &td) : TD(td) {}
+
+ /// AddPrototypes - This method, if called, causes all of the prototypes
+ /// that might be needed by an intrinsic lowering implementation to be
+ /// inserted into the module specified.
+ void AddPrototypes(Module &M);
+
+ /// LowerIntrinsicCall - This method replaces a call with the LLVM function
+ /// which should be used to implement the specified intrinsic function call.
+ /// If an intrinsic function must be implemented by the code generator
+ /// (such as va_start), this function should print a message and abort.
+ ///
+ /// Otherwise, if an intrinsic function call can be lowered, the code to
+ /// implement it (often a call to a non-intrinsic function) is inserted
+ /// _after_ the call instruction and the call is deleted. The caller must
+ /// be capable of handling this kind of change.
+ ///
+ void LowerIntrinsicCall(CallInst *CI);
+ };
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h
new file mode 100644
index 0000000..15021c1
--- /dev/null
+++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h
@@ -0,0 +1,48 @@
+//===- llvm/Codegen/LinkAllCodegenComponents.h ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all codegen related passes for tools like lli and
+// llc that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+#define LLVM_CODEGEN_LINKALLCODEGENCOMPONENTS_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/ScheduleDAG.h"
+
+namespace {
+ struct ForceCodegenLinking {
+ ForceCodegenLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void) llvm::createSimpleRegisterAllocator();
+ (void) llvm::createLocalRegisterAllocator();
+ (void) llvm::createBigBlockRegisterAllocator();
+ (void) llvm::createLinearScanRegisterAllocator();
+
+ (void) llvm::createBFS_DAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createSimpleDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createNoItinsDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createBURRListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createTDRRListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createTDListDAGScheduler(NULL, NULL, NULL);
+ (void) llvm::createDefaultScheduler(NULL, NULL, NULL);
+
+ }
+ } ForceCodegenLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveInterval.h b/include/llvm/CodeGen/LiveInterval.h
new file mode 100644
index 0000000..1912d64
--- /dev/null
+++ b/include/llvm/CodeGen/LiveInterval.h
@@ -0,0 +1,287 @@
+//===-- llvm/CodeGen/LiveInterval.h - Interval representation ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveRange and LiveInterval classes. Given some
+// numbering of each the machine instructions an interval [i, j) is said to be a
+// live interval for register v if there is no instruction with number j' > j
+// such that v is live at j' and there is no instruction with number i' < i such
+// that v is live at i'. In this implementation intervals can have holes,
+// i.e. an interval might look like [1,20), [50,65), [1000,1001). Each
+// individual range is represented as an instance of LiveRange, and the whole
+// interval is represented as an instance of LiveInterval.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_H
+#define LLVM_CODEGEN_LIVEINTERVAL_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Streams.h"
+#include <iosfwd>
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class MachineInstr;
+ class MRegisterInfo;
+
+ /// LiveRange structure - This represents a simple register range in the
+ /// program, with an inclusive start point and an exclusive end point.
+ /// These ranges are rendered as [start,end).
+ struct LiveRange {
+ unsigned start; // Start point of the interval (inclusive)
+ unsigned end; // End point of the interval (exclusive)
+ unsigned ValId; // identifier for the value contained in this interval.
+
+ LiveRange(unsigned S, unsigned E, unsigned V) : start(S), end(E), ValId(V) {
+ assert(S < E && "Cannot create empty or backwards range");
+ }
+
+ /// contains - Return true if the index is covered by this range.
+ ///
+ bool contains(unsigned I) const {
+ return start <= I && I < end;
+ }
+
+ bool operator<(const LiveRange &LR) const {
+ return start < LR.start || (start == LR.start && end < LR.end);
+ }
+ bool operator==(const LiveRange &LR) const {
+ return start == LR.start && end == LR.end;
+ }
+
+ void dump() const;
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+ private:
+ LiveRange(); // DO NOT IMPLEMENT
+ };
+
+ std::ostream& operator<<(std::ostream& os, const LiveRange &LR);
+
+
+ inline bool operator<(unsigned V, const LiveRange &LR) {
+ return V < LR.start;
+ }
+
+ inline bool operator<(const LiveRange &LR, unsigned V) {
+ return LR.start < V;
+ }
+
+ /// LiveInterval - This class represents some number of live ranges for a
+ /// register or value. This class also contains a bit of register allocator
+ /// state.
+ struct LiveInterval {
+ typedef SmallVector<LiveRange,4> Ranges;
+ unsigned reg; // the register of this interval
+ unsigned preference; // preferred register to allocate for this interval
+ float weight; // weight of this interval
+ MachineInstr* remat; // definition if the definition rematerializable
+ Ranges ranges; // the ranges in which this register is live
+ private:
+ /// ValueNumberInfo - If this value number is not defined by a copy, this
+ /// holds ~0,x. If the value number is not in use, it contains ~1,x to
+ /// indicate that the value # is not used. If the val# is defined by a
+ /// copy, the first entry is the instruction # of the copy, and the second
+ /// is the register number copied from.
+ SmallVector<std::pair<unsigned,unsigned>, 4> ValueNumberInfo;
+ public:
+
+ LiveInterval(unsigned Reg, float Weight)
+ : reg(Reg), preference(0), weight(Weight), remat(NULL) {
+ }
+
+ typedef Ranges::iterator iterator;
+ iterator begin() { return ranges.begin(); }
+ iterator end() { return ranges.end(); }
+
+ typedef Ranges::const_iterator const_iterator;
+ const_iterator begin() const { return ranges.begin(); }
+ const_iterator end() const { return ranges.end(); }
+
+
+ /// advanceTo - Advance the specified iterator to point to the LiveRange
+ /// containing the specified position, or end() if the position is past the
+ /// end of the interval. If no LiveRange contains this position, but the
+ /// position is in a hole, this method returns an iterator pointing the the
+ /// LiveRange immediately after the hole.
+ iterator advanceTo(iterator I, unsigned Pos) {
+ if (Pos >= endNumber())
+ return end();
+ while (I->end <= Pos) ++I;
+ return I;
+ }
+
+ void swap(LiveInterval& other) {
+ std::swap(reg, other.reg);
+ std::swap(weight, other.weight);
+ std::swap(remat, other.remat);
+ std::swap(ranges, other.ranges);
+ std::swap(ValueNumberInfo, other.ValueNumberInfo);
+ }
+
+ bool containsOneValue() const { return ValueNumberInfo.size() == 1; }
+
+ unsigned getNumValNums() const { return ValueNumberInfo.size(); }
+
+ /// getNextValue - Create a new value number and return it. MIIdx specifies
+ /// the instruction that defines the value number.
+ unsigned getNextValue(unsigned MIIdx, unsigned SrcReg) {
+ ValueNumberInfo.push_back(std::make_pair(MIIdx, SrcReg));
+ return ValueNumberInfo.size()-1;
+ }
+
+ /// getInstForValNum - Return the machine instruction index that defines the
+ /// specified value number.
+ unsigned getInstForValNum(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ return ValueNumberInfo[ValNo].first;
+ }
+
+ unsigned getSrcRegForValNum(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ if (ValueNumberInfo[ValNo].first < ~2U)
+ return ValueNumberInfo[ValNo].second;
+ return 0;
+ }
+
+ std::pair<unsigned, unsigned> getValNumInfo(unsigned ValNo) const {
+ //assert(ValNo < ValueNumberInfo.size());
+ return ValueNumberInfo[ValNo];
+ }
+
+ /// setValueNumberInfo - Change the value number info for the specified
+ /// value number.
+ void setValueNumberInfo(unsigned ValNo,
+ const std::pair<unsigned, unsigned> &I){
+ ValueNumberInfo[ValNo] = I;
+ }
+
+ /// MergeValueNumberInto - This method is called when two value nubmers
+ /// are found to be equivalent. This eliminates V1, replacing all
+ /// LiveRanges with the V1 value number with the V2 value number. This can
+ /// cause merging of V1/V2 values numbers and compaction of the value space.
+ void MergeValueNumberInto(unsigned V1, unsigned V2);
+
+ /// MergeInClobberRanges - For any live ranges that are not defined in the
+ /// current interval, but are defined in the Clobbers interval, mark them
+ /// used with an unknown definition value.
+ void MergeInClobberRanges(const LiveInterval &Clobbers);
+
+
+ /// MergeRangesInAsValue - Merge all of the intervals in RHS into this live
+ /// interval as the specified value number. The LiveRanges in RHS are
+ /// allowed to overlap with LiveRanges in the current interval, but only if
+ /// the overlapping LiveRanges have the specified value number.
+ void MergeRangesInAsValue(const LiveInterval &RHS, unsigned LHSValNo);
+
+ bool empty() const { return ranges.empty(); }
+
+ /// beginNumber - Return the lowest numbered slot covered by interval.
+ unsigned beginNumber() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.front().start;
+ }
+
+ /// endNumber - return the maximum point of the interval of the whole,
+ /// exclusive.
+ unsigned endNumber() const {
+ assert(!empty() && "empty interval for register");
+ return ranges.back().end;
+ }
+
+ bool expiredAt(unsigned index) const {
+ return index >= endNumber();
+ }
+
+ bool liveAt(unsigned index) const;
+
+ /// getLiveRangeContaining - Return the live range that contains the
+ /// specified index, or null if there is none.
+ const LiveRange *getLiveRangeContaining(unsigned Idx) const {
+ const_iterator I = FindLiveRangeContaining(Idx);
+ return I == end() ? 0 : &*I;
+ }
+
+ /// FindLiveRangeContaining - Return an iterator to the live range that
+ /// contains the specified index, or end() if there is none.
+ const_iterator FindLiveRangeContaining(unsigned Idx) const;
+
+ /// FindLiveRangeContaining - Return an iterator to the live range that
+ /// contains the specified index, or end() if there is none.
+ iterator FindLiveRangeContaining(unsigned Idx);
+
+ /// getOverlapingRanges - Given another live interval which is defined as a
+ /// copy from this one, return a list of all of the live ranges where the
+ /// two overlap and have different value numbers.
+ void getOverlapingRanges(const LiveInterval &Other, unsigned CopyIdx,
+ std::vector<LiveRange*> &Ranges);
+
+ /// overlaps - Return true if the intersection of the two live intervals is
+ /// not empty.
+ bool overlaps(const LiveInterval& other) const {
+ return overlapsFrom(other, other.begin());
+ }
+
+ /// overlapsFrom - Return true if the intersection of the two live intervals
+ /// is not empty. The specified iterator is a hint that we can begin
+ /// scanning the Other interval starting at I.
+ bool overlapsFrom(const LiveInterval& other, const_iterator I) const;
+
+ /// addRange - Add the specified LiveRange to this interval, merging
+ /// intervals as appropriate. This returns an iterator to the inserted live
+ /// range (which may have grown since it was inserted.
+ void addRange(LiveRange LR) {
+ addRangeFrom(LR, ranges.begin());
+ }
+
+ /// join - Join two live intervals (this, and other) together. This applies
+ /// mappings to the value numbers in the LHS/RHS intervals as specified. If
+ /// the intervals are not joinable, this aborts.
+ void join(LiveInterval &Other, int *ValNoAssignments,
+ int *RHSValNoAssignments,
+ SmallVector<std::pair<unsigned,unsigned>,16> &NewValueNumberInfo);
+
+ /// removeRange - Remove the specified range from this interval. Note that
+ /// the range must already be in this interval in its entirety.
+ void removeRange(unsigned Start, unsigned End);
+
+ void removeRange(LiveRange LR) {
+ removeRange(LR.start, LR.end);
+ }
+
+ /// getSize - Returns the sum of sizes of all the LiveRange's.
+ ///
+ unsigned getSize() const;
+
+ bool operator<(const LiveInterval& other) const {
+ return beginNumber() < other.beginNumber();
+ }
+
+ void print(std::ostream &OS, const MRegisterInfo *MRI = 0) const;
+ void print(std::ostream *OS, const MRegisterInfo *MRI = 0) const {
+ if (OS) print(*OS, MRI);
+ }
+ void dump() const;
+
+ private:
+ Ranges::iterator addRangeFrom(LiveRange LR, Ranges::iterator From);
+ void extendIntervalEndTo(Ranges::iterator I, unsigned NewEnd);
+ Ranges::iterator extendIntervalStartTo(Ranges::iterator I, unsigned NewStr);
+ LiveInterval& operator=(const LiveInterval& rhs); // DO NOT IMPLEMENT
+ };
+
+ inline std::ostream &operator<<(std::ostream &OS, const LiveInterval &LI) {
+ LI.print(OS);
+ return OS;
+ }
+}
+
+#endif
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h
new file mode 100644
index 0000000..4783df4
--- /dev/null
+++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h
@@ -0,0 +1,235 @@
+//===-- LiveIntervalAnalysis.h - Live Interval Analysis ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveInterval analysis pass. Given some numbering of
+// each the machine instructions (in this implemention depth-first order) an
+// interval [i, j) is said to be a live interval for register v if there is no
+// instruction with number j' > j such that v is live at j' abd there is no
+// instruction with number i' < i such that v is live at i'. In this
+// implementation intervals can have holes, i.e. an interval might look like
+// [1,20), [50,65), [1000,1001).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+#define LLVM_CODEGEN_LIVEINTERVAL_ANALYSIS_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+ class LiveVariables;
+ class MRegisterInfo;
+ class TargetInstrInfo;
+ class TargetRegisterClass;
+ class VirtRegMap;
+
+ class LiveIntervals : public MachineFunctionPass {
+ MachineFunction* mf_;
+ const TargetMachine* tm_;
+ const MRegisterInfo* mri_;
+ const TargetInstrInfo* tii_;
+ LiveVariables* lv_;
+
+ /// MBB2IdxMap - The index of the first instruction in the specified basic
+ /// block.
+ std::vector<unsigned> MBB2IdxMap;
+
+ typedef std::map<MachineInstr*, unsigned> Mi2IndexMap;
+ Mi2IndexMap mi2iMap_;
+
+ typedef std::vector<MachineInstr*> Index2MiMap;
+ Index2MiMap i2miMap_;
+
+ typedef std::map<unsigned, LiveInterval> Reg2IntervalMap;
+ Reg2IntervalMap r2iMap_;
+
+ BitVector allocatableRegs_;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveIntervals() : MachineFunctionPass((intptr_t)&ID) {}
+
+ struct InstrSlots {
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4
+ };
+ };
+
+ static unsigned getBaseIndex(unsigned index) {
+ return index - (index % InstrSlots::NUM);
+ }
+ static unsigned getBoundaryIndex(unsigned index) {
+ return getBaseIndex(index + InstrSlots::NUM - 1);
+ }
+ static unsigned getLoadIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::LOAD;
+ }
+ static unsigned getUseIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::USE;
+ }
+ static unsigned getDefIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::DEF;
+ }
+ static unsigned getStoreIndex(unsigned index) {
+ return getBaseIndex(index) + InstrSlots::STORE;
+ }
+
+ typedef Reg2IntervalMap::iterator iterator;
+ typedef Reg2IntervalMap::const_iterator const_iterator;
+ const_iterator begin() const { return r2iMap_.begin(); }
+ const_iterator end() const { return r2iMap_.end(); }
+ iterator begin() { return r2iMap_.begin(); }
+ iterator end() { return r2iMap_.end(); }
+ unsigned getNumIntervals() const { return r2iMap_.size(); }
+
+ LiveInterval &getInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ const LiveInterval &getInterval(unsigned reg) const {
+ Reg2IntervalMap::const_iterator I = r2iMap_.find(reg);
+ assert(I != r2iMap_.end() && "Interval does not exist for register");
+ return I->second;
+ }
+
+ bool hasInterval(unsigned reg) const {
+ return r2iMap_.count(reg);
+ }
+
+ /// getMBBStartIdx - Return the base index of the first instruction in the
+ /// specified MachineBasicBlock.
+ unsigned getMBBStartIdx(MachineBasicBlock *MBB) const {
+ return getMBBStartIdx(MBB->getNumber());
+ }
+
+ unsigned getMBBStartIdx(unsigned MBBNo) const {
+ assert(MBBNo < MBB2IdxMap.size() && "Invalid MBB number!");
+ return MBB2IdxMap[MBBNo];
+ }
+
+ /// getInstructionIndex - returns the base index of instr
+ unsigned getInstructionIndex(MachineInstr* instr) const {
+ Mi2IndexMap::const_iterator it = mi2iMap_.find(instr);
+ assert(it != mi2iMap_.end() && "Invalid instruction!");
+ return it->second;
+ }
+
+ /// getInstructionFromIndex - given an index in any slot of an
+ /// instruction return a pointer the instruction
+ MachineInstr* getInstructionFromIndex(unsigned index) const {
+ index /= InstrSlots::NUM; // convert index to vector index
+ assert(index < i2miMap_.size() &&
+ "index does not correspond to an instruction");
+ return i2miMap_[index];
+ }
+
+ // Interval creation
+
+ LiveInterval &getOrCreateInterval(unsigned reg) {
+ Reg2IntervalMap::iterator I = r2iMap_.find(reg);
+ if (I == r2iMap_.end())
+ I = r2iMap_.insert(I, std::make_pair(reg, createInterval(reg)));
+ return I->second;
+ }
+
+ /// CreateNewLiveInterval - Create a new live interval with the given live
+ /// ranges. The new live interval will have an infinite spill weight.
+ LiveInterval &CreateNewLiveInterval(const LiveInterval *LI,
+ const std::vector<LiveRange> &LRs);
+
+ std::vector<LiveInterval*> addIntervalsForSpills(const LiveInterval& i,
+ VirtRegMap& vrm,
+ int slot);
+
+ // Interval removal
+
+ void removeInterval(unsigned Reg) {
+ r2iMap_.erase(Reg);
+ }
+
+ /// isRemoved - returns true if the specified machine instr has been
+ /// removed.
+ bool isRemoved(MachineInstr* instr) const {
+ return !mi2iMap_.count(instr);
+ }
+
+ /// RemoveMachineInstrFromMaps - This marks the specified machine instr as
+ /// deleted.
+ void RemoveMachineInstrFromMaps(MachineInstr *MI) {
+ // remove index -> MachineInstr and
+ // MachineInstr -> index mappings
+ Mi2IndexMap::iterator mi2i = mi2iMap_.find(MI);
+ if (mi2i != mi2iMap_.end()) {
+ i2miMap_[mi2i->second/InstrSlots::NUM] = 0;
+ mi2iMap_.erase(mi2i);
+ }
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ private:
+ /// computeIntervals - Compute live intervals.
+ void computeIntervals();
+
+ /// handleRegisterDef - update intervals for a register def
+ /// (calls handlePhysicalRegisterDef and
+ /// handleVirtualRegisterDef)
+ void handleRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI, unsigned MIIdx,
+ unsigned reg);
+
+ /// handleVirtualRegisterDef - update intervals for a virtual
+ /// register def
+ void handleVirtualRegisterDef(MachineBasicBlock *MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned MIIdx,
+ LiveInterval& interval);
+
+ /// handlePhysicalRegisterDef - update intervals for a physical register
+ /// def.
+ void handlePhysicalRegisterDef(MachineBasicBlock* mbb,
+ MachineBasicBlock::iterator mi,
+ unsigned MIIdx,
+ LiveInterval &interval,
+ unsigned SrcReg);
+
+ /// handleLiveInRegister - Create interval for a livein register.
+ void handleLiveInRegister(MachineBasicBlock* mbb,
+ unsigned MIIdx,
+ LiveInterval &interval, bool isAlias = false);
+
+ static LiveInterval createInterval(unsigned Reg);
+
+ void printRegName(unsigned reg) const;
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/LiveVariables.h b/include/llvm/CodeGen/LiveVariables.h
new file mode 100644
index 0000000..ec01556
--- /dev/null
+++ b/include/llvm/CodeGen/LiveVariables.h
@@ -0,0 +1,304 @@
+//===-- llvm/CodeGen/LiveVariables.h - Live Variable Analysis ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the LiveVariable analysis pass. For each machine
+// instruction in the function, this pass calculates the set of registers that
+// are immediately dead after the instruction (i.e., the instruction calculates
+// the value, but it is never used) and the set of registers that are used by
+// the instruction, but are never used after the instruction (i.e., they are
+// killed).
+//
+// This class computes live variables using are sparse implementation based on
+// the machine code SSA form. This class computes live variable information for
+// each virtual and _register allocatable_ physical register in a function. It
+// uses the dominance properties of SSA form to efficiently compute live
+// variables for virtual registers, and assumes that physical registers are only
+// live within a single basic block (allowing it to do a single local analysis
+// to resolve physical register lifetimes in each basic block). If a physical
+// register is not register allocatable, it is not tracked. This is useful for
+// things like the stack pointer and condition codes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_LIVEVARIABLES_H
+#define LLVM_CODEGEN_LIVEVARIABLES_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include <map>
+
+namespace llvm {
+
+class MRegisterInfo;
+
+class LiveVariables : public MachineFunctionPass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ LiveVariables() : MachineFunctionPass((intptr_t)&ID) {}
+
+ /// VarInfo - This represents the regions where a virtual register is live in
+ /// the program. We represent this with three different pieces of
+ /// information: the instruction that uniquely defines the value, the set of
+ /// blocks the instruction is live into and live out of, and the set of
+ /// non-phi instructions that are the last users of the value.
+ ///
+ /// In the common case where a value is defined and killed in the same block,
+ /// DefInst is the defining inst, there is one killing instruction, and
+ /// AliveBlocks is empty.
+ ///
+ /// Otherwise, the value is live out of the block. If the value is live
+ /// across any blocks, these blocks are listed in AliveBlocks. Blocks where
+ /// the liveness range ends are not included in AliveBlocks, instead being
+ /// captured by the Kills set. In these blocks, the value is live into the
+ /// block (unless the value is defined and killed in the same block) and lives
+ /// until the specified instruction. Note that there cannot ever be a value
+ /// whose Kills set contains two instructions from the same basic block.
+ ///
+ /// PHI nodes complicate things a bit. If a PHI node is the last user of a
+ /// value in one of its predecessor blocks, it is not listed in the kills set,
+ /// but does include the predecessor block in the AliveBlocks set (unless that
+ /// block also defines the value). This leads to the (perfectly sensical)
+ /// situation where a value is defined in a block, and the last use is a phi
+ /// node in the successor. In this case, DefInst will be the defining
+ /// instruction, AliveBlocks is empty (the value is not live across any
+ /// blocks) and Kills is empty (phi nodes are not included). This is sensical
+ /// because the value must be live to the end of the block, but is not live in
+ /// any successor blocks.
+ struct VarInfo {
+ /// DefInst - The machine instruction that defines this register.
+ ///
+ MachineInstr *DefInst;
+
+ /// AliveBlocks - Set of blocks of which this value is alive completely
+ /// through. This is a bit set which uses the basic block number as an
+ /// index.
+ ///
+ BitVector AliveBlocks;
+
+ /// NumUses - Number of uses of this register across the entire function.
+ ///
+ unsigned NumUses;
+
+ /// Kills - List of MachineInstruction's which are the last use of this
+ /// virtual register (kill it) in their basic block.
+ ///
+ std::vector<MachineInstr*> Kills;
+
+ VarInfo() : DefInst(0), NumUses(0) {}
+
+ /// removeKill - Delete a kill corresponding to the specified
+ /// machine instruction. Returns true if there was a kill
+ /// corresponding to this instruction, false otherwise.
+ bool removeKill(MachineInstr *MI) {
+ for (std::vector<MachineInstr*>::iterator i = Kills.begin(),
+ e = Kills.end(); i != e; ++i)
+ if (*i == MI) {
+ Kills.erase(i);
+ return true;
+ }
+ return false;
+ }
+
+ void dump() const;
+ };
+
+private:
+ /// VirtRegInfo - This list is a mapping from virtual register number to
+ /// variable information. FirstVirtualRegister is subtracted from the virtual
+ /// register number before indexing into this list.
+ ///
+ std::vector<VarInfo> VirtRegInfo;
+
+ /// ReservedRegisters - This vector keeps track of which registers
+ /// are reserved register which are not allocatable by the target machine.
+ /// We can not track liveness for values that are in this set.
+ ///
+ BitVector ReservedRegisters;
+
+private: // Intermediate data structures
+ MachineFunction *MF;
+
+ const MRegisterInfo *RegInfo;
+
+ // PhysRegInfo - Keep track of which instruction was the last def/use of a
+ // physical register. This is a purely local property, because all physical
+ // register references as presumed dead across basic blocks.
+ MachineInstr **PhysRegInfo;
+
+ // PhysRegUsed - Keep track whether the physical register has been used after
+ // its last definition. This is local property.
+ bool *PhysRegUsed;
+
+ // PhysRegPartUse - Keep track of which instruction was the last partial use
+ // of a physical register (e.g. on X86 a def of EAX followed by a use of AX).
+ // This is a purely local property.
+ MachineInstr **PhysRegPartUse;
+
+ // PhysRegPartDef - Keep track of a list of instructions which "partially"
+ // defined the physical register (e.g. on X86 AX partially defines EAX).
+ // These are turned into use/mod/write if there is a use of the register
+ // later in the same block. This is local property.
+ SmallVector<MachineInstr*, 4> *PhysRegPartDef;
+
+ SmallVector<unsigned, 4> *PHIVarInfo;
+
+ /// addRegisterKilled - We have determined MI kills a register. Look for the
+ /// operand that uses it and mark it as IsKill. If AddIfNotFound is true,
+ /// add a implicit operand if it's not found. Returns true if the operand
+ /// exists / is added.
+ bool addRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false);
+
+ /// addRegisterDead - We have determined MI defined a register without a use.
+ /// Look for the operand that defines it and mark it as IsDead. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found. Returns
+ /// true if the operand exists / is added.
+ bool addRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false);
+
+ void addRegisterKills(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+
+ /// HandlePhysRegKill - Add kills of Reg and its sub-registers to the
+ /// uses. Pay special attention to the sub-register uses which may come below
+ /// the last use of the whole register.
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI,
+ SmallSet<unsigned, 4> &SubKills);
+ bool HandlePhysRegKill(unsigned Reg, MachineInstr *MI);
+ void HandlePhysRegUse(unsigned Reg, MachineInstr *MI);
+ void HandlePhysRegDef(unsigned Reg, MachineInstr *MI);
+
+ /// analyzePHINodes - Gather information about the PHI nodes in here. In
+ /// particular, we want to map the variable information of a virtual
+ /// register which is used in a PHI node. We map that to the BB the vreg
+ /// is coming from.
+ void analyzePHINodes(const MachineFunction& Fn);
+public:
+
+ virtual bool runOnMachineFunction(MachineFunction &MF);
+
+ /// KillsRegister - Return true if the specified instruction kills the
+ /// specified register.
+ bool KillsRegister(MachineInstr *MI, unsigned Reg) const;
+
+ /// RegisterDefIsDead - Return true if the specified instruction defines the
+ /// specified register, but that definition is dead.
+ bool RegisterDefIsDead(MachineInstr *MI, unsigned Reg) const;
+
+ /// ModifiesRegister - Return true if the specified instruction modifies the
+ /// specified register.
+ bool ModifiesRegister(MachineInstr *MI, unsigned Reg) const;
+
+ //===--------------------------------------------------------------------===//
+ // API to update live variable information
+
+ /// instructionChanged - When the address of an instruction changes, this
+ /// method should be called so that live variables can update its internal
+ /// data structures. This removes the records for OldMI, transfering them to
+ /// the records for NewMI.
+ void instructionChanged(MachineInstr *OldMI, MachineInstr *NewMI);
+
+ /// addVirtualRegisterKilled - Add information about the fact that the
+ /// specified register is killed after being used by the specified
+ /// instruction. If AddIfNotFound is true, add a implicit operand if it's
+ /// not found.
+ void addVirtualRegisterKilled(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (addRegisterKilled(IncomingReg, MI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterKilled - Remove the specified virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked as killed by the specified instruction,
+ /// false otherwise.
+ bool removeVirtualRegisterKilled(unsigned reg,
+ MachineBasicBlock *MBB,
+ MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isUse() && MO.getReg() == reg) {
+ MO.unsetIsKill();
+ Removed = true;
+ break;
+ }
+ }
+
+ assert(Removed && "Register is not used by this instruction!");
+ return true;
+ }
+
+ /// removeVirtualRegistersKilled - Remove all killed info for the specified
+ /// instruction.
+ void removeVirtualRegistersKilled(MachineInstr *MI);
+
+ /// addVirtualRegisterDead - Add information about the fact that the specified
+ /// register is dead after being used by the specified instruction. If
+ /// AddIfNotFound is true, add a implicit operand if it's not found.
+ void addVirtualRegisterDead(unsigned IncomingReg, MachineInstr *MI,
+ bool AddIfNotFound = false) {
+ if (addRegisterDead(IncomingReg, MI, AddIfNotFound))
+ getVarInfo(IncomingReg).Kills.push_back(MI);
+ }
+
+ /// removeVirtualRegisterDead - Remove the specified virtual
+ /// register from the live variable information. Returns true if the
+ /// variable was marked dead at the specified instruction, false
+ /// otherwise.
+ bool removeVirtualRegisterDead(unsigned reg,
+ MachineBasicBlock *MBB,
+ MachineInstr *MI) {
+ if (!getVarInfo(reg).removeKill(MI))
+ return false;
+
+ bool Removed = false;
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (MO.isReg() && MO.isDef() && MO.getReg() == reg) {
+ MO.unsetIsDead();
+ Removed = true;
+ break;
+ }
+ }
+ assert(Removed && "Register is not defined by this instruction!");
+ return true;
+ }
+
+ /// removeVirtualRegistersDead - Remove all of the dead registers for the
+ /// specified instruction from the live variable information.
+ void removeVirtualRegistersDead(MachineInstr *MI);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ virtual void releaseMemory() {
+ VirtRegInfo.clear();
+ }
+
+ /// getVarInfo - Return the VarInfo structure for the specified VIRTUAL
+ /// register.
+ VarInfo &getVarInfo(unsigned RegIdx);
+
+ void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB);
+ void MarkVirtRegAliveInBlock(VarInfo &VRInfo, MachineBasicBlock *BB,
+ std::vector<MachineBasicBlock*> &WorkList);
+ void HandleVirtRegUse(VarInfo &VRInfo, MachineBasicBlock *MBB,
+ MachineInstr *MI);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachORelocation.h b/include/llvm/CodeGen/MachORelocation.h
new file mode 100644
index 0000000..6bf176d
--- /dev/null
+++ b/include/llvm/CodeGen/MachORelocation.h
@@ -0,0 +1,54 @@
+//=== MachORelocation.h - Mach-O Relocation Info ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachORelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHO_RELOCATION_H
+#define LLVM_CODEGEN_MACHO_RELOCATION_H
+
+namespace llvm {
+
+ /// MachORelocation - This struct contains information about each relocation
+ /// that needs to be emitted to the file.
+ /// see <mach-o/reloc.h>
+ class MachORelocation {
+ uint32_t r_address; // offset in the section to what is being relocated
+ uint32_t r_symbolnum; // symbol index if r_extern == 1 else section index
+ bool r_pcrel; // was relocated pc-relative already
+ uint8_t r_length; // length = 2 ^ r_length
+ bool r_extern; //
+ uint8_t r_type; // if not 0, machine-specific relocation type.
+ bool r_scattered; // 1 = scattered, 0 = non-scattered
+ int32_t r_value; // the value the item to be relocated is referring
+ // to.
+ public:
+ uint32_t getPackedFields() const {
+ if (r_scattered)
+ return (1 << 31) | (r_pcrel << 30) | ((r_length & 3) << 28) |
+ ((r_type & 15) << 24) | (r_address & 0x00FFFFFF);
+ else
+ return (r_symbolnum << 8) | (r_pcrel << 7) | ((r_length & 3) << 5) |
+ (r_extern << 4) | (r_type & 15);
+ }
+ uint32_t getAddress() const { return r_scattered ? r_value : r_address; }
+ uint32_t getRawAddress() const { return r_address; }
+
+ MachORelocation(uint32_t addr, uint32_t index, bool pcrel, uint8_t len,
+ bool ext, uint8_t type, bool scattered = false,
+ int32_t value = 0) :
+ r_address(addr), r_symbolnum(index), r_pcrel(pcrel), r_length(len),
+ r_extern(ext), r_type(type), r_scattered(scattered), r_value(value) {}
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_CODEGEN_MACHO_RELOCATION_H
diff --git a/include/llvm/CodeGen/MachineBasicBlock.h b/include/llvm/CodeGen/MachineBasicBlock.h
new file mode 100644
index 0000000..df6e5a3
--- /dev/null
+++ b/include/llvm/CodeGen/MachineBasicBlock.h
@@ -0,0 +1,371 @@
+//===-- llvm/CodeGen/MachineBasicBlock.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect the sequence of machine instructions for a basic block.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEBASICBLOCK_H
+#define LLVM_CODEGEN_MACHINEBASICBLOCK_H
+
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/ilist"
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+ class MachineFunction;
+
+// ilist_traits
+template <>
+struct ilist_traits<MachineInstr> {
+protected:
+ // this is only set by the MachineBasicBlock owning the ilist
+ friend class MachineBasicBlock;
+ MachineBasicBlock* parent;
+
+public:
+ ilist_traits<MachineInstr>() : parent(0) { }
+
+ static MachineInstr* getPrev(MachineInstr* N) { return N->prev; }
+ static MachineInstr* getNext(MachineInstr* N) { return N->next; }
+
+ static const MachineInstr*
+ getPrev(const MachineInstr* N) { return N->prev; }
+
+ static const MachineInstr*
+ getNext(const MachineInstr* N) { return N->next; }
+
+ static void setPrev(MachineInstr* N, MachineInstr* prev) { N->prev = prev; }
+ static void setNext(MachineInstr* N, MachineInstr* next) { N->next = next; }
+
+ static MachineInstr* createSentinel();
+ static void destroySentinel(MachineInstr *MI) { delete MI; }
+ void addNodeToList(MachineInstr* N);
+ void removeNodeFromList(MachineInstr* N);
+ void transferNodesFromList(
+ iplist<MachineInstr, ilist_traits<MachineInstr> >& toList,
+ ilist_iterator<MachineInstr> first,
+ ilist_iterator<MachineInstr> last);
+};
+
+class BasicBlock;
+
+class MachineBasicBlock {
+ typedef ilist<MachineInstr> Instructions;
+ Instructions Insts;
+ MachineBasicBlock *Prev, *Next;
+ const BasicBlock *BB;
+ int Number;
+ MachineFunction *Parent;
+
+ /// Predecessors/Successors - Keep track of the predecessor / successor
+ /// basicblocks.
+ std::vector<MachineBasicBlock *> Predecessors;
+ std::vector<MachineBasicBlock *> Successors;
+
+ /// LiveIns - Keep track of the physical registers that are livein of
+ /// the basicblock.
+ std::vector<unsigned> LiveIns;
+
+ /// IsLandingPad - Indicate that this basic block is entered via an
+ /// exception handler.
+ bool IsLandingPad;
+
+public:
+ explicit MachineBasicBlock(const BasicBlock *bb = 0) : Prev(0), Next(0),
+ BB(bb), Number(-1),
+ Parent(0),
+ IsLandingPad(false) {
+ Insts.parent = this;
+ }
+
+ ~MachineBasicBlock();
+
+ /// getBasicBlock - Return the LLVM basic block that this instance
+ /// corresponded to originally.
+ ///
+ const BasicBlock *getBasicBlock() const { return BB; }
+
+ /// getParent - Return the MachineFunction containing this basic block.
+ ///
+ const MachineFunction *getParent() const { return Parent; }
+ MachineFunction *getParent() { return Parent; }
+
+ typedef ilist<MachineInstr>::iterator iterator;
+ typedef ilist<MachineInstr>::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ unsigned size() const { return Insts.size(); }
+ bool empty() const { return Insts.empty(); }
+
+ MachineInstr& front() { return Insts.front(); }
+ MachineInstr& back() { return Insts.back(); }
+
+ iterator begin() { return Insts.begin(); }
+ const_iterator begin() const { return Insts.begin(); }
+ iterator end() { return Insts.end(); }
+ const_iterator end() const { return Insts.end(); }
+ reverse_iterator rbegin() { return Insts.rbegin(); }
+ const_reverse_iterator rbegin() const { return Insts.rbegin(); }
+ reverse_iterator rend () { return Insts.rend(); }
+ const_reverse_iterator rend () const { return Insts.rend(); }
+
+ // Machine-CFG iterators
+ typedef std::vector<MachineBasicBlock *>::iterator pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_pred_iterator;
+ typedef std::vector<MachineBasicBlock *>::iterator succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_iterator const_succ_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_pred_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::reverse_iterator
+ succ_reverse_iterator;
+ typedef std::vector<MachineBasicBlock *>::const_reverse_iterator
+ const_succ_reverse_iterator;
+
+ pred_iterator pred_begin() { return Predecessors.begin(); }
+ const_pred_iterator pred_begin() const { return Predecessors.begin(); }
+ pred_iterator pred_end() { return Predecessors.end(); }
+ const_pred_iterator pred_end() const { return Predecessors.end(); }
+ pred_reverse_iterator pred_rbegin()
+ { return Predecessors.rbegin();}
+ const_pred_reverse_iterator pred_rbegin() const
+ { return Predecessors.rbegin();}
+ pred_reverse_iterator pred_rend()
+ { return Predecessors.rend(); }
+ const_pred_reverse_iterator pred_rend() const
+ { return Predecessors.rend(); }
+ unsigned pred_size() const { return Predecessors.size(); }
+ bool pred_empty() const { return Predecessors.empty(); }
+ succ_iterator succ_begin() { return Successors.begin(); }
+ const_succ_iterator succ_begin() const { return Successors.begin(); }
+ succ_iterator succ_end() { return Successors.end(); }
+ const_succ_iterator succ_end() const { return Successors.end(); }
+ succ_reverse_iterator succ_rbegin()
+ { return Successors.rbegin(); }
+ const_succ_reverse_iterator succ_rbegin() const
+ { return Successors.rbegin(); }
+ succ_reverse_iterator succ_rend()
+ { return Successors.rend(); }
+ const_succ_reverse_iterator succ_rend() const
+ { return Successors.rend(); }
+ unsigned succ_size() const { return Successors.size(); }
+ bool succ_empty() const { return Successors.empty(); }
+
+ // LiveIn management methods.
+
+ /// addLiveIn - Add the specified register as a live in. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg) { LiveIns.push_back(Reg); }
+
+ /// removeLiveIn - Remove the specified register from the live in set.
+ ///
+ void removeLiveIn(unsigned Reg);
+
+ // Iteration support for live in sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<unsigned>::iterator livein_iterator;
+ typedef std::vector<unsigned>::const_iterator const_livein_iterator;
+ livein_iterator livein_begin() { return LiveIns.begin(); }
+ const_livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() { return LiveIns.end(); }
+ const_livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+
+ /// isLandingPad - Returns true if the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ bool isLandingPad() const { return IsLandingPad; }
+
+ /// setIsLandingPad - Indicates the block is a landing pad. That is
+ /// this basic block is entered via an exception handler.
+ void setIsLandingPad() { IsLandingPad = true; }
+
+ // Code Layout methods.
+
+ /// moveBefore/moveAfter - move 'this' block before or after the specified
+ /// block. This only moves the block, it does not modify the CFG or adjust
+ /// potential fall-throughs at the end of the block.
+ void moveBefore(MachineBasicBlock *NewAfter);
+ void moveAfter(MachineBasicBlock *NewBefore);
+
+ // Machine-CFG mutators
+
+ /// addSuccessor - Add succ as a successor of this MachineBasicBlock.
+ /// The Predecessors list of succ is automatically updated.
+ ///
+ void addSuccessor(MachineBasicBlock *succ);
+
+ /// removeSuccessor - Remove successor from the successors list of this
+ /// MachineBasicBlock. The Predecessors list of succ is automatically updated.
+ ///
+ void removeSuccessor(MachineBasicBlock *succ);
+
+ /// removeSuccessor - Remove specified successor from the successors list of
+ /// this MachineBasicBlock. The Predecessors list of succ is automatically
+ /// updated. Return the iterator to the element after the one removed.
+ ///
+ succ_iterator removeSuccessor(succ_iterator I);
+
+ /// isSuccessor - Return true if the specified MBB is a successor of this
+ /// block.
+ bool isSuccessor(MachineBasicBlock *MBB) const;
+
+ /// getFirstTerminator - returns an iterator to the first terminator
+ /// instruction of this basic block. If a terminator does not exist,
+ /// it returns end()
+ iterator getFirstTerminator();
+
+ void pop_front() { Insts.pop_front(); }
+ void pop_back() { Insts.pop_back(); }
+ void push_back(MachineInstr *MI) { Insts.push_back(MI); }
+ template<typename IT>
+ void insert(iterator I, IT S, IT E) { Insts.insert(I, S, E); }
+ iterator insert(iterator I, MachineInstr *M) { return Insts.insert(I, M); }
+
+ // erase - Remove the specified element or range from the instruction list.
+ // These functions delete any instructions removed.
+ //
+ iterator erase(iterator I) { return Insts.erase(I); }
+ iterator erase(iterator I, iterator E) { return Insts.erase(I, E); }
+ MachineInstr *remove(MachineInstr *I) { return Insts.remove(I); }
+ void clear() { Insts.clear(); }
+
+ /// splice - Take a block of instructions from MBB 'Other' in the range [From,
+ /// To), and insert them into this MBB right before 'where'.
+ void splice(iterator where, MachineBasicBlock *Other, iterator From,
+ iterator To) {
+ Insts.splice(where, Other->Insts, From, To);
+ }
+
+ /// ReplaceUsesOfBlockWith - Given a machine basic block that branched to
+ /// 'Old', change the code and CFG so that it branches to 'New' instead.
+ void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New);
+
+ /// CorrectExtraCFGEdges - Various pieces of code can cause excess edges in
+ /// the CFG to be inserted. If we have proven that MBB can only branch to
+ /// DestA and DestB, remove any other MBB successors from the CFG. DestA and
+ /// DestB can be null. Besides DestA and DestB, retain other edges leading
+ /// to LandingPads (currently there can be only one; we don't check or require
+ /// that here). Note it is possible that DestA and/or DestB are LandingPads.
+ bool CorrectExtraCFGEdges(MachineBasicBlock *DestA,
+ MachineBasicBlock *DestB,
+ bool isCond);
+
+ // Debugging methods.
+ void dump() const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// getNumber - MachineBasicBlocks are uniquely numbered at the function
+ /// level, unless they're not in a MachineFunction yet, in which case this
+ /// will return -1.
+ ///
+ int getNumber() const { return Number; }
+ void setNumber(int N) { Number = N; }
+
+private: // Methods used to maintain doubly linked list of blocks...
+ friend struct ilist_traits<MachineBasicBlock>;
+
+ MachineBasicBlock *getPrev() const { return Prev; }
+ MachineBasicBlock *getNext() const { return Next; }
+ void setPrev(MachineBasicBlock *P) { Prev = P; }
+ void setNext(MachineBasicBlock *N) { Next = N; }
+
+ // Machine-CFG mutators
+
+ /// addPredecessor - Remove pred as a predecessor of this MachineBasicBlock.
+ /// Don't do this unless you know what you're doing, because it doesn't
+ /// update pred's successors list. Use pred->addSuccessor instead.
+ ///
+ void addPredecessor(MachineBasicBlock *pred);
+
+ /// removePredecessor - Remove pred as a predecessor of this
+ /// MachineBasicBlock. Don't do this unless you know what you're
+ /// doing, because it doesn't update pred's successors list. Use
+ /// pred->removeSuccessor instead.
+ ///
+ void removePredecessor(MachineBasicBlock *pred);
+};
+
+std::ostream& operator<<(std::ostream &OS, const MachineBasicBlock &MBB);
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for machine basic block graphs (machine-CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks...
+//
+
+template <> struct GraphTraits<MachineBasicBlock *> {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+template <> struct GraphTraits<const MachineBasicBlock *> {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const MachineBasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->succ_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->succ_end();
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a
+// MachineFunction as a graph of MachineBasicBlocks... and to walk it
+// in inverse order. Inverse order for a function is considered
+// to be when traversing the predecessor edges of a MBB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineBasicBlock*> > {
+ typedef MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<MachineBasicBlock *> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+template <> struct GraphTraits<Inverse<const MachineBasicBlock*> > {
+ typedef const MachineBasicBlock NodeType;
+ typedef MachineBasicBlock::const_pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const MachineBasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->pred_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->pred_end();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h
new file mode 100644
index 0000000..018c5e5
--- /dev/null
+++ b/include/llvm/CodeGen/MachineCodeEmitter.h
@@ -0,0 +1,200 @@
+//===-- llvm/CodeGen/MachineCodeEmitter.h - Code emission -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines an abstract interface that is used by the machine code
+// emission framework to output the code. This allows machine code emission to
+// be separated from concerns such as resolution of call targets, and where the
+// machine code will be written (memory or disk, f.e.).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECODEEMITTER_H
+#define LLVM_CODEGEN_MACHINECODEEMITTER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+class MachineFunction;
+class MachineRelocation;
+class Value;
+class GlobalValue;
+class Function;
+
+/// MachineCodeEmitter - This class defines two sorts of methods: those for
+/// emitting the actual bytes of machine code, and those for emitting auxillary
+/// structures, such as jump tables, relocations, etc.
+///
+/// Emission of machine code is complicated by the fact that we don't (in
+/// general) know the size of the machine code that we're about to emit before
+/// we emit it. As such, we preallocate a certain amount of memory, and set the
+/// BufferBegin/BufferEnd pointers to the start and end of the buffer. As we
+/// emit machine instructions, we advance the CurBufferPtr to indicate the
+/// location of the next byte to emit. In the case of a buffer overflow (we
+/// need to emit more machine code than we have allocated space for), the
+/// CurBufferPtr will saturate to BufferEnd and ignore stores. Once the entire
+/// function has been emitted, the overflow condition is checked, and if it has
+/// occurred, more memory is allocated, and we reemit the code into it.
+///
+class MachineCodeEmitter {
+protected:
+ /// BufferBegin/BufferEnd - Pointers to the start and end of the memory
+ /// allocated for this code buffer.
+ unsigned char *BufferBegin, *BufferEnd;
+
+ /// CurBufferPtr - Pointer to the next byte of memory to fill when emitting
+ /// code. This is guranteed to be in the range [BufferBegin,BufferEnd]. If
+ /// this pointer is at BufferEnd, it will never move due to code emission, and
+ /// all code emission requests will be ignored (this is the buffer overflow
+ /// condition).
+ unsigned char *CurBufferPtr;
+public:
+ virtual ~MachineCodeEmitter() {}
+
+ /// startFunction - This callback is invoked when the specified function is
+ /// about to be code generated. This initializes the BufferBegin/End/Ptr
+ /// fields.
+ ///
+ virtual void startFunction(MachineFunction &F) = 0;
+
+ /// finishFunction - This callback is invoked when the specified function has
+ /// finished code generation. If a buffer overflow has occurred, this method
+ /// returns true (the callee is required to try again), otherwise it returns
+ /// false.
+ ///
+ virtual bool finishFunction(MachineFunction &F) = 0;
+
+ /// startFunctionStub - This callback is invoked when the JIT needs the
+ /// address of a function that has not been code generated yet. The StubSize
+ /// specifies the total size required by the stub. Stubs are not allowed to
+ /// have constant pools, the can only use the other emitByte*/emitWord*
+ /// methods.
+ ///
+ virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) = 0;
+
+ /// finishFunctionStub - This callback is invoked to terminate a function
+ /// stub.
+ ///
+ virtual void *finishFunctionStub(const Function *F) = 0;
+
+ /// emitByte - This callback is invoked when a byte needs to be written to the
+ /// output stream.
+ ///
+ void emitByte(unsigned char B) {
+ if (CurBufferPtr != BufferEnd)
+ *CurBufferPtr++ = B;
+ }
+
+ /// emitWordLE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in little-endian format.
+ ///
+ void emitWordLE(unsigned W) {
+ if (CurBufferPtr+4 <= BufferEnd) {
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitWordBE - This callback is invoked when a 32-bit word needs to be
+ /// written to the output stream in big-endian format.
+ ///
+ void emitWordBE(unsigned W) {
+ if (CurBufferPtr+4 <= BufferEnd) {
+ *CurBufferPtr++ = (unsigned char)(W >> 24);
+ *CurBufferPtr++ = (unsigned char)(W >> 16);
+ *CurBufferPtr++ = (unsigned char)(W >> 8);
+ *CurBufferPtr++ = (unsigned char)(W >> 0);
+ } else {
+ CurBufferPtr = BufferEnd;
+ }
+ }
+
+ /// emitAlignment - Move the CurBufferPtr pointer up the the specified
+ /// alignment (saturated to BufferEnd of course).
+ void emitAlignment(unsigned Alignment) {
+ if (Alignment == 0) Alignment = 1;
+ // Move the current buffer ptr up to the specified alignment.
+ CurBufferPtr =
+ (unsigned char*)(((intptr_t)CurBufferPtr+Alignment-1) &
+ ~(intptr_t)(Alignment-1));
+ if (CurBufferPtr > BufferEnd)
+ CurBufferPtr = BufferEnd;
+ }
+
+ /// allocateSpace - Allocate a block of space in the current output buffer,
+ /// returning null (and setting conditions to indicate buffer overflow) on
+ /// failure. Alignment is the alignment in bytes of the buffer desired.
+ void *allocateSpace(intptr_t Size, unsigned Alignment) {
+ emitAlignment(Alignment);
+ void *Result = CurBufferPtr;
+
+ // Allocate the space.
+ CurBufferPtr += Size;
+
+ // Check for buffer overflow.
+ if (CurBufferPtr >= BufferEnd) {
+ CurBufferPtr = BufferEnd;
+ Result = 0;
+ }
+ return Result;
+ }
+
+ /// StartMachineBasicBlock - This should be called by the target when a new
+ /// basic block is about to be emitted. This way the MCE knows where the
+ /// start of the block is, and can implement getMachineBasicBlockAddress.
+ virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0;
+
+ /// getCurrentPCValue - This returns the address that the next emitted byte
+ /// will be output to.
+ ///
+ virtual intptr_t getCurrentPCValue() const {
+ return (intptr_t)CurBufferPtr;
+ }
+
+ /// getCurrentPCOffset - Return the offset from the start of the emitted
+ /// buffer that we are currently writing to.
+ intptr_t getCurrentPCOffset() const {
+ return CurBufferPtr-BufferBegin;
+ }
+
+ /// addRelocation - Whenever a relocatable address is needed, it should be
+ /// noted with this interface.
+ virtual void addRelocation(const MachineRelocation &MR) = 0;
+
+
+ /// FIXME: These should all be handled with relocations!
+
+ /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
+ /// the constant pool that was last emitted with the emitConstantPool method.
+ ///
+ virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const = 0;
+
+ /// getJumpTableEntryAddress - Return the address of the jump table with index
+ /// 'Index' in the function that last called initJumpTableInfo.
+ ///
+ virtual intptr_t getJumpTableEntryAddress(unsigned Index) const = 0;
+
+ /// getMachineBasicBlockAddress - Return the address of the specified
+ /// MachineBasicBlock, only usable after the label for the MBB has been
+ /// emitted.
+ ///
+ virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineConstantPool.h b/include/llvm/CodeGen/MachineConstantPool.h
new file mode 100644
index 0000000..1500053
--- /dev/null
+++ b/include/llvm/CodeGen/MachineConstantPool.h
@@ -0,0 +1,149 @@
+//===-- CodeGen/MachineConstantPool.h - Abstract Constant Pool --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file This file declares the MachineConstantPool class which is an abstract
+/// constant pool to keep track of constants referenced by a function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+#define LLVM_CODEGEN_MACHINECONSTANTPOOL_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+
+class AsmPrinter;
+class Constant;
+class TargetData;
+class TargetMachine;
+class MachineConstantPool;
+
+/// Abstract base class for all machine specific constantpool value subclasses.
+///
+class MachineConstantPoolValue {
+ const Type *Ty;
+
+public:
+ explicit MachineConstantPoolValue(const Type *ty) : Ty(ty) {}
+ virtual ~MachineConstantPoolValue() {};
+
+ /// getType - get type of this MachineConstantPoolValue.
+ ///
+ inline const Type *getType() const { return Ty; }
+
+ virtual int getExistingMachineCPValue(MachineConstantPool *CP,
+ unsigned Alignment) = 0;
+
+ virtual void AddSelectionDAGCSEId(FoldingSetNodeID &ID) = 0;
+
+ /// print - Implement operator<<...
+ ///
+ virtual void print(std::ostream &O) const = 0;
+ void print(std::ostream *O) const { if (O) print(*O); }
+};
+
+inline std::ostream &operator<<(std::ostream &OS,
+ const MachineConstantPoolValue &V) {
+ V.print(OS);
+ return OS;
+}
+
+/// This class is a data container for one entry in a MachineConstantPool.
+/// It contains a pointer to the value and an offset from the start of
+/// the constant pool.
+/// @brief An entry in a MachineConstantPool
+class MachineConstantPoolEntry {
+public:
+ /// The constant itself.
+ union {
+ Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+
+ /// The offset of the constant from the start of the pool. The top bit is set
+ /// when Val is a MachineConstantPoolValue.
+ unsigned Offset;
+
+ MachineConstantPoolEntry(Constant *V, unsigned O)
+ : Offset(O) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = V;
+ }
+ MachineConstantPoolEntry(MachineConstantPoolValue *V, unsigned O)
+ : Offset(O){
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = V;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+
+ bool isMachineConstantPoolEntry() const {
+ return (int)Offset < 0;
+ }
+
+ int getOffset() const {
+ return Offset & ~(1 << (sizeof(unsigned)*8-1));
+ }
+
+ const Type *getType() const;
+};
+
+/// The MachineConstantPool class keeps track of constants referenced by a
+/// function which must be spilled to memory. This is used for constants which
+/// are unable to be used directly as operands to instructions, which typically
+/// include floating point and large integer constants.
+///
+/// Instructions reference the address of these constant pool constants through
+/// the use of MO_ConstantPoolIndex values. When emitting assembly or machine
+/// code, these virtual address references are converted to refer to the
+/// address of the function constant pool values.
+/// @brief The machine constant pool.
+class MachineConstantPool {
+ const TargetData *TD; ///< The machine's TargetData.
+ unsigned PoolAlignment; ///< The alignment for the pool.
+ std::vector<MachineConstantPoolEntry> Constants; ///< The pool of constants.
+public:
+ /// @brief The only constructor.
+ MachineConstantPool(const TargetData *td) : TD(td), PoolAlignment(1) {}
+ ~MachineConstantPool();
+
+ /// getConstantPoolAlignment - Return the log2 of the alignment required by
+ /// the whole constant pool, of which the first element must be aligned.
+ unsigned getConstantPoolAlignment() const { return PoolAlignment; }
+
+ /// getConstantPoolIndex - Create a new entry in the constant pool or return
+ /// an existing one. User must specify an alignment in bytes for the object.
+ unsigned getConstantPoolIndex(Constant *C, unsigned Alignment);
+ unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
+
+ /// isEmpty - Return true if this constant pool contains no constants.
+ bool isEmpty() const { return Constants.empty(); }
+
+ const std::vector<MachineConstantPoolEntry> &getConstants() const {
+ return Constants;
+ }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// constant pool objects. Implemented in MachineFunction.cpp
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Call print(std::cerr) to be called from the debugger.
+ ///
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFrameInfo.h b/include/llvm/CodeGen/MachineFrameInfo.h
new file mode 100644
index 0000000..be481f7
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFrameInfo.h
@@ -0,0 +1,327 @@
+//===-- CodeGen/MachineFrameInfo.h - Abstract Stack Frame Rep. --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHINEFRAMEINFO_H
+#define LLVM_CODEGEN_MACHINEFRAMEINFO_H
+
+#include <vector>
+
+namespace llvm {
+class TargetData;
+class TargetRegisterClass;
+class Type;
+class MachineModuleInfo;
+class MachineFunction;
+
+/// The CalleeSavedInfo class tracks the information need to locate where a
+/// callee saved register in the current frame.
+class CalleeSavedInfo {
+
+private:
+ unsigned Reg;
+ const TargetRegisterClass *RegClass;
+ int FrameIdx;
+
+public:
+ CalleeSavedInfo(unsigned R, const TargetRegisterClass *RC, int FI = 0)
+ : Reg(R)
+ , RegClass(RC)
+ , FrameIdx(FI)
+ {}
+
+ // Accessors.
+ unsigned getReg() const { return Reg; }
+ const TargetRegisterClass *getRegClass() const { return RegClass; }
+ int getFrameIdx() const { return FrameIdx; }
+ void setFrameIdx(int FI) { FrameIdx = FI; }
+};
+
+/// The MachineFrameInfo class represents an abstract stack frame until
+/// prolog/epilog code is inserted. This class is key to allowing stack frame
+/// representation optimizations, such as frame pointer elimination. It also
+/// allows more mundane (but still important) optimizations, such as reordering
+/// of abstract objects on the stack frame.
+///
+/// To support this, the class assigns unique integer identifiers to stack
+/// objects requested clients. These identifiers are negative integers for
+/// fixed stack objects (such as arguments passed on the stack) or positive
+/// for objects that may be reordered. Instructions which refer to stack
+/// objects use a special MO_FrameIndex operand to represent these frame
+/// indexes.
+///
+/// Because this class keeps track of all references to the stack frame, it
+/// knows when a variable sized object is allocated on the stack. This is the
+/// sole condition which prevents frame pointer elimination, which is an
+/// important optimization on register-poor architectures. Because original
+/// variable sized alloca's in the source program are the only source of
+/// variable sized stack objects, it is safe to decide whether there will be
+/// any variable sized objects before all stack objects are known (for
+/// example, register allocator spill code never needs variable sized
+/// objects).
+///
+/// When prolog/epilog code emission is performed, the final stack frame is
+/// built and the machine instructions are modified to refer to the actual
+/// stack offsets of the object, eliminating all MO_FrameIndex operands from
+/// the program.
+///
+/// @brief Abstract Stack Frame Information
+class MachineFrameInfo {
+
+ // StackObject - Represent a single object allocated on the stack.
+ struct StackObject {
+ // The size of this object on the stack. 0 means a variable sized object
+ uint64_t Size;
+
+ // Alignment - The required alignment of this stack slot.
+ unsigned Alignment;
+
+ // SPOffset - The offset of this object from the stack pointer on entry to
+ // the function. This field has no meaning for a variable sized element.
+ int64_t SPOffset;
+
+ StackObject(uint64_t Sz, unsigned Al, int64_t SP)
+ : Size(Sz), Alignment(Al), SPOffset(SP) {}
+ };
+
+ /// Objects - The list of stack objects allocated...
+ ///
+ std::vector<StackObject> Objects;
+
+ /// NumFixedObjects - This contains the number of fixed objects contained on
+ /// the stack. Because fixed objects are stored at a negative index in the
+ /// Objects list, this is also the index to the 0th object in the list.
+ ///
+ unsigned NumFixedObjects;
+
+ /// HasVarSizedObjects - This boolean keeps track of whether any variable
+ /// sized objects have been allocated yet.
+ ///
+ bool HasVarSizedObjects;
+
+ /// StackSize - The prolog/epilog code inserter calculates the final stack
+ /// offsets for all of the fixed size objects, updating the Objects list
+ /// above. It then updates StackSize to contain the number of bytes that need
+ /// to be allocated on entry to the function.
+ ///
+ uint64_t StackSize;
+
+ /// OffsetAdjustment - The amount that a frame offset needs to be adjusted to
+ /// have the actual offset from the stack/frame pointer. The calculation is
+ /// MFI->getObjectOffset(Index) + StackSize - TFI.getOffsetOfLocalArea() +
+ /// OffsetAdjustment. If OffsetAdjustment is zero (default) then offsets are
+ /// away from TOS. If OffsetAdjustment == StackSize then offsets are toward
+ /// TOS.
+ int OffsetAdjustment;
+
+ /// MaxAlignment - The prolog/epilog code inserter may process objects
+ /// that require greater alignment than the default alignment the target
+ /// provides. To handle this, MaxAlignment is set to the maximum alignment
+ /// needed by the objects on the current frame. If this is greater than the
+ /// native alignment maintained by the compiler, dynamic alignment code will
+ /// be needed.
+ ///
+ unsigned MaxAlignment;
+
+ /// HasCalls - Set to true if this function has any function calls. This is
+ /// only valid during and after prolog/epilog code insertion.
+ bool HasCalls;
+
+ /// MaxCallFrameSize - This contains the size of the largest call frame if the
+ /// target uses frame setup/destroy pseudo instructions (as defined in the
+ /// TargetFrameInfo class). This information is important for frame pointer
+ /// elimination. If is only valid during and after prolog/epilog code
+ /// insertion.
+ ///
+ unsigned MaxCallFrameSize;
+
+ /// CSInfo - The prolog/epilog code inserter fills in this vector with each
+ /// callee saved register saved in the frame. Beyond its use by the prolog/
+ /// epilog code inserter, this data used for debug info and exception
+ /// handling.
+ std::vector<CalleeSavedInfo> CSInfo;
+
+ /// MMI - This field is set (via setMachineModuleInfo) by a module info
+ /// consumer (ex. DwarfWriter) to indicate that frame layout information
+ /// should be acquired. Typically, it's the responsibility of the target's
+ /// MRegisterInfo prologue/epilogue emitting code to inform MachineModuleInfo
+ /// of frame layouts.
+ MachineModuleInfo *MMI;
+
+public:
+ MachineFrameInfo() {
+ StackSize = NumFixedObjects = OffsetAdjustment = MaxAlignment = 0;
+ HasVarSizedObjects = false;
+ HasCalls = false;
+ MaxCallFrameSize = 0;
+ MMI = 0;
+ }
+
+ /// hasStackObjects - Return true if there are any stack objects in this
+ /// function.
+ ///
+ bool hasStackObjects() const { return !Objects.empty(); }
+
+ /// hasVarSizedObjects - This method may be called any time after instruction
+ /// selection is complete to determine if the stack frame for this function
+ /// contains any variable sized objects.
+ ///
+ bool hasVarSizedObjects() const { return HasVarSizedObjects; }
+
+ /// getObjectIndexBegin - Return the minimum frame object index...
+ ///
+ int getObjectIndexBegin() const { return -NumFixedObjects; }
+
+ /// getObjectIndexEnd - Return one past the maximum frame object index...
+ ///
+ int getObjectIndexEnd() const { return Objects.size()-NumFixedObjects; }
+
+ /// getObjectSize - Return the size of the specified object
+ ///
+ int64_t getObjectSize(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Size;
+ }
+
+ /// getObjectAlignment - Return the alignment of the specified stack object...
+ int getObjectAlignment(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].Alignment;
+ }
+
+ /// getObjectOffset - Return the assigned stack offset of the specified object
+ /// from the incoming stack pointer.
+ ///
+ int64_t getObjectOffset(int ObjectIdx) const {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ return Objects[ObjectIdx+NumFixedObjects].SPOffset;
+ }
+
+ /// setObjectOffset - Set the stack frame offset of the specified object. The
+ /// offset is relative to the stack pointer on entry to the function.
+ ///
+ void setObjectOffset(int ObjectIdx, int64_t SPOffset) {
+ assert(ObjectIdx+NumFixedObjects < Objects.size() && "Invalid Object Idx!");
+ Objects[ObjectIdx+NumFixedObjects].SPOffset = SPOffset;
+ }
+
+ /// getStackSize - Return the number of bytes that must be allocated to hold
+ /// all of the fixed size frame objects. This is only valid after
+ /// Prolog/Epilog code insertion has finalized the stack frame layout.
+ ///
+ uint64_t getStackSize() const { return StackSize; }
+
+ /// setStackSize - Set the size of the stack...
+ ///
+ void setStackSize(uint64_t Size) { StackSize = Size; }
+
+ /// getOffsetAdjustment - Return the correction for frame offsets.
+ ///
+ int getOffsetAdjustment() const { return OffsetAdjustment; }
+
+ /// setOffsetAdjustment - Set the correction for frame offsets.
+ ///
+ void setOffsetAdjustment(int Adj) { OffsetAdjustment = Adj; }
+
+ /// getMaxAlignment - Return the alignment in bytes that this function must be
+ /// aligned to, which is greater than the default stack alignment provided by
+ /// the target.
+ ///
+ unsigned getMaxAlignment() const { return MaxAlignment; }
+
+ /// setMaxAlignment - Set the preferred alignment.
+ ///
+ void setMaxAlignment(unsigned Align) { MaxAlignment = Align; }
+
+ /// hasCalls - Return true if the current function has no function calls.
+ /// This is only valid during or after prolog/epilog code emission.
+ ///
+ bool hasCalls() const { return HasCalls; }
+ void setHasCalls(bool V) { HasCalls = V; }
+
+ /// getMaxCallFrameSize - Return the maximum size of a call frame that must be
+ /// allocated for an outgoing function call. This is only available if
+ /// CallFrameSetup/Destroy pseudo instructions are used by the target, and
+ /// then only during or after prolog/epilog code insertion.
+ ///
+ unsigned getMaxCallFrameSize() const { return MaxCallFrameSize; }
+ void setMaxCallFrameSize(unsigned S) { MaxCallFrameSize = S; }
+
+ /// CreateFixedObject - Create a new object at a fixed location on the stack.
+ /// All fixed objects should be created before other objects are created for
+ /// efficiency. This returns an index with a negative value.
+ ///
+ int CreateFixedObject(uint64_t Size, int64_t SPOffset) {
+ assert(Size != 0 && "Cannot allocate zero size fixed stack objects!");
+ Objects.insert(Objects.begin(), StackObject(Size, 1, SPOffset));
+ return -++NumFixedObjects;
+ }
+
+ /// isFixedObjectIndex - Returns true if the specified index corresponds to a
+ /// fixed stack object.
+ bool isFixedObjectIndex(int ObjectIdx) const {
+ return ObjectIdx < 0 && (ObjectIdx >= -(int)NumFixedObjects);
+ }
+
+ /// CreateStackObject - Create a new statically sized stack object, returning
+ /// a postive identifier to represent it.
+ ///
+ int CreateStackObject(uint64_t Size, unsigned Alignment) {
+ // Keep track of the maximum alignment.
+ if (MaxAlignment < Alignment) MaxAlignment = Alignment;
+
+ assert(Size != 0 && "Cannot allocate zero size stack objects!");
+ Objects.push_back(StackObject(Size, Alignment, -1));
+ return Objects.size()-NumFixedObjects-1;
+ }
+
+ /// CreateVariableSizedObject - Notify the MachineFrameInfo object that a
+ /// variable sized object has been created. This must be created whenever a
+ /// variable sized object is created, whether or not the index returned is
+ /// actually used.
+ ///
+ int CreateVariableSizedObject() {
+ HasVarSizedObjects = true;
+ if (MaxAlignment < 1) MaxAlignment = 1;
+ Objects.push_back(StackObject(0, 1, -1));
+ return Objects.size()-NumFixedObjects-1;
+ }
+
+ /// getCalleeSavedInfo - Returns a reference to call saved info vector for the
+ /// current function.
+ const std::vector<CalleeSavedInfo> &getCalleeSavedInfo() const {
+ return CSInfo;
+ }
+
+ /// setCalleeSavedInfo - Used by prolog/epilog inserter to set the function's
+ /// callee saved information.
+ void setCalleeSavedInfo(const std::vector<CalleeSavedInfo> &CSI) {
+ CSInfo = CSI;
+ }
+
+ /// getMachineModuleInfo - Used by a prologue/epilogue emitter (MRegisterInfo)
+ /// to provide frame layout information.
+ MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
+
+ /// setMachineModuleInfo - Used by a meta info consumer (DwarfWriter) to
+ /// indicate that frame layout information should be gathered.
+ void setMachineModuleInfo(MachineModuleInfo *mmi) { MMI = mmi; }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// stack objects. Implemented in MachineFunction.cpp
+ ///
+ void print(const MachineFunction &MF, std::ostream &OS) const;
+
+ /// dump - Call print(MF, std::cerr) to be called from the debugger.
+ void dump(const MachineFunction &MF) const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunction.h b/include/llvm/CodeGen/MachineFunction.h
new file mode 100644
index 0000000..00a1fe8
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunction.h
@@ -0,0 +1,374 @@
+//===-- llvm/CodeGen/MachineFunction.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect native machine code for a function. This class contains a list of
+// MachineBasicBlock instances that make up the current compiled function.
+//
+// This class also contains pointers to various classes which hold
+// target-specific information about the generated code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEFUNCTION_H
+#define LLVM_CODEGEN_MACHINEFUNCTION_H
+
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Support/Annotation.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace llvm {
+
+class Function;
+class TargetMachine;
+class SSARegMap;
+class MachineFrameInfo;
+class MachineConstantPool;
+class MachineJumpTableInfo;
+
+// ilist_traits
+template <>
+struct ilist_traits<MachineBasicBlock> {
+ // this is only set by the MachineFunction owning the ilist
+ friend class MachineFunction;
+ MachineFunction* Parent;
+
+public:
+ ilist_traits<MachineBasicBlock>() : Parent(0) { }
+
+ static MachineBasicBlock* getPrev(MachineBasicBlock* N) { return N->Prev; }
+ static MachineBasicBlock* getNext(MachineBasicBlock* N) { return N->Next; }
+
+ static const MachineBasicBlock*
+ getPrev(const MachineBasicBlock* N) { return N->Prev; }
+
+ static const MachineBasicBlock*
+ getNext(const MachineBasicBlock* N) { return N->Next; }
+
+ static void setPrev(MachineBasicBlock* N, MachineBasicBlock* prev) {
+ N->Prev = prev;
+ }
+ static void setNext(MachineBasicBlock* N, MachineBasicBlock* next) {
+ N->Next = next;
+ }
+
+ static MachineBasicBlock* createSentinel();
+ static void destroySentinel(MachineBasicBlock *MBB) { delete MBB; }
+ void addNodeToList(MachineBasicBlock* N);
+ void removeNodeFromList(MachineBasicBlock* N);
+ void transferNodesFromList(iplist<MachineBasicBlock,
+ ilist_traits<MachineBasicBlock> > &toList,
+ ilist_iterator<MachineBasicBlock> first,
+ ilist_iterator<MachineBasicBlock> last);
+};
+
+/// MachineFunctionInfo - This class can be derived from and used by targets to
+/// hold private target-specific information for each MachineFunction. Objects
+/// of type are accessed/created with MF::getInfo and destroyed when the
+/// MachineFunction is destroyed.
+struct MachineFunctionInfo {
+ virtual ~MachineFunctionInfo() {};
+};
+
+class MachineFunction : private Annotation {
+ const Function *Fn;
+ const TargetMachine &Target;
+
+ // List of machine basic blocks in function
+ ilist<MachineBasicBlock> BasicBlocks;
+
+ // Keeping track of mapping from SSA values to registers
+ SSARegMap *SSARegMapping;
+
+ // Used to keep track of target-specific per-machine function information for
+ // the target implementation.
+ MachineFunctionInfo *MFInfo;
+
+ // Keep track of objects allocated on the stack.
+ MachineFrameInfo *FrameInfo;
+
+ // Keep track of constants which are spilled to memory
+ MachineConstantPool *ConstantPool;
+
+ // Keep track of jump tables for switch instructions
+ MachineJumpTableInfo *JumpTableInfo;
+
+ // Function-level unique numbering for MachineBasicBlocks. When a
+ // MachineBasicBlock is inserted into a MachineFunction is it automatically
+ // numbered and this vector keeps track of the mapping from ID's to MBB's.
+ std::vector<MachineBasicBlock*> MBBNumbering;
+
+ /// UsedPhysRegs - This is a bit vector that is computed and set by the
+ /// register allocator, and must be kept up to date by passes that run after
+ /// register allocation (though most don't modify this). This is used
+ /// so that the code generator knows which callee save registers to save and
+ /// for other target specific uses.
+ BitVector UsedPhysRegs;
+
+ /// LiveIns/LiveOuts - Keep track of the physical registers that are
+ /// livein/liveout of the function. Live in values are typically arguments in
+ /// registers, live out values are typically return values in registers.
+ /// LiveIn values are allowed to have virtual registers associated with them,
+ /// stored in the second element.
+ std::vector<std::pair<unsigned, unsigned> > LiveIns;
+ std::vector<unsigned> LiveOuts;
+
+public:
+ MachineFunction(const Function *Fn, const TargetMachine &TM);
+ ~MachineFunction();
+
+ /// getFunction - Return the LLVM function that this machine code represents
+ ///
+ const Function *getFunction() const { return Fn; }
+
+ /// getTarget - Return the target machine this machine code is compiled with
+ ///
+ const TargetMachine &getTarget() const { return Target; }
+
+ /// SSARegMap Interface... Keep track of information about each SSA virtual
+ /// register, such as which register class it belongs to.
+ ///
+ SSARegMap *getSSARegMap() const { return SSARegMapping; }
+ void clearSSARegMap();
+
+ /// getFrameInfo - Return the frame info object for the current function.
+ /// This object contains information about objects allocated on the stack
+ /// frame of the current function in an abstract way.
+ ///
+ MachineFrameInfo *getFrameInfo() const { return FrameInfo; }
+
+ /// getJumpTableInfo - Return the jump table info object for the current
+ /// function. This object contains information about jump tables for switch
+ /// instructions in the current function.
+ ///
+ MachineJumpTableInfo *getJumpTableInfo() const { return JumpTableInfo; }
+
+ /// getConstantPool - Return the constant pool object for the current
+ /// function.
+ ///
+ MachineConstantPool *getConstantPool() const { return ConstantPool; }
+
+ /// MachineFunctionInfo - Keep track of various per-function pieces of
+ /// information for backends that would like to do so.
+ ///
+ template<typename Ty>
+ Ty *getInfo() {
+ if (!MFInfo) MFInfo = new Ty(*this);
+
+ assert((void*)dynamic_cast<Ty*>(MFInfo) == (void*)MFInfo &&
+ "Invalid concrete type or multiple inheritence for getInfo");
+ return static_cast<Ty*>(MFInfo);
+ }
+
+ template<typename Ty>
+ const Ty *getInfo() const {
+ return const_cast<MachineFunction*>(this)->getInfo<Ty>();
+ }
+
+ /// isPhysRegUsed - Return true if the specified register is used in this
+ /// function. This only works after register allocation.
+ bool isPhysRegUsed(unsigned Reg) const { return UsedPhysRegs[Reg]; }
+
+ /// setPhysRegUsed - Mark the specified register used in this function.
+ /// This should only be called during and after register allocation.
+ void setPhysRegUsed(unsigned Reg) { UsedPhysRegs[Reg] = true; }
+
+ /// setPhysRegUnused - Mark the specified register unused in this function.
+ /// This should only be called during and after register allocation.
+ void setPhysRegUnused(unsigned Reg) { UsedPhysRegs[Reg] = false; }
+
+ // LiveIn/LiveOut management methods.
+
+ /// addLiveIn/Out - Add the specified register as a live in/out. Note that it
+ /// is an error to add the same register to the same set more than once.
+ void addLiveIn(unsigned Reg, unsigned vreg = 0) {
+ LiveIns.push_back(std::make_pair(Reg, vreg));
+ }
+ void addLiveOut(unsigned Reg) { LiveOuts.push_back(Reg); }
+
+ // Iteration support for live in/out sets. These sets are kept in sorted
+ // order by their register number.
+ typedef std::vector<std::pair<unsigned,unsigned> >::const_iterator
+ livein_iterator;
+ typedef std::vector<unsigned>::const_iterator liveout_iterator;
+ livein_iterator livein_begin() const { return LiveIns.begin(); }
+ livein_iterator livein_end() const { return LiveIns.end(); }
+ bool livein_empty() const { return LiveIns.empty(); }
+ liveout_iterator liveout_begin() const { return LiveOuts.begin(); }
+ liveout_iterator liveout_end() const { return LiveOuts.end(); }
+ bool liveout_empty() const { return LiveOuts.empty(); }
+
+ /// getBlockNumbered - MachineBasicBlocks are automatically numbered when they
+ /// are inserted into the machine function. The block number for a machine
+ /// basic block can be found by using the MBB::getBlockNumber method, this
+ /// method provides the inverse mapping.
+ ///
+ MachineBasicBlock *getBlockNumbered(unsigned N) {
+ assert(N < MBBNumbering.size() && "Illegal block number");
+ assert(MBBNumbering[N] && "Block was removed from the machine function!");
+ return MBBNumbering[N];
+ }
+
+ /// getNumBlockIDs - Return the number of MBB ID's allocated.
+ ///
+ unsigned getNumBlockIDs() const { return MBBNumbering.size(); }
+
+ /// RenumberBlocks - This discards all of the MachineBasicBlock numbers and
+ /// recomputes them. This guarantees that the MBB numbers are sequential,
+ /// dense, and match the ordering of the blocks within the function. If a
+ /// specific MachineBasicBlock is specified, only that block and those after
+ /// it are renumbered.
+ void RenumberBlocks(MachineBasicBlock *MBBFrom = 0);
+
+ /// print - Print out the MachineFunction in a format suitable for debugging
+ /// to the specified stream.
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// viewCFG - This function is meant for use from the debugger. You can just
+ /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+ /// program, displaying the CFG of the current function with the code for each
+ /// basic block inside. This depends on there being a 'dot' and 'gv' program
+ /// in your path.
+ ///
+ void viewCFG() const;
+
+ /// viewCFGOnly - This function is meant for use from the debugger. It works
+ /// just like viewCFG, but it does not include the contents of basic blocks
+ /// into the nodes, just the label. If you are only interested in the CFG
+ /// this can make the graph smaller.
+ ///
+ void viewCFGOnly() const;
+
+ /// dump - Print the current MachineFunction to cerr, useful for debugger use.
+ ///
+ void dump() const;
+
+ /// construct - Allocate and initialize a MachineFunction for a given Function
+ /// and Target
+ ///
+ static MachineFunction& construct(const Function *F, const TargetMachine &TM);
+
+ /// destruct - Destroy the MachineFunction corresponding to a given Function
+ ///
+ static void destruct(const Function *F);
+
+ /// get - Return a handle to a MachineFunction corresponding to the given
+ /// Function. This should not be called before "construct()" for a given
+ /// Function.
+ ///
+ static MachineFunction& get(const Function *F);
+
+ // Provide accessors for the MachineBasicBlock list...
+ typedef ilist<MachineBasicBlock> BasicBlockListType;
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+
+ // Provide accessors for basic blocks...
+ const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
+ BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
+
+ //===--------------------------------------------------------------------===//
+ // BasicBlock iterator forwarding functions
+ //
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ reverse_iterator rbegin() { return BasicBlocks.rbegin(); }
+ const_reverse_iterator rbegin() const { return BasicBlocks.rbegin(); }
+ reverse_iterator rend () { return BasicBlocks.rend(); }
+ const_reverse_iterator rend () const { return BasicBlocks.rend(); }
+
+ unsigned size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+ const MachineBasicBlock &front() const { return BasicBlocks.front(); }
+ MachineBasicBlock &front() { return BasicBlocks.front(); }
+ const MachineBasicBlock & back() const { return BasicBlocks.back(); }
+ MachineBasicBlock & back() { return BasicBlocks.back(); }
+
+ //===--------------------------------------------------------------------===//
+ // Internal functions used to automatically number MachineBasicBlocks
+ //
+
+ /// getNextMBBNumber - Returns the next unique number to be assigned
+ /// to a MachineBasicBlock in this MachineFunction.
+ ///
+ unsigned addToMBBNumbering(MachineBasicBlock *MBB) {
+ MBBNumbering.push_back(MBB);
+ return MBBNumbering.size()-1;
+ }
+
+ /// removeFromMBBNumbering - Remove the specific machine basic block from our
+ /// tracker, this is only really to be used by the MachineBasicBlock
+ /// implementation.
+ void removeFromMBBNumbering(unsigned N) {
+ assert(N < MBBNumbering.size() && "Illegal basic block #");
+ MBBNumbering[N] = 0;
+ }
+};
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a
+// machine function as a graph of machine basic blocks... these are
+// the same as the machine basic block iterators, except that the root
+// node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<MachineFunction*> :
+ public GraphTraits<MachineBasicBlock*> {
+ static NodeType *getEntryNode(MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(MachineFunction *F) { return F->begin(); }
+ static nodes_iterator nodes_end (MachineFunction *F) { return F->end(); }
+};
+template <> struct GraphTraits<const MachineFunction*> :
+ public GraphTraits<const MachineBasicBlock*> {
+ static NodeType *getEntryNode(const MachineFunction *F) {
+ return &F->front();
+ }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef MachineFunction::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const MachineFunction *F) { return F->begin(); }
+ static nodes_iterator nodes_end (const MachineFunction *F) { return F->end(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<MachineFunction*> > :
+ public GraphTraits<Inverse<MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<MachineFunction*> G) {
+ return &G.Graph->front();
+ }
+};
+template <> struct GraphTraits<Inverse<const MachineFunction*> > :
+ public GraphTraits<Inverse<const MachineBasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const MachineFunction *> G) {
+ return &G.Graph->front();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineFunctionPass.h b/include/llvm/CodeGen/MachineFunctionPass.h
new file mode 100644
index 0000000..f90c696
--- /dev/null
+++ b/include/llvm/CodeGen/MachineFunctionPass.h
@@ -0,0 +1,50 @@
+//===-- MachineFunctionPass.h - Pass for MachineFunctions --------*-C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachineFunctionPass class. MachineFunctionPass's are
+// just FunctionPass's, except they operate on machine code as part of a code
+// generator. Because they operate on machine code, not the LLVM
+// representation, MachineFunctionPass's are not allowed to modify the LLVM
+// representation. Due to this limitation, the MachineFunctionPass class takes
+// care of declaring that no LLVM passes are invalidated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+#define LLVM_CODEGEN_MACHINE_FUNCTION_PASS_H
+
+#include "llvm/Pass.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+struct MachineFunctionPass : public FunctionPass {
+
+ explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
+
+protected:
+ /// runOnMachineFunction - This method must be overloaded to perform the
+ /// desired machine code transformation or analysis.
+ ///
+ virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
+
+public:
+ // FIXME: This pass should declare that the pass does not invalidate any LLVM
+ // passes.
+ bool runOnFunction(Function &F) {
+ return runOnMachineFunction(MachineFunction::get(&F));
+ }
+
+private:
+ virtual void virtfn(); // out of line virtual fn to give class a home.
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstr.h b/include/llvm/CodeGen/MachineInstr.h
new file mode 100644
index 0000000..1f621c1
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstr.h
@@ -0,0 +1,567 @@
+//===-- llvm/CodeGen/MachineInstr.h - MachineInstr class --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the MachineInstr class, which is the
+// basic representation for all target dependent machine instructions used by
+// the back end.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTR_H
+#define LLVM_CODEGEN_MACHINEINSTR_H
+
+#include "llvm/ADT/iterator"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <cassert>
+#include <iosfwd>
+
+namespace llvm {
+
+class Value;
+class Function;
+class MachineBasicBlock;
+class TargetInstrDescriptor;
+class TargetMachine;
+class GlobalValue;
+
+template <typename T> struct ilist_traits;
+template <typename T> struct ilist;
+
+//===----------------------------------------------------------------------===//
+// class MachineOperand
+//
+// Representation of each machine instruction operand.
+//
+struct MachineOperand {
+ enum MachineOperandType {
+ MO_Register, // Register operand.
+ MO_Immediate, // Immediate Operand
+ MO_MachineBasicBlock, // MachineBasicBlock reference
+ MO_FrameIndex, // Abstract Stack Frame Index
+ MO_ConstantPoolIndex, // Address of indexed Constant in Constant Pool
+ MO_JumpTableIndex, // Address of indexed Jump Table for switch
+ MO_ExternalSymbol, // Name of external global symbol
+ MO_GlobalAddress // Address of a global value
+ };
+
+private:
+ union {
+ GlobalValue *GV; // For MO_GlobalAddress.
+ MachineBasicBlock *MBB; // For MO_MachineBasicBlock.
+ const char *SymbolName; // For MO_ExternalSymbol.
+ unsigned RegNo; // For MO_Register.
+ int64_t immedVal; // For MO_Immediate and MO_*Index.
+ } contents;
+
+ MachineOperandType opType:8; // Discriminate the union.
+ bool IsDef : 1; // True if this is a def, false if this is a use.
+ bool IsImp : 1; // True if this is an implicit def or use.
+
+ bool IsKill : 1; // True if this is a reg use and the reg is dead
+ // immediately after the read.
+ bool IsDead : 1; // True if this is a reg def and the reg is dead
+ // immediately after the write. i.e. A register
+ // that is defined but never used.
+
+ /// auxInfo - auxiliary information used by the MachineOperand
+ union {
+ /// offset - Offset to address of global or external, only valid for
+ /// MO_GlobalAddress, MO_ExternalSym and MO_ConstantPoolIndex
+ int offset;
+
+ /// subReg - SubRegister number, only valid for MO_Register. A value of 0
+ /// indicates the MO_Register has no subReg.
+ unsigned subReg;
+ } auxInfo;
+
+ MachineOperand() {}
+
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+public:
+ MachineOperand(const MachineOperand &M) {
+ *this = M;
+ }
+
+ ~MachineOperand() {}
+
+ static MachineOperand CreateImm(int64_t Val) {
+ MachineOperand Op;
+ Op.opType = MachineOperand::MO_Immediate;
+ Op.contents.immedVal = Val;
+ Op.IsDef = false;
+ Op.IsImp = false;
+ Op.IsKill = false;
+ Op.IsDead = false;
+ Op.auxInfo.offset = 0;
+ return Op;
+ }
+
+ const MachineOperand &operator=(const MachineOperand &MO) {
+ contents = MO.contents;
+ IsDef = MO.IsDef;
+ IsImp = MO.IsImp;
+ IsKill = MO.IsKill;
+ IsDead = MO.IsDead;
+ opType = MO.opType;
+ auxInfo = MO.auxInfo;
+ return *this;
+ }
+
+ /// getType - Returns the MachineOperandType for this operand.
+ ///
+ MachineOperandType getType() const { return opType; }
+
+ /// Accessors that tell you what kind of MachineOperand you're looking at.
+ ///
+ bool isReg() const { return opType == MO_Register; }
+ bool isImm() const { return opType == MO_Immediate; }
+ bool isMBB() const { return opType == MO_MachineBasicBlock; }
+
+ bool isRegister() const { return opType == MO_Register; }
+ bool isImmediate() const { return opType == MO_Immediate; }
+ bool isMachineBasicBlock() const { return opType == MO_MachineBasicBlock; }
+ bool isFrameIndex() const { return opType == MO_FrameIndex; }
+ bool isConstantPoolIndex() const { return opType == MO_ConstantPoolIndex; }
+ bool isJumpTableIndex() const { return opType == MO_JumpTableIndex; }
+ bool isGlobalAddress() const { return opType == MO_GlobalAddress; }
+ bool isExternalSymbol() const { return opType == MO_ExternalSymbol; }
+
+ int64_t getImm() const {
+ assert(isImm() && "Wrong MachineOperand accessor");
+ return contents.immedVal;
+ }
+
+ int64_t getImmedValue() const {
+ assert(isImm() && "Wrong MachineOperand accessor");
+ return contents.immedVal;
+ }
+ MachineBasicBlock *getMBB() const {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ return contents.MBB;
+ }
+ MachineBasicBlock *getMachineBasicBlock() const {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ return contents.MBB;
+ }
+ void setMachineBasicBlock(MachineBasicBlock *MBB) {
+ assert(isMachineBasicBlock() && "Wrong MachineOperand accessor");
+ contents.MBB = MBB;
+ }
+ int getFrameIndex() const {
+ assert(isFrameIndex() && "Wrong MachineOperand accessor");
+ return (int)contents.immedVal;
+ }
+ unsigned getConstantPoolIndex() const {
+ assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
+ return (unsigned)contents.immedVal;
+ }
+ unsigned getJumpTableIndex() const {
+ assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+ return (unsigned)contents.immedVal;
+ }
+ GlobalValue *getGlobal() const {
+ assert(isGlobalAddress() && "Wrong MachineOperand accessor");
+ return contents.GV;
+ }
+ int getOffset() const {
+ assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex()) &&
+ "Wrong MachineOperand accessor");
+ return auxInfo.offset;
+ }
+ unsigned getSubReg() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return auxInfo.subReg;
+ }
+ const char *getSymbolName() const {
+ assert(isExternalSymbol() && "Wrong MachineOperand accessor");
+ return contents.SymbolName;
+ }
+
+ bool isUse() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return !IsDef;
+ }
+ bool isDef() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsDef;
+ }
+ void setIsUse() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsDef = false;
+ }
+ void setIsDef() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsDef = true;
+ }
+
+ bool isImplicit() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsImp;
+ }
+ void setImplicit() {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ IsImp = true;
+ }
+
+ bool isKill() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsKill;
+ }
+ bool isDead() const {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ return IsDead;
+ }
+ void setIsKill() {
+ assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+ IsKill = true;
+ }
+ void setIsDead() {
+ assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+ IsDead = true;
+ }
+ void unsetIsKill() {
+ assert(isRegister() && !IsDef && "Wrong MachineOperand accessor");
+ IsKill = false;
+ }
+ void unsetIsDead() {
+ assert(isRegister() && IsDef && "Wrong MachineOperand accessor");
+ IsDead = false;
+ }
+
+ /// getReg - Returns the register number.
+ ///
+ unsigned getReg() const {
+ assert(isRegister() && "This is not a register operand!");
+ return contents.RegNo;
+ }
+
+ /// MachineOperand mutators.
+ ///
+ void setReg(unsigned Reg) {
+ assert(isRegister() && "This is not a register operand!");
+ contents.RegNo = Reg;
+ }
+
+ void setImmedValue(int64_t immVal) {
+ assert(isImm() && "Wrong MachineOperand mutator");
+ contents.immedVal = immVal;
+ }
+ void setImm(int64_t immVal) {
+ assert(isImm() && "Wrong MachineOperand mutator");
+ contents.immedVal = immVal;
+ }
+
+ void setOffset(int Offset) {
+ assert((isGlobalAddress() || isExternalSymbol() || isConstantPoolIndex() ||
+ isJumpTableIndex()) &&
+ "Wrong MachineOperand accessor");
+ auxInfo.offset = Offset;
+ }
+ void setSubReg(unsigned subReg) {
+ assert(isRegister() && "Wrong MachineOperand accessor");
+ auxInfo.subReg = subReg;
+ }
+ void setConstantPoolIndex(unsigned Idx) {
+ assert(isConstantPoolIndex() && "Wrong MachineOperand accessor");
+ contents.immedVal = Idx;
+ }
+ void setJumpTableIndex(unsigned Idx) {
+ assert(isJumpTableIndex() && "Wrong MachineOperand accessor");
+ contents.immedVal = Idx;
+ }
+
+ /// isIdenticalTo - Return true if this operand is identical to the specified
+ /// operand. Note: This method ignores isKill and isDead properties.
+ bool isIdenticalTo(const MachineOperand &Other) const;
+
+ /// ChangeToImmediate - Replace this operand with a new immediate operand of
+ /// the specified value. If an operand is known to be an immediate already,
+ /// the setImmedValue method should be used.
+ void ChangeToImmediate(int64_t ImmVal) {
+ opType = MO_Immediate;
+ contents.immedVal = ImmVal;
+ }
+
+ /// ChangeToRegister - Replace this operand with a new register operand of
+ /// the specified value. If an operand is known to be an register already,
+ /// the setReg method should be used.
+ void ChangeToRegister(unsigned Reg, bool isDef, bool isImp = false,
+ bool isKill = false, bool isDead = false) {
+ opType = MO_Register;
+ contents.RegNo = Reg;
+ IsDef = isDef;
+ IsImp = isImp;
+ IsKill = isKill;
+ IsDead = isDead;
+ }
+
+ friend std::ostream& operator<<(std::ostream& os, const MachineOperand& mop) {
+ mop.print(os);
+ return os;
+ }
+
+ friend class MachineInstr;
+};
+
+
+//===----------------------------------------------------------------------===//
+/// MachineInstr - Representation of each machine instruction.
+///
+class MachineInstr {
+ const TargetInstrDescriptor *TID; // Instruction descriptor.
+ unsigned short NumImplicitOps; // Number of implicit operands (which
+ // are determined at construction time).
+
+ std::vector<MachineOperand> Operands; // the operands
+ MachineInstr* prev, *next; // links for our intrusive list
+ MachineBasicBlock* parent; // pointer to the owning basic block
+
+ // OperandComplete - Return true if it's illegal to add a new operand
+ bool OperandsComplete() const;
+
+ MachineInstr(const MachineInstr&);
+ void operator=(const MachineInstr&); // DO NOT IMPLEMENT
+
+ // Intrusive list support
+ //
+ friend struct ilist_traits<MachineInstr>;
+
+public:
+ /// MachineInstr ctor - This constructor creates a dummy MachineInstr with
+ /// TID NULL and no operands.
+ MachineInstr();
+
+ /// MachineInstr ctor - This constructor create a MachineInstr and add the
+ /// implicit operands. It reserves space for number of operands specified by
+ /// TargetInstrDescriptor.
+ explicit MachineInstr(const TargetInstrDescriptor &TID);
+
+ /// MachineInstr ctor - Work exactly the same as the ctor above, except that
+ /// the MachineInstr is created and added to the end of the specified basic
+ /// block.
+ ///
+ MachineInstr(MachineBasicBlock *MBB, const TargetInstrDescriptor &TID);
+
+ ~MachineInstr();
+
+ const MachineBasicBlock* getParent() const { return parent; }
+ MachineBasicBlock* getParent() { return parent; }
+
+ /// getInstrDescriptor - Returns the target instruction descriptor of this
+ /// MachineInstr.
+ const TargetInstrDescriptor *getInstrDescriptor() const { return TID; }
+
+ /// getOpcode - Returns the opcode of this MachineInstr.
+ ///
+ const int getOpcode() const;
+
+ /// Access to explicit operands of the instruction.
+ ///
+ unsigned getNumOperands() const { return Operands.size(); }
+
+ const MachineOperand& getOperand(unsigned i) const {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+ MachineOperand& getOperand(unsigned i) {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Operands[i];
+ }
+
+ /// getNumExplicitOperands - Returns the number of non-implicit operands.
+ ///
+ unsigned getNumExplicitOperands() const;
+
+ /// isIdenticalTo - Return true if this instruction is identical to (same
+ /// opcode and same operands as) the specified instruction.
+ bool isIdenticalTo(const MachineInstr *Other) const {
+ if (Other->getOpcode() != getOpcode() ||
+ Other->getNumOperands() != getNumOperands())
+ return false;
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (!getOperand(i).isIdenticalTo(Other->getOperand(i)))
+ return false;
+ return true;
+ }
+
+ /// clone - Create a copy of 'this' instruction that is identical in
+ /// all ways except the the instruction has no parent, prev, or next.
+ MachineInstr* clone() const { return new MachineInstr(*this); }
+
+ /// removeFromParent - This method unlinks 'this' from the containing basic
+ /// block, and returns it, but does not delete it.
+ MachineInstr *removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing basic
+ /// block and deletes it.
+ void eraseFromParent() {
+ delete removeFromParent();
+ }
+
+ /// findRegisterUseOperandIdx() - Returns the operand index that is a use of
+ /// the specific register or -1 if it is not found. It further tightening
+ /// the search criteria to a use that kills the register if isKill is true.
+ int findRegisterUseOperandIdx(unsigned Reg, bool isKill = false) const;
+
+ /// findRegisterDefOperand() - Returns the MachineOperand that is a def of
+ /// the specific register or NULL if it is not found.
+ MachineOperand *findRegisterDefOperand(unsigned Reg);
+
+ /// findFirstPredOperandIdx() - Find the index of the first operand in the
+ /// operand list that is used to represent the predicate. It returns -1 if
+ /// none is found.
+ int findFirstPredOperandIdx() const;
+
+ /// copyKillDeadInfo - Copies kill / dead operand properties from MI.
+ ///
+ void copyKillDeadInfo(const MachineInstr *MI);
+
+ /// copyPredicates - Copies predicate operand(s) from MI.
+ void copyPredicates(const MachineInstr *MI);
+
+ //
+ // Debugging support
+ //
+ void print(std::ostream *OS, const TargetMachine *TM) const {
+ if (OS) print(*OS, TM);
+ }
+ void print(std::ostream &OS, const TargetMachine *TM) const;
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void dump() const;
+ friend std::ostream& operator<<(std::ostream& os, const MachineInstr& minstr){
+ minstr.print(os);
+ return os;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors to add operands when building up machine instructions.
+ //
+
+ /// addRegOperand - Add a register operand.
+ ///
+ void addRegOperand(unsigned Reg, bool IsDef, bool IsImp = false,
+ bool IsKill = false, bool IsDead = false) {
+ MachineOperand &Op = AddNewOperand(IsImp);
+ Op.opType = MachineOperand::MO_Register;
+ Op.IsDef = IsDef;
+ Op.IsImp = IsImp;
+ Op.IsKill = IsKill;
+ Op.IsDead = IsDead;
+ Op.contents.RegNo = Reg;
+ Op.auxInfo.subReg = 0;
+ }
+
+ /// addImmOperand - Add a zero extended constant argument to the
+ /// machine instruction.
+ ///
+ void addImmOperand(int64_t Val) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_Immediate;
+ Op.contents.immedVal = Val;
+ Op.auxInfo.offset = 0;
+ }
+
+ void addMachineBasicBlockOperand(MachineBasicBlock *MBB) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_MachineBasicBlock;
+ Op.contents.MBB = MBB;
+ Op.auxInfo.offset = 0;
+ }
+
+ /// addFrameIndexOperand - Add an abstract frame index to the instruction
+ ///
+ void addFrameIndexOperand(unsigned Idx) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_FrameIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = 0;
+ }
+
+ /// addConstantPoolndexOperand - Add a constant pool object index to the
+ /// instruction.
+ ///
+ void addConstantPoolIndexOperand(unsigned Idx, int Offset) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_ConstantPoolIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = Offset;
+ }
+
+ /// addJumpTableIndexOperand - Add a jump table object index to the
+ /// instruction.
+ ///
+ void addJumpTableIndexOperand(unsigned Idx) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_JumpTableIndex;
+ Op.contents.immedVal = Idx;
+ Op.auxInfo.offset = 0;
+ }
+
+ void addGlobalAddressOperand(GlobalValue *GV, int Offset) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_GlobalAddress;
+ Op.contents.GV = GV;
+ Op.auxInfo.offset = Offset;
+ }
+
+ /// addExternalSymbolOperand - Add an external symbol operand to this instr
+ ///
+ void addExternalSymbolOperand(const char *SymName) {
+ MachineOperand &Op = AddNewOperand();
+ Op.opType = MachineOperand::MO_ExternalSymbol;
+ Op.contents.SymbolName = SymName;
+ Op.auxInfo.offset = 0;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors used to modify instructions in place.
+ //
+
+ /// setInstrDescriptor - Replace the instruction descriptor (thus opcode) of
+ /// the current instruction with a new one.
+ ///
+ void setInstrDescriptor(const TargetInstrDescriptor &tid) { TID = &tid; }
+
+ /// RemoveOperand - Erase an operand from an instruction, leaving it with one
+ /// fewer operand than it started with.
+ ///
+ void RemoveOperand(unsigned i) {
+ Operands.erase(Operands.begin()+i);
+ }
+private:
+ MachineOperand &AddNewOperand(bool IsImp = false) {
+ assert((IsImp || !OperandsComplete()) &&
+ "Trying to add an operand to a machine instr that is already done!");
+ if (IsImp || NumImplicitOps == 0) { // This is true most of the time.
+ Operands.push_back(MachineOperand());
+ return Operands.back();
+ }
+ return *Operands.insert(Operands.begin()+Operands.size()-NumImplicitOps,
+ MachineOperand());
+ }
+
+ /// addImplicitDefUseOperands - Add all implicit def and use operands to
+ /// this instruction.
+ void addImplicitDefUseOperands();
+};
+
+//===----------------------------------------------------------------------===//
+// Debugging Support
+
+std::ostream& operator<<(std::ostream &OS, const MachineInstr &MI);
+std::ostream& operator<<(std::ostream &OS, const MachineOperand &MO);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineInstrBuilder.h b/include/llvm/CodeGen/MachineInstrBuilder.h
new file mode 100644
index 0000000..eb45b6e
--- /dev/null
+++ b/include/llvm/CodeGen/MachineInstrBuilder.h
@@ -0,0 +1,147 @@
+//===-- CodeGen/MachineInstBuilder.h - Simplify creation of MIs -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes a function named BuildMI, which is useful for dramatically
+// simplifying how MachineInstr's are created. It allows use of code like this:
+//
+// M = BuildMI(X86::ADDrr8, 2).addReg(argVal1).addReg(argVal2);
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+#define LLVM_CODEGEN_MACHINEINSTRBUILDER_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+namespace llvm {
+
+class TargetInstrDescriptor;
+
+class MachineInstrBuilder {
+ MachineInstr *MI;
+public:
+ explicit MachineInstrBuilder(MachineInstr *mi) : MI(mi) {}
+
+ /// Allow automatic conversion to the machine instruction we are working on.
+ ///
+ operator MachineInstr*() const { return MI; }
+ operator MachineBasicBlock::iterator() const { return MI; }
+
+ /// addReg - Add a new virtual register operand...
+ ///
+ const
+ MachineInstrBuilder &addReg(int RegNo, bool isDef = false, bool isImp = false,
+ bool isKill = false, bool isDead = false) const {
+ MI->addRegOperand(RegNo, isDef, isImp, isKill, isDead);
+ return *this;
+ }
+
+ /// addImm - Add a new immediate operand.
+ ///
+ const MachineInstrBuilder &addImm(int64_t Val) const {
+ MI->addImmOperand(Val);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addMBB(MachineBasicBlock *MBB) const {
+ MI->addMachineBasicBlockOperand(MBB);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addFrameIndex(unsigned Idx) const {
+ MI->addFrameIndexOperand(Idx);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addConstantPoolIndex(unsigned Idx,
+ int Offset = 0) const {
+ MI->addConstantPoolIndexOperand(Idx, Offset);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addJumpTableIndex(unsigned Idx) const {
+ MI->addJumpTableIndexOperand(Idx);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
+ int Offset = 0) const {
+ MI->addGlobalAddressOperand(GV, Offset);
+ return *this;
+ }
+
+ const MachineInstrBuilder &addExternalSymbol(const char *FnName) const{
+ MI->addExternalSymbolOperand(FnName);
+ return *this;
+ }
+};
+
+/// BuildMI - Builder interface. Specify how to create the initial instruction
+/// itself.
+///
+inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID) {
+ return MachineInstrBuilder(new MachineInstr(TID));
+}
+
+/// BuildMI - This version of the builder sets up the first operand as a
+/// destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ return MachineInstrBuilder(new MachineInstr(TID)).addReg(DestReg, true);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// sets up the first operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ MachineInstr *MI = new MachineInstr(TID);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI).addReg(DestReg, true);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction before the given position in the given MachineBasicBlock, and
+/// does NOT take a destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB,
+ MachineBasicBlock::iterator I,
+ const TargetInstrDescriptor &TID) {
+ MachineInstr *MI = new MachineInstr(TID);
+ BB.insert(I, MI);
+ return MachineInstrBuilder(MI);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and does NOT take a
+/// destination register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ const TargetInstrDescriptor &TID) {
+ return BuildMI(*BB, BB->end(), TID);
+}
+
+/// BuildMI - This version of the builder inserts the newly-built
+/// instruction at the end of the given MachineBasicBlock, and sets up the first
+/// operand as a destination virtual register.
+///
+inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB,
+ const TargetInstrDescriptor &TID,
+ unsigned DestReg) {
+ return BuildMI(*BB, BB->end(), TID, DestReg);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineJumpTableInfo.h b/include/llvm/CodeGen/MachineJumpTableInfo.h
new file mode 100644
index 0000000..d440268
--- /dev/null
+++ b/include/llvm/CodeGen/MachineJumpTableInfo.h
@@ -0,0 +1,103 @@
+//===-- CodeGen/MachineJumpTableInfo.h - Abstract Jump Tables --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The MachineJumpTableInfo class keeps track of jump tables referenced by
+// lowered switch instructions in the MachineFunction.
+//
+// Instructions reference the address of these jump tables through the use of
+// MO_JumpTableIndex values. When emitting assembly or machine code, these
+// virtual address references are converted to refer to the address of the
+// function jump tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+#define LLVM_CODEGEN_MACHINEJUMPTABLEINFO_H
+
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+
+class MachineBasicBlock;
+class TargetData;
+
+/// MachineJumpTableEntry - One jump table in the jump table info.
+///
+struct MachineJumpTableEntry {
+ /// MBBs - The vector of basic blocks from which to create the jump table.
+ std::vector<MachineBasicBlock*> MBBs;
+
+ explicit MachineJumpTableEntry(const std::vector<MachineBasicBlock*> &M)
+ : MBBs(M) {}
+};
+
+class MachineJumpTableInfo {
+ unsigned EntrySize;
+ unsigned Alignment;
+ std::vector<MachineJumpTableEntry> JumpTables;
+public:
+ MachineJumpTableInfo(unsigned Size, unsigned Align)
+ : EntrySize(Size), Alignment(Align) {}
+
+ /// getJumpTableIndex - Create a new jump table or return an existing one.
+ ///
+ unsigned getJumpTableIndex(const std::vector<MachineBasicBlock*> &DestBBs);
+
+ /// isEmpty - Return true if there are no jump tables.
+ ///
+ bool isEmpty() const { return JumpTables.empty(); }
+
+ const std::vector<MachineJumpTableEntry> &getJumpTables() const {
+ return JumpTables;
+ }
+
+ /// RemoveJumpTable - Mark the specific index as being dead. This will cause
+ /// it to not be emitted.
+ void RemoveJumpTable(unsigned Idx) {
+ JumpTables[Idx].MBBs.clear();
+ }
+
+ /// ReplaceMBBInJumpTables - If Old is the target of any jump tables, update
+ /// the jump tables to branch to New instead.
+ bool ReplaceMBBInJumpTables(MachineBasicBlock *Old, MachineBasicBlock *New) {
+ assert(Old != New && "Not making a change?");
+ bool MadeChange = false;
+ for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
+ MachineJumpTableEntry &JTE = JumpTables[i];
+ for (unsigned j = 0, e = JTE.MBBs.size(); j != e; ++j)
+ if (JTE.MBBs[j] == Old) {
+ JTE.MBBs[j] = New;
+ MadeChange = true;
+ }
+ }
+ return MadeChange;
+ }
+
+ /// getEntrySize - Returns the size of an individual field in a jump table.
+ ///
+ unsigned getEntrySize() const { return EntrySize; }
+
+ /// getAlignment - returns the target's preferred alignment for jump tables
+ unsigned getAlignment() const { return Alignment; }
+
+ /// print - Used by the MachineFunction printer to print information about
+ /// jump tables. Implemented in MachineFunction.cpp
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Call print(std::cerr) to be called from the debugger.
+ ///
+ void dump() const;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineLocation.h b/include/llvm/CodeGen/MachineLocation.h
new file mode 100644
index 0000000..c0a78ae
--- /dev/null
+++ b/include/llvm/CodeGen/MachineLocation.h
@@ -0,0 +1,106 @@
+//===-- llvm/CodeGen/MachineLocation.h --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// The MachineLocation class is used to represent a simple location in a machine
+// frame. Locations will be one of two forms; a register or an address formed
+// from a base address plus an offset. Register indirection can be specified by
+// using an offset of zero.
+//
+// The MachineMove class is used to represent abstract move operations in the
+// prolog/epilog of a compiled function. A collection of these objects can be
+// used by a debug consumer to track the location of values when unwinding stack
+// frames.
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_CODEGEN_MACHINELOCATION_H
+#define LLVM_CODEGEN_MACHINELOCATION_H
+
+namespace llvm {
+
+class MachineLocation {
+private:
+ bool IsRegister; // True if location is a register.
+ unsigned Register; // gcc/gdb register number.
+ int Offset; // Displacement if not register.
+
+public:
+ enum {
+ // The target register number for an abstract frame pointer. The value is
+ // an arbitrary value greater than MRegisterInfo::FirstVirtualRegister.
+ VirtualFP = ~0U
+ };
+ MachineLocation()
+ : IsRegister(false)
+ , Register(0)
+ , Offset(0)
+ {}
+ explicit MachineLocation(unsigned R)
+ : IsRegister(true)
+ , Register(R)
+ , Offset(0)
+ {}
+ MachineLocation(unsigned R, int O)
+ : IsRegister(false)
+ , Register(R)
+ , Offset(O)
+ {}
+
+ // Accessors
+ bool isRegister() const { return IsRegister; }
+ unsigned getRegister() const { return Register; }
+ int getOffset() const { return Offset; }
+ void setIsRegister(bool Is) { IsRegister = Is; }
+ void setRegister(unsigned R) { Register = R; }
+ void setOffset(int O) { Offset = O; }
+ void set(unsigned R) {
+ IsRegister = true;
+ Register = R;
+ Offset = 0;
+ }
+ void set(unsigned R, int O) {
+ IsRegister = false;
+ Register = R;
+ Offset = O;
+ }
+
+#ifndef NDEBUG
+ void dump();
+#endif
+};
+
+class MachineMove {
+private:
+ unsigned LabelID; // Label ID number for post-instruction
+ // address when result of move takes
+ // effect.
+ MachineLocation Destination; // Move to location.
+ MachineLocation Source; // Move from location.
+
+public:
+ MachineMove()
+ : LabelID(0)
+ , Destination()
+ , Source()
+ {}
+
+ MachineMove(unsigned ID, MachineLocation &D, MachineLocation &S)
+ : LabelID(ID)
+ , Destination(D)
+ , Source(S)
+ {}
+
+ // Accessors
+ unsigned getLabelID() const { return LabelID; }
+ const MachineLocation &getDestination() const { return Destination; }
+ const MachineLocation &getSource() const { return Source; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachineModuleInfo.h b/include/llvm/CodeGen/MachineModuleInfo.h
new file mode 100644
index 0000000..778b75c
--- /dev/null
+++ b/include/llvm/CodeGen/MachineModuleInfo.h
@@ -0,0 +1,1280 @@
+//===-- llvm/CodeGen/MachineModuleInfo.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Collect meta information for a module. This information should be in a
+// neutral form that can be used by different debugging and exception handling
+// schemes.
+//
+// The organization of information is primarily clustered around the source
+// compile units. The main exception is source line correspondence where
+// inlining may interleave code from various compile units.
+//
+// The following information can be retrieved from the MachineModuleInfo.
+//
+// -- Source directories - Directories are uniqued based on their canonical
+// string and assigned a sequential numeric ID (base 1.)
+// -- Source files - Files are also uniqued based on their name and directory
+// ID. A file ID is sequential number (base 1.)
+// -- Source line correspondence - A vector of file ID, line#, column# triples.
+// A DEBUG_LOCATION instruction is generated by the DAG Legalizer
+// corresponding to each entry in the source line list. This allows a debug
+// emitter to generate labels referenced by debug information tables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEMODULEINFO_H
+#define LLVM_CODEGEN_MACHINEMODULEINFO_H
+
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/UniqueVector.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Forward declarations.
+class Constant;
+class DebugInfoDesc;
+class GlobalVariable;
+class MachineBasicBlock;
+class MachineFunction;
+class MachineMove;
+class Module;
+class PointerType;
+class StructType;
+
+//===----------------------------------------------------------------------===//
+// Debug info constants.
+
+enum {
+ LLVMDebugVersion = (6 << 16), // Current version of debug information.
+ LLVMDebugVersion5 = (5 << 16), // Constant for version 5.
+ LLVMDebugVersion4 = (4 << 16), // Constant for version 4.
+ LLVMDebugVersionMask = 0xffff0000 // Mask for version number.
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVisitor - Subclasses of this class apply steps to each of the fields in
+/// the supplied DebugInfoDesc.
+class DIVisitor {
+public:
+ DIVisitor() {}
+ virtual ~DIVisitor() {}
+
+ /// ApplyToFields - Target the visitor to each field of the debug information
+ /// descriptor.
+ void ApplyToFields(DebugInfoDesc *DD);
+
+ /// Apply - Subclasses override each of these methods to perform the
+ /// appropriate action for the type of field.
+ virtual void Apply(int &Field) = 0;
+ virtual void Apply(unsigned &Field) = 0;
+ virtual void Apply(int64_t &Field) = 0;
+ virtual void Apply(uint64_t &Field) = 0;
+ virtual void Apply(bool &Field) = 0;
+ virtual void Apply(std::string &Field) = 0;
+ virtual void Apply(DebugInfoDesc *&Field) = 0;
+ virtual void Apply(GlobalVariable *&Field) = 0;
+ virtual void Apply(std::vector<DebugInfoDesc *> &Field) = 0;
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugInfoDesc - This class is the base class for debug info descriptors.
+///
+class DebugInfoDesc {
+private:
+ unsigned Tag; // Content indicator. Dwarf values are
+ // used but that does not limit use to
+ // Dwarf writers.
+
+protected:
+ explicit DebugInfoDesc(unsigned T) : Tag(T | LLVMDebugVersion) {}
+
+public:
+ virtual ~DebugInfoDesc() {}
+
+ // Accessors
+ unsigned getTag() const { return Tag & ~LLVMDebugVersionMask; }
+ unsigned getVersion() const { return Tag & LLVMDebugVersionMask; }
+ void setTag(unsigned T) { Tag = T | LLVMDebugVersion; }
+
+ /// TagFromGlobal - Returns the tag number from a debug info descriptor
+ /// GlobalVariable. Return DIIValid if operand is not an unsigned int.
+ static unsigned TagFromGlobal(GlobalVariable *GV);
+
+ /// VersionFromGlobal - Returns the version number from a debug info
+ /// descriptor GlobalVariable. Return DIIValid if operand is not an unsigned
+ /// int.
+ static unsigned VersionFromGlobal(GlobalVariable *GV);
+
+ /// DescFactory - Create an instance of debug info descriptor based on Tag.
+ /// Return NULL if not a recognized Tag.
+ static DebugInfoDesc *DescFactory(unsigned Tag);
+
+ /// getLinkage - get linkage appropriate for this type of descriptor.
+ ///
+ virtual GlobalValue::LinkageTypes getLinkage() const;
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following static methods.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DebugInfoDesc *) { return true; }
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following virtual methods.
+
+ /// ApplyToFields - Target the vistor to the fields of the descriptor.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const = 0;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const = 0;
+
+#ifndef NDEBUG
+ virtual void dump() = 0;
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// AnchorDesc - Descriptors of this class act as markers for identifying
+/// descriptors of certain groups.
+class AnchoredDesc;
+class AnchorDesc : public DebugInfoDesc {
+private:
+ unsigned AnchorTag; // Tag number of descriptors anchored
+ // by this object.
+
+public:
+ AnchorDesc();
+ AnchorDesc(AnchoredDesc *D);
+
+ // Accessors
+ unsigned getAnchorTag() const { return AnchorTag; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const AnchorDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// getLinkage - get linkage appropriate for this type of descriptor.
+ ///
+ virtual GlobalValue::LinkageTypes getLinkage() const;
+
+ /// ApplyToFields - Target the visitor to the fields of the AnchorDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// AnchoredDesc - This class manages anchors for a variety of top level
+/// descriptors.
+class AnchoredDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Anchor; // Anchor for all descriptors of the
+ // same type.
+
+protected:
+
+ AnchoredDesc(unsigned T);
+
+public:
+ // Accessors.
+ AnchorDesc *getAnchor() const { return static_cast<AnchorDesc *>(Anchor); }
+ void setAnchor(AnchorDesc *A) { Anchor = static_cast<DebugInfoDesc *>(A); }
+
+ //===--------------------------------------------------------------------===//
+ // Subclasses should supply the following virtual methods.
+
+ /// getAnchorString - Return a string used to label descriptor's anchor.
+ ///
+ virtual const char *getAnchorString() const = 0;
+
+ /// ApplyToFields - Target the visitor to the fields of the AnchoredDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+};
+
+//===----------------------------------------------------------------------===//
+/// CompileUnitDesc - This class packages debug information associated with a
+/// source/header file.
+class CompileUnitDesc : public AnchoredDesc {
+private:
+ unsigned Language; // Language number (ex. DW_LANG_C89.)
+ std::string FileName; // Source file name.
+ std::string Directory; // Source file directory.
+ std::string Producer; // Compiler string.
+
+public:
+ CompileUnitDesc();
+
+
+ // Accessors
+ unsigned getLanguage() const { return Language; }
+ const std::string &getFileName() const { return FileName; }
+ const std::string &getDirectory() const { return Directory; }
+ const std::string &getProducer() const { return Producer; }
+ void setLanguage(unsigned L) { Language = L; }
+ void setFileName(const std::string &FN) { FileName = FN; }
+ void setDirectory(const std::string &D) { Directory = D; }
+ void setProducer(const std::string &P) { Producer = P; }
+
+ // FIXME - Need translation unit getter/setter.
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const CompileUnitDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the CompileUnitDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// TypeDesc - This class packages debug information associated with a type.
+///
+class TypeDesc : public DebugInfoDesc {
+private:
+ enum {
+ FlagPrivate = 1 << 0,
+ FlagProtected = 1 << 1
+ };
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Type name (may be empty.)
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ uint64_t Size; // Type bit size (may be zero.)
+ uint64_t Align; // Type bit alignment (may be zero.)
+ uint64_t Offset; // Type bit offset (may be zero.)
+ unsigned Flags; // Miscellaneous flags.
+
+public:
+ TypeDesc(unsigned T);
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ uint64_t getSize() const { return Size; }
+ uint64_t getAlign() const { return Align; }
+ uint64_t getOffset() const { return Offset; }
+ bool isPrivate() const {
+ return (Flags & FlagPrivate) != 0;
+ }
+ bool isProtected() const {
+ return (Flags & FlagProtected) != 0;
+ }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setSize(uint64_t S) { Size = S; }
+ void setAlign(uint64_t A) { Align = A; }
+ void setOffset(uint64_t O) { Offset = O; }
+ void setIsPrivate() { Flags |= FlagPrivate; }
+ void setIsProtected() { Flags |= FlagProtected; }
+
+ /// ApplyToFields - Target the visitor to the fields of the TypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// BasicTypeDesc - This class packages debug information associated with a
+/// basic type (eg. int, bool, double.)
+class BasicTypeDesc : public TypeDesc {
+private:
+ unsigned Encoding; // Type encoding.
+
+public:
+ BasicTypeDesc();
+
+ // Accessors
+ unsigned getEncoding() const { return Encoding; }
+ void setEncoding(unsigned E) { Encoding = E; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const BasicTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+
+//===----------------------------------------------------------------------===//
+/// DerivedTypeDesc - This class packages debug information associated with a
+/// derived types (eg., typedef, pointer, reference.)
+class DerivedTypeDesc : public TypeDesc {
+private:
+ DebugInfoDesc *FromType; // Type derived from.
+
+public:
+ DerivedTypeDesc(unsigned T);
+
+ // Accessors
+ TypeDesc *getFromType() const {
+ return static_cast<TypeDesc *>(FromType);
+ }
+ void setFromType(TypeDesc *F) {
+ FromType = static_cast<DebugInfoDesc *>(F);
+ }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const DerivedTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// CompositeTypeDesc - This class packages debug information associated with a
+/// array/struct types (eg., arrays, struct, union, enums.)
+class CompositeTypeDesc : public DerivedTypeDesc {
+private:
+ std::vector<DebugInfoDesc *> Elements;// Information used to compose type.
+
+public:
+ CompositeTypeDesc(unsigned T);
+
+ // Accessors
+ std::vector<DebugInfoDesc *> &getElements() { return Elements; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const CompositeTypeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the CompositeTypeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// SubrangeDesc - This class packages debug information associated with integer
+/// value ranges.
+class SubrangeDesc : public DebugInfoDesc {
+private:
+ int64_t Lo; // Low value of range.
+ int64_t Hi; // High value of range.
+
+public:
+ SubrangeDesc();
+
+ // Accessors
+ int64_t getLo() const { return Lo; }
+ int64_t getHi() const { return Hi; }
+ void setLo(int64_t L) { Lo = L; }
+ void setHi(int64_t H) { Hi = H; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const SubrangeDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the SubrangeDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// EnumeratorDesc - This class packages debug information associated with
+/// named integer constants.
+class EnumeratorDesc : public DebugInfoDesc {
+private:
+ std::string Name; // Enumerator name.
+ int64_t Value; // Enumerator value.
+
+public:
+ EnumeratorDesc();
+
+ // Accessors
+ const std::string &getName() const { return Name; }
+ int64_t getValue() const { return Value; }
+ void setName(const std::string &N) { Name = N; }
+ void setValue(int64_t V) { Value = V; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const EnumeratorDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the EnumeratorDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// VariableDesc - This class packages debug information associated with a
+/// subprogram variable.
+///
+class VariableDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Type name (may be empty.)
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ DebugInfoDesc *TyDesc; // Type of variable.
+
+public:
+ VariableDesc(unsigned T);
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ TypeDesc *getType() const {
+ return static_cast<TypeDesc *>(TyDesc);
+ }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setType(TypeDesc *T) {
+ TyDesc = static_cast<DebugInfoDesc *>(T);
+ }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const VariableDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the VariableDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// GlobalDesc - This class is the base descriptor for global functions and
+/// variables.
+class GlobalDesc : public AnchoredDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+ std::string Name; // Global name.
+ std::string FullName; // Fully qualified name.
+ std::string LinkageName; // Name for binding to MIPS linkage.
+ DebugInfoDesc *File; // Defined compile unit (may be NULL.)
+ unsigned Line; // Defined line# (may be zero.)
+ DebugInfoDesc *TyDesc; // Type debug descriptor.
+ bool IsStatic; // Is the global a static.
+ bool IsDefinition; // Is the global defined in context.
+
+protected:
+ GlobalDesc(unsigned T);
+
+public:
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ const std::string &getName() const { return Name; }
+ const std::string &getFullName() const { return FullName; }
+ const std::string &getLinkageName() const { return LinkageName; }
+ CompileUnitDesc *getFile() const {
+ return static_cast<CompileUnitDesc *>(File);
+ }
+ unsigned getLine() const { return Line; }
+ TypeDesc *getType() const {
+ return static_cast<TypeDesc *>(TyDesc);
+ }
+ bool isStatic() const { return IsStatic; }
+ bool isDefinition() const { return IsDefinition; }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+ void setName(const std::string &N) { Name = N; }
+ void setFullName(const std::string &N) { FullName = N; }
+ void setLinkageName(const std::string &N) { LinkageName = N; }
+ void setFile(CompileUnitDesc *U) {
+ File = static_cast<DebugInfoDesc *>(U);
+ }
+ void setLine(unsigned L) { Line = L; }
+ void setType(TypeDesc *T) {
+ TyDesc = static_cast<DebugInfoDesc *>(T);
+ }
+ void setIsStatic(bool IS) { IsStatic = IS; }
+ void setIsDefinition(bool ID) { IsDefinition = ID; }
+
+ /// ApplyToFields - Target the visitor to the fields of the GlobalDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+};
+
+//===----------------------------------------------------------------------===//
+/// GlobalVariableDesc - This class packages debug information associated with a
+/// GlobalVariable.
+class GlobalVariableDesc : public GlobalDesc {
+private:
+ GlobalVariable *Global; // llvm global.
+
+public:
+ GlobalVariableDesc();
+
+ // Accessors.
+ GlobalVariable *getGlobalVariable() const { return Global; }
+ void setGlobalVariable(GlobalVariable *GV) { Global = GV; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const GlobalVariableDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the
+ /// GlobalVariableDesc.
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// SubprogramDesc - This class packages debug information associated with a
+/// subprogram/function.
+class SubprogramDesc : public GlobalDesc {
+private:
+
+public:
+ SubprogramDesc();
+
+ // Accessors
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const SubprogramDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the SubprogramDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+ /// getAnchorString - Return a string used to label this descriptor's anchor.
+ ///
+ static const char *AnchorString;
+ virtual const char *getAnchorString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// BlockDesc - This descriptor groups variables and blocks nested in a block.
+///
+class BlockDesc : public DebugInfoDesc {
+private:
+ DebugInfoDesc *Context; // Context debug descriptor.
+
+public:
+ BlockDesc();
+
+ // Accessors
+ DebugInfoDesc *getContext() const { return Context; }
+ void setContext(DebugInfoDesc *C) { Context = C; }
+
+ // Implement isa/cast/dyncast.
+ static bool classof(const BlockDesc *) { return true; }
+ static bool classof(const DebugInfoDesc *D);
+
+ /// ApplyToFields - Target the visitor to the fields of the BlockDesc.
+ ///
+ virtual void ApplyToFields(DIVisitor *Visitor);
+
+ /// getDescString - Return a string used to compose global names and labels.
+ ///
+ virtual const char *getDescString() const;
+
+ /// getTypeString - Return a string used to label this descriptor's type.
+ ///
+ virtual const char *getTypeString() const;
+
+#ifndef NDEBUG
+ virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// DIDeserializer - This class is responsible for casting GlobalVariables
+/// into DebugInfoDesc objects.
+class DIDeserializer {
+private:
+ std::map<GlobalVariable *, DebugInfoDesc *> GlobalDescs;
+ // Previously defined gloabls.
+
+public:
+ DIDeserializer() {}
+ ~DIDeserializer() {}
+
+ /// Deserialize - Reconstitute a GlobalVariable into it's component
+ /// DebugInfoDesc objects.
+ DebugInfoDesc *Deserialize(Value *V);
+ DebugInfoDesc *Deserialize(GlobalVariable *GV);
+};
+
+//===----------------------------------------------------------------------===//
+/// DISerializer - This class is responsible for casting DebugInfoDesc objects
+/// into GlobalVariables.
+class DISerializer {
+private:
+ Module *M; // Definition space module.
+ PointerType *StrPtrTy; // A "sbyte *" type. Created lazily.
+ PointerType *EmptyStructPtrTy; // A "{ }*" type. Created lazily.
+ std::map<unsigned, StructType *> TagTypes;
+ // Types per Tag. Created lazily.
+ std::map<DebugInfoDesc *, GlobalVariable *> DescGlobals;
+ // Previously defined descriptors.
+ std::map<const std::string, Constant *> StringCache;
+ // Previously defined strings.
+
+public:
+ DISerializer()
+ : M(NULL)
+ , StrPtrTy(NULL)
+ , EmptyStructPtrTy(NULL)
+ , TagTypes()
+ , DescGlobals()
+ , StringCache()
+ {}
+ ~DISerializer() {}
+
+ // Accessors
+ Module *getModule() const { return M; };
+ void setModule(Module *module) { M = module; }
+
+ /// getStrPtrType - Return a "sbyte *" type.
+ ///
+ const PointerType *getStrPtrType();
+
+ /// getEmptyStructPtrType - Return a "{ }*" type.
+ ///
+ const PointerType *getEmptyStructPtrType();
+
+ /// getTagType - Return the type describing the specified descriptor (via
+ /// tag.)
+ const StructType *getTagType(DebugInfoDesc *DD);
+
+ /// getString - Construct the string as constant string global.
+ ///
+ Constant *getString(const std::string &String);
+
+ /// Serialize - Recursively cast the specified descriptor into a
+ /// GlobalVariable so that it can be serialized to a .bc or .ll file.
+ GlobalVariable *Serialize(DebugInfoDesc *DD);
+};
+
+//===----------------------------------------------------------------------===//
+/// DIVerifier - This class is responsible for verifying the given network of
+/// GlobalVariables are valid as DebugInfoDesc objects.
+class DIVerifier {
+private:
+ enum {
+ Unknown = 0,
+ Invalid,
+ Valid
+ };
+ std::map<GlobalVariable *, unsigned> Validity;// Tracks prior results.
+ std::map<unsigned, unsigned> Counts; // Count of fields per Tag type.
+
+public:
+ DIVerifier()
+ : Validity()
+ , Counts()
+ {}
+ ~DIVerifier() {}
+
+ /// Verify - Return true if the GlobalVariable appears to be a valid
+ /// serialization of a DebugInfoDesc.
+ bool Verify(Value *V);
+ bool Verify(GlobalVariable *GV);
+};
+
+//===----------------------------------------------------------------------===//
+/// SourceLineInfo - This class is used to record source line correspondence.
+///
+class SourceLineInfo {
+private:
+ unsigned Line; // Source line number.
+ unsigned Column; // Source column.
+ unsigned SourceID; // Source ID number.
+ unsigned LabelID; // Label in code ID number.
+
+public:
+ SourceLineInfo(unsigned L, unsigned C, unsigned S, unsigned I)
+ : Line(L), Column(C), SourceID(S), LabelID(I) {}
+
+ // Accessors
+ unsigned getLine() const { return Line; }
+ unsigned getColumn() const { return Column; }
+ unsigned getSourceID() const { return SourceID; }
+ unsigned getLabelID() const { return LabelID; }
+};
+
+//===----------------------------------------------------------------------===//
+/// SourceFileInfo - This class is used to track source information.
+///
+class SourceFileInfo {
+private:
+ unsigned DirectoryID; // Directory ID number.
+ std::string Name; // File name (not including directory.)
+
+public:
+ SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
+
+ // Accessors
+ unsigned getDirectoryID() const { return DirectoryID; }
+ const std::string &getName() const { return Name; }
+
+ /// operator== - Used by UniqueVector to locate entry.
+ ///
+ bool operator==(const SourceFileInfo &SI) const {
+ return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
+ }
+
+ /// operator< - Used by UniqueVector to locate entry.
+ ///
+ bool operator<(const SourceFileInfo &SI) const {
+ return getDirectoryID() < SI.getDirectoryID() ||
+ (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugVariable - This class is used to track local variable information.
+///
+class DebugVariable {
+private:
+ VariableDesc *Desc; // Variable Descriptor.
+ unsigned FrameIndex; // Variable frame index.
+
+public:
+ DebugVariable(VariableDesc *D, unsigned I)
+ : Desc(D)
+ , FrameIndex(I)
+ {}
+
+ // Accessors.
+ VariableDesc *getDesc() const { return Desc; }
+ unsigned getFrameIndex() const { return FrameIndex; }
+};
+
+//===----------------------------------------------------------------------===//
+/// DebugScope - This class is used to track scope information.
+///
+class DebugScope {
+private:
+ DebugScope *Parent; // Parent to this scope.
+ DebugInfoDesc *Desc; // Debug info descriptor for scope.
+ // Either subprogram or block.
+ unsigned StartLabelID; // Label ID of the beginning of scope.
+ unsigned EndLabelID; // Label ID of the end of scope.
+ std::vector<DebugScope *> Scopes; // Scopes defined in scope.
+ std::vector<DebugVariable *> Variables;// Variables declared in scope.
+
+public:
+ DebugScope(DebugScope *P, DebugInfoDesc *D)
+ : Parent(P)
+ , Desc(D)
+ , StartLabelID(0)
+ , EndLabelID(0)
+ , Scopes()
+ , Variables()
+ {}
+ ~DebugScope();
+
+ // Accessors.
+ DebugScope *getParent() const { return Parent; }
+ DebugInfoDesc *getDesc() const { return Desc; }
+ unsigned getStartLabelID() const { return StartLabelID; }
+ unsigned getEndLabelID() const { return EndLabelID; }
+ std::vector<DebugScope *> &getScopes() { return Scopes; }
+ std::vector<DebugVariable *> &getVariables() { return Variables; }
+ void setStartLabelID(unsigned S) { StartLabelID = S; }
+ void setEndLabelID(unsigned E) { EndLabelID = E; }
+
+ /// AddScope - Add a scope to the scope.
+ ///
+ void AddScope(DebugScope *S) { Scopes.push_back(S); }
+
+ /// AddVariable - Add a variable to the scope.
+ ///
+ void AddVariable(DebugVariable *V) { Variables.push_back(V); }
+};
+
+//===----------------------------------------------------------------------===//
+/// LandingPadInfo - This structure is used to retain landing pad info for
+/// the current function.
+///
+struct LandingPadInfo {
+ MachineBasicBlock *LandingPadBlock; // Landing pad block.
+ SmallVector<unsigned, 1> BeginLabels; // Labels prior to invoke.
+ SmallVector<unsigned, 1> EndLabels; // Labels after invoke.
+ unsigned LandingPadLabel; // Label at beginning of landing pad.
+ Function *Personality; // Personality function.
+ std::vector<int> TypeIds; // List of type ids (filters negative)
+
+ LandingPadInfo(MachineBasicBlock *MBB)
+ : LandingPadBlock(MBB)
+ , LandingPadLabel(0)
+ , Personality(NULL)
+ , TypeIds(1, 0) // Always have cleanups
+ {}
+};
+
+//===----------------------------------------------------------------------===//
+/// MachineModuleInfo - This class contains meta information specific to a
+/// module. Queries can be made by different debugging and exception handling
+/// schemes and reformated for specific use.
+///
+class MachineModuleInfo : public ImmutablePass {
+private:
+ // Use the same deserializer/verifier for the module.
+ DIDeserializer DR;
+ DIVerifier VR;
+
+ // CompileUnits - Uniquing vector for compile units.
+ UniqueVector<CompileUnitDesc *> CompileUnits;
+
+ // Directories - Uniquing vector for directories.
+ UniqueVector<std::string> Directories;
+
+ // SourceFiles - Uniquing vector for source files.
+ UniqueVector<SourceFileInfo> SourceFiles;
+
+ // Lines - List of of source line correspondence.
+ std::vector<SourceLineInfo> Lines;
+
+ // LabelIDList - One entry per assigned label. Normally the entry is equal to
+ // the list index(+1). If the entry is zero then the label has been deleted.
+ // Any other value indicates the label has been deleted by is mapped to
+ // another label.
+ std::vector<unsigned> LabelIDList;
+
+ // ScopeMap - Tracks the scopes in the current function.
+ std::map<DebugInfoDesc *, DebugScope *> ScopeMap;
+
+ // RootScope - Top level scope for the current function.
+ //
+ DebugScope *RootScope;
+
+ // FrameMoves - List of moves done by a function's prolog. Used to construct
+ // frame maps by debug and exception handling consumers.
+ std::vector<MachineMove> FrameMoves;
+
+ // LandingPads - List of LandingPadInfo describing the landing pad information
+ // in the current function.
+ std::vector<LandingPadInfo> LandingPads;
+
+ // TypeInfos - List of C++ TypeInfo used in the current function.
+ //
+ std::vector<GlobalVariable *> TypeInfos;
+
+ // FilterIds - List of typeids encoding filters used in the current function.
+ //
+ std::vector<unsigned> FilterIds;
+
+ // FilterEnds - List of the indices in FilterIds corresponding to filter
+ // terminators.
+ //
+ std::vector<unsigned> FilterEnds;
+
+ // Personalities - Vector of all personality functions ever seen. Used to emit
+ // common EH frames.
+ std::vector<Function *> Personalities;
+
+ bool CallsEHReturn;
+ bool CallsUnwindInit;
+public:
+ static char ID; // Pass identification, replacement for typeid
+
+ MachineModuleInfo();
+ ~MachineModuleInfo();
+
+ /// doInitialization - Initialize the state for a new module.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Tear down the state after completion of a module.
+ ///
+ bool doFinalization();
+
+ /// BeginFunction - Begin gathering function meta information.
+ ///
+ void BeginFunction(MachineFunction *MF);
+
+ /// EndFunction - Discard function meta information.
+ ///
+ void EndFunction();
+
+ /// getDescFor - Convert a Value to a debug information descriptor.
+ ///
+ // FIXME - use new Value type when available.
+ DebugInfoDesc *getDescFor(Value *V);
+
+ /// Verify - Verify that a Value is debug information descriptor.
+ ///
+ bool Verify(Value *V);
+
+ /// AnalyzeModule - Scan the module for global debug information.
+ ///
+ void AnalyzeModule(Module &M);
+
+ /// hasDebugInfo - Returns true if valid debug info is present.
+ ///
+ bool hasDebugInfo() const { return !CompileUnits.empty(); }
+
+ /// needsFrameInfo - Returns true if we need to gather callee-saved register
+ /// move info for the frame.
+ bool needsFrameInfo() const;
+
+ bool callsEHReturn() const { return CallsEHReturn; }
+ void setCallsEHReturn(bool b) { CallsEHReturn = b; }
+
+ bool callsUnwindInit() const { return CallsUnwindInit; }
+ void setCallsUnwindInit(bool b) { CallsUnwindInit = b; }
+
+ /// NextLabelID - Return the next unique label id.
+ ///
+ unsigned NextLabelID() {
+ unsigned ID = LabelIDList.size() + 1;
+ LabelIDList.push_back(ID);
+ return ID;
+ }
+
+ /// RecordLabel - Records location information and associates it with a
+ /// label. Returns a unique label ID used to generate a label and
+ /// provide correspondence to the source line list.
+ unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source);
+
+ /// InvalidateLabel - Inhibit use of the specified label # from
+ /// MachineModuleInfo, for example because the code was deleted.
+ void InvalidateLabel(unsigned LabelID) {
+ // Remap to zero to indicate deletion.
+ RemapLabel(LabelID, 0);
+ }
+
+ /// RemapLabel - Indicate that a label has been merged into another.
+ ///
+ void RemapLabel(unsigned OldLabelID, unsigned NewLabelID) {
+ assert(0 < OldLabelID && OldLabelID <= LabelIDList.size() &&
+ "Old label ID out of range.");
+ assert(NewLabelID <= LabelIDList.size() &&
+ "New label ID out of range.");
+ LabelIDList[OldLabelID - 1] = NewLabelID;
+ }
+
+ /// MappedLabel - Find out the label's final ID. Zero indicates deletion.
+ /// ID != Mapped ID indicates that the label was folded into another label.
+ unsigned MappedLabel(unsigned LabelID) const {
+ assert(LabelID <= LabelIDList.size() && "Debug label ID out of range.");
+ return LabelID ? LabelIDList[LabelID - 1] : 0;
+ }
+
+ /// RecordSource - Register a source file with debug info. Returns an source
+ /// ID.
+ unsigned RecordSource(const std::string &Directory,
+ const std::string &Source);
+ unsigned RecordSource(const CompileUnitDesc *CompileUnit);
+
+ /// getDirectories - Return the UniqueVector of std::string representing
+ /// directories.
+ const UniqueVector<std::string> &getDirectories() const {
+ return Directories;
+ }
+
+ /// getSourceFiles - Return the UniqueVector of source files.
+ ///
+ const UniqueVector<SourceFileInfo> &getSourceFiles() const {
+ return SourceFiles;
+ }
+
+ /// getSourceLines - Return a vector of source lines.
+ ///
+ const std::vector<SourceLineInfo> &getSourceLines() const {
+ return Lines;
+ }
+
+ /// SetupCompileUnits - Set up the unique vector of compile units.
+ ///
+ void SetupCompileUnits(Module &M);
+
+ /// getCompileUnits - Return a vector of debug compile units.
+ ///
+ const UniqueVector<CompileUnitDesc *> getCompileUnits() const;
+
+ /// getGlobalVariablesUsing - Return all of the GlobalVariables that use the
+ /// named GlobalVariable.
+ std::vector<GlobalVariable*>
+ getGlobalVariablesUsing(Module &M, const std::string &RootName);
+
+ /// getAnchoredDescriptors - Return a vector of anchored debug descriptors.
+ ///
+ template <class T>std::vector<T *> getAnchoredDescriptors(Module &M) {
+ T Desc;
+ std::vector<GlobalVariable *> Globals =
+ getGlobalVariablesUsing(M, Desc.getAnchorString());
+ std::vector<T *> AnchoredDescs;
+ for (unsigned i = 0, N = Globals.size(); i < N; ++i) {
+ GlobalVariable *GV = Globals[i];
+
+ // FIXME - In the short term, changes are too drastic to continue.
+ if (DebugInfoDesc::TagFromGlobal(GV) == Desc.getTag() &&
+ DebugInfoDesc::VersionFromGlobal(GV) == LLVMDebugVersion) {
+ AnchoredDescs.push_back(cast<T>(DR.Deserialize(GV)));
+ }
+ }
+
+ return AnchoredDescs;
+ }
+
+ /// RecordRegionStart - Indicate the start of a region.
+ ///
+ unsigned RecordRegionStart(Value *V);
+
+ /// RecordRegionEnd - Indicate the end of a region.
+ ///
+ unsigned RecordRegionEnd(Value *V);
+
+ /// RecordVariable - Indicate the declaration of a local variable.
+ ///
+ void RecordVariable(Value *V, unsigned FrameIndex);
+
+ /// getRootScope - Return current functions root scope.
+ ///
+ DebugScope *getRootScope() { return RootScope; }
+
+ /// getOrCreateScope - Returns the scope associated with the given descriptor.
+ ///
+ DebugScope *getOrCreateScope(DebugInfoDesc *ScopeDesc);
+
+ /// getFrameMoves - Returns a reference to a list of moves done in the current
+ /// function's prologue. Used to construct frame maps for debug and exception
+ /// handling comsumers.
+ std::vector<MachineMove> &getFrameMoves() { return FrameMoves; }
+
+ //===-EH-----------------------------------------------------------------===//
+
+ /// getOrCreateLandingPadInfo - Find or create an LandingPadInfo for the
+ /// specified MachineBasicBlock.
+ LandingPadInfo &getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad);
+
+ /// addInvoke - Provide the begin and end labels of an invoke style call and
+ /// associate it with a try landing pad block.
+ void addInvoke(MachineBasicBlock *LandingPad, unsigned BeginLabel,
+ unsigned EndLabel);
+
+ /// addLandingPad - Add a new panding pad. Returns the label ID for the
+ /// landing pad entry.
+ unsigned addLandingPad(MachineBasicBlock *LandingPad);
+
+ /// addPersonality - Provide the personality function for the exception
+ /// information.
+ void addPersonality(MachineBasicBlock *LandingPad, Function *Personality);
+
+ /// getPersonalityIndex - Get index of the current personality function inside
+ /// Personalitites array
+ unsigned getPersonalityIndex() const;
+
+ /// getPersonalities - Return array of personality functions ever seen.
+ const std::vector<Function *>& getPersonalities() const {
+ return Personalities;
+ }
+
+ /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
+ ///
+ void addCatchTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo);
+
+ /// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
+ ///
+ void addFilterTypeInfo(MachineBasicBlock *LandingPad,
+ std::vector<GlobalVariable *> &TyInfo);
+
+ /// getTypeIDFor - Return the type id for the specified typeinfo. This is
+ /// function wide.
+ unsigned getTypeIDFor(GlobalVariable *TI);
+
+ /// getFilterIDFor - Return the id of the filter encoded by TyIds. This is
+ /// function wide.
+ int getFilterIDFor(std::vector<unsigned> &TyIds);
+
+ /// TidyLandingPads - Remap landing pad labels and remove any deleted landing
+ /// pads.
+ void TidyLandingPads();
+
+ /// getLandingPads - Return a reference to the landing pad info for the
+ /// current function.
+ const std::vector<LandingPadInfo> &getLandingPads() const {
+ return LandingPads;
+ }
+
+ /// getTypeInfos - Return a reference to the C++ typeinfo for the current
+ /// function.
+ const std::vector<GlobalVariable *> &getTypeInfos() const {
+ return TypeInfos;
+ }
+
+ /// getFilterIds - Return a reference to the typeids encoding filters used in
+ /// the current function.
+ const std::vector<unsigned> &getFilterIds() const {
+ return FilterIds;
+ }
+
+ /// getPersonality - Return a personality function if available. The presence
+ /// of one is required to emit exception handling info.
+ Function *getPersonality() const;
+
+}; // End class MachineModuleInfo
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/MachinePassRegistry.h b/include/llvm/CodeGen/MachinePassRegistry.h
new file mode 100644
index 0000000..4bb34b0
--- /dev/null
+++ b/include/llvm/CodeGen/MachinePassRegistry.h
@@ -0,0 +1,156 @@
+//===-- llvm/CodeGen/MachinePassRegistry.h ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the mechanics for machine function pass registries. A
+// function pass registry (MachinePassRegistry) is auto filled by the static
+// constructors of MachinePassRegistryNode. Further there is a command line
+// parser (RegisterPassParser) which listens to each registry for additions
+// and deletions, so that the appropriate command option is updated.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+#define LLVM_CODEGEN_MACHINEPASSREGISTRY_H
+
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+
+typedef void *(*MachinePassCtor)();
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryListener - Listener to adds and removals of nodes in
+/// registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryListener {
+public:
+ MachinePassRegistryListener() {}
+ virtual ~MachinePassRegistryListener() {}
+ virtual void NotifyAdd(const char *N, MachinePassCtor C, const char *D) = 0;
+ virtual void NotifyRemove(const char *N) = 0;
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistryNode - Machine pass node stored in registration list.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistryNode {
+
+private:
+
+ MachinePassRegistryNode *Next; // Next function pass in list.
+ const char *Name; // Name of function pass.
+ const char *Description; // Description string.
+ MachinePassCtor Ctor; // Function pass creator.
+
+public:
+
+ MachinePassRegistryNode(const char *N, const char *D, MachinePassCtor C)
+ : Next(NULL)
+ , Name(N)
+ , Description(D)
+ , Ctor(C)
+ {}
+
+ // Accessors
+ MachinePassRegistryNode *getNext() const { return Next; }
+ MachinePassRegistryNode **getNextAddress() { return &Next; }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+ MachinePassCtor getCtor() const { return Ctor; }
+ void setNext(MachinePassRegistryNode *N) { Next = N; }
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// MachinePassRegistry - Track the registration of machine passes.
+///
+//===----------------------------------------------------------------------===//
+class MachinePassRegistry {
+
+private:
+
+ MachinePassRegistryNode *List; // List of registry nodes.
+ MachinePassCtor Default; // Default function pass creator.
+ MachinePassRegistryListener* Listener;// Listener for list adds are removes.
+
+public:
+
+ // NO CONSTRUCTOR - we don't want static constructor ordering to mess
+ // with the registry.
+
+ // Accessors.
+ //
+ MachinePassRegistryNode *getList() { return List; }
+ MachinePassCtor getDefault() { return Default; }
+ void setDefault(MachinePassCtor C) { Default = C; }
+ void setListener(MachinePassRegistryListener *L) { Listener = L; }
+
+ /// Add - Adds a function pass to the registration list.
+ ///
+ void Add(MachinePassRegistryNode *Node);
+
+ /// Remove - Removes a function pass from the registration list.
+ ///
+ void Remove(MachinePassRegistryNode *Node);
+
+};
+
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterPassParser class - Handle the addition of new machine passes.
+///
+//===----------------------------------------------------------------------===//
+template<class RegistryClass>
+class RegisterPassParser : public MachinePassRegistryListener,
+ public cl::parser<typename RegistryClass::FunctionPassCtor> {
+public:
+ RegisterPassParser() {}
+ ~RegisterPassParser() { RegistryClass::setListener(NULL); }
+
+ void initialize(cl::Option &O) {
+ cl::parser<typename RegistryClass::FunctionPassCtor>::initialize(O);
+
+ // Add existing passes to option.
+ for (RegistryClass *Node = RegistryClass::getList();
+ Node; Node = Node->getNext()) {
+ addLiteralOption(Node->getName(),
+ (typename RegistryClass::FunctionPassCtor)Node->getCtor(),
+ Node->getDescription());
+ }
+
+ // Make sure we listen for list changes.
+ RegistryClass::setListener(this);
+ }
+
+ // Implement the MachinePassRegistryListener callbacks.
+ //
+ virtual void NotifyAdd(const char *N,
+ MachinePassCtor C,
+ const char *D) {
+ this->addLiteralOption(N, (typename RegistryClass::FunctionPassCtor)C, D);
+ }
+ virtual void NotifyRemove(const char *N) {
+ this->removeLiteralOption(N);
+ }
+};
+
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/MachineRelocation.h b/include/llvm/CodeGen/MachineRelocation.h
new file mode 100644
index 0000000..364b8b1
--- /dev/null
+++ b/include/llvm/CodeGen/MachineRelocation.h
@@ -0,0 +1,298 @@
+//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MachineRelocation class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
+#define LLVM_CODEGEN_MACHINERELOCATION_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+class GlobalValue;
+class MachineBasicBlock;
+
+/// MachineRelocation - This represents a target-specific relocation value,
+/// produced by the code emitter. This relocation is resolved after the has
+/// been emitted, either to an object file or to memory, when the target of the
+/// relocation can be resolved.
+///
+/// A relocation is made up of the following logical portions:
+/// 1. An offset in the machine code buffer, the location to modify.
+/// 2. A target specific relocation type (a number from 0 to 63).
+/// 3. A symbol being referenced, either as a GlobalValue* or as a string.
+/// 4. An optional constant value to be added to the reference.
+/// 5. A bit, CanRewrite, which indicates to the JIT that a function stub is
+/// not needed for the relocation.
+/// 6. An index into the GOT, if the target uses a GOT
+///
+class MachineRelocation {
+ enum AddressType {
+ isResult, // Relocation has be transformed into its result pointer.
+ isGV, // The Target.GV field is valid.
+ isBB, // Relocation of BB address.
+ isExtSym, // The Target.ExtSym field is valid.
+ isConstPool, // Relocation of constant pool address.
+ isJumpTable, // Relocation of jump table address.
+ isGOTIndex // The Target.GOTIndex field is valid.
+ };
+
+ /// Offset - This is the offset from the start of the code buffer of the
+ /// relocation to perform.
+ intptr_t Offset;
+
+ /// ConstantVal - A field that may be used by the target relocation type.
+ intptr_t ConstantVal;
+
+ union {
+ void *Result; // If this has been resolved to a resolved pointer
+ GlobalValue *GV; // If this is a pointer to an LLVM global
+ MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
+ const char *ExtSym; // If this is a pointer to a named symbol
+ unsigned Index; // Constant pool / jump table index
+ unsigned GOTIndex; // Index in the GOT of this symbol/global
+ } Target;
+
+ unsigned TargetReloType : 6; // The target relocation ID.
+ AddressType AddrType : 4; // The field of Target to use.
+ bool DoesntNeedFnStub : 1; // True if we don't need a fn stub.
+ bool GOTRelative : 1; // Should this relocation be relative to the GOT?
+
+public:
+ // Relocation types used in a generic implementation. Currently, relocation
+ // entries for all things use the generic VANILLA type until they are refined
+ // into target relocation types.
+ enum RelocationType {
+ VANILLA
+ };
+
+ /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
+ ///
+ static MachineRelocation getGV(intptr_t offset, unsigned RelocationType,
+ GlobalValue *GV, intptr_t cst = 0,
+ bool DoesntNeedFunctionStub = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isGV;
+ Result.DoesntNeedFnStub = DoesntNeedFunctionStub;
+ Result.GOTRelative = GOTrelative;
+ Result.Target.GV = GV;
+ return Result;
+ }
+
+ /// MachineRelocation::getBB - Return a relocation entry for a BB.
+ ///
+ static MachineRelocation getBB(intptr_t offset,unsigned RelocationType,
+ MachineBasicBlock *MBB, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isBB;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.MBB = MBB;
+ return Result;
+ }
+
+ /// MachineRelocation::getExtSym - Return a relocation entry for an external
+ /// symbol, like "free".
+ ///
+ static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType,
+ const char *ES, intptr_t cst = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isExtSym;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = GOTrelative;
+ Result.Target.ExtSym = ES;
+ return Result;
+ }
+
+ /// MachineRelocation::getConstPool - Return a relocation entry for a constant
+ /// pool entry.
+ ///
+ static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType,
+ unsigned CPI, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isConstPool;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.Index = CPI;
+ return Result;
+ }
+
+ /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
+ /// table entry.
+ ///
+ static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType,
+ unsigned JTI, intptr_t cst = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isJumpTable;
+ Result.DoesntNeedFnStub = false;
+ Result.GOTRelative = false;
+ Result.Target.Index = JTI;
+ return Result;
+ }
+
+ /// getMachineCodeOffset - Return the offset into the code buffer that the
+ /// relocation should be performed.
+ intptr_t getMachineCodeOffset() const {
+ return Offset;
+ }
+
+ /// getRelocationType - Return the target-specific relocation ID for this
+ /// relocation.
+ unsigned getRelocationType() const {
+ return TargetReloType;
+ }
+
+ /// getConstantVal - Get the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ intptr_t getConstantVal() const {
+ return ConstantVal;
+ }
+
+ /// setConstantVal - Set the constant value associated with this relocation.
+ /// This is often an offset from the symbol.
+ ///
+ void setConstantVal(intptr_t val) {
+ ConstantVal = val;
+ }
+
+ /// isGlobalValue - Return true if this relocation is a GlobalValue, as
+ /// opposed to a constant string.
+ bool isGlobalValue() const {
+ return AddrType == isGV;
+ }
+
+ /// isBasicBlock - Return true if this relocation is a basic block reference.
+ ///
+ bool isBasicBlock() const {
+ return AddrType == isBB;
+ }
+
+ /// isString - Return true if this is a constant string.
+ ///
+ bool isString() const {
+ return AddrType == isExtSym;
+ }
+
+ /// isConstantPoolIndex - Return true if this is a constant pool reference.
+ ///
+ bool isConstantPoolIndex() const {
+ return AddrType == isConstPool;
+ }
+
+ /// isJumpTableIndex - Return true if this is a jump table reference.
+ ///
+ bool isJumpTableIndex() const {
+ return AddrType == isJumpTable;
+ }
+
+ /// isGOTRelative - Return true the target wants the index into the GOT of
+ /// the symbol rather than the address of the symbol.
+ bool isGOTRelative() const {
+ return GOTRelative;
+ }
+
+ /// doesntNeedFunctionStub - This function returns true if the JIT for this
+ /// target is capable of directly handling the relocated instruction without
+ /// using a stub function. It is always conservatively correct for this flag
+ /// to be false, but targets can improve their compilation callback functions
+ /// to handle more general cases if they want improved performance.
+ bool doesntNeedFunctionStub() const {
+ return DoesntNeedFnStub;
+ }
+
+ /// getGlobalValue - If this is a global value reference, return the
+ /// referenced global.
+ GlobalValue *getGlobalValue() const {
+ assert(isGlobalValue() && "This is not a global value reference!");
+ return Target.GV;
+ }
+
+ MachineBasicBlock *getBasicBlock() const {
+ assert(isBasicBlock() && "This is not a basic block reference!");
+ return Target.MBB;
+ }
+
+ /// getString - If this is a string value, return the string reference.
+ ///
+ const char *getString() const {
+ assert(isString() && "This is not a string reference!");
+ return Target.ExtSym;
+ }
+
+ /// getConstantPoolIndex - If this is a const pool reference, return
+ /// the index into the constant pool.
+ unsigned getConstantPoolIndex() const {
+ assert(isConstantPoolIndex() && "This is not a constant pool reference!");
+ return Target.Index;
+ }
+
+ /// getJumpTableIndex - If this is a jump table reference, return
+ /// the index into the jump table.
+ unsigned getJumpTableIndex() const {
+ assert(isJumpTableIndex() && "This is not a jump table reference!");
+ return Target.Index;
+ }
+
+ /// getResultPointer - Once this has been resolved to point to an actual
+ /// address, this returns the pointer.
+ void *getResultPointer() const {
+ assert(AddrType == isResult && "Result pointer isn't set yet!");
+ return Target.Result;
+ }
+
+ /// setResultPointer - Set the result to the specified pointer value.
+ ///
+ void setResultPointer(void *Ptr) {
+ Target.Result = Ptr;
+ AddrType = isResult;
+ }
+
+ /// setGOTIndex - Set the GOT index to a specific value.
+ void setGOTIndex(unsigned idx) {
+ AddrType = isGOTIndex;
+ Target.GOTIndex = idx;
+ }
+
+ /// getGOTIndex - Once this has been resolved to an entry in the GOT,
+ /// this returns that index. The index is from the lowest address entry
+ /// in the GOT.
+ unsigned getGOTIndex() const {
+ assert(AddrType == isGOTIndex);
+ return Target.GOTIndex;
+ }
+};
+}
+
+#endif
diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h
new file mode 100644
index 0000000..eda6a5d
--- /dev/null
+++ b/include/llvm/CodeGen/Passes.h
@@ -0,0 +1,120 @@
+//===-- Passes.h - Target independent code generation passes ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces to access the target independent code generation
+// passes provided by the LLVM backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_PASSES_H
+#define LLVM_CODEGEN_PASSES_H
+
+#include <iosfwd>
+#include <string>
+
+namespace llvm {
+
+ class FunctionPass;
+ class PassInfo;
+ class TargetMachine;
+
+ /// createUnreachableBlockEliminationPass - The LLVM code generator does not
+ /// work well with unreachable basic blocks (what live ranges make sense for a
+ /// block that cannot be reached?). As such, a code generator should either
+ /// not instruction select unreachable blocks, or it can run this pass as it's
+ /// last LLVM modifying pass to clean up blocks that are not reachable from
+ /// the entry block.
+ FunctionPass *createUnreachableBlockEliminationPass();
+
+ /// MachineFunctionPrinter pass - This pass prints out the machine function to
+ /// standard error, as a debugging tool.
+ FunctionPass *createMachineFunctionPrinterPass(std::ostream *OS,
+ const std::string &Banner ="");
+
+ /// PHIElimination pass - This pass eliminates machine instruction PHI nodes
+ /// by inserting copy instructions. This destroys SSA information, but is the
+ /// desired input for some register allocators. This pass is "required" by
+ /// these register allocator like this: AU.addRequiredID(PHIEliminationID);
+ ///
+ extern const PassInfo *PHIEliminationID;
+
+ /// SimpleRegisterCoalescing pass. Aggressively coalesces every register
+ /// copy it can.
+ ///
+ extern const PassInfo *SimpleRegisterCoalescingID;
+
+ /// TwoAddressInstruction pass - This pass reduces two-address instructions to
+ /// use two operands. This destroys SSA information but it is desired by
+ /// register allocators.
+ extern const PassInfo *TwoAddressInstructionPassID;
+
+ /// Creates a register allocator as the user specified on the command line.
+ ///
+ FunctionPass *createRegisterAllocator();
+
+ /// SimpleRegisterAllocation Pass - This pass converts the input machine code
+ /// from SSA form to use explicit registers by spilling every register. Wow,
+ /// great policy huh?
+ ///
+ FunctionPass *createSimpleRegisterAllocator();
+
+ /// LocalRegisterAllocation Pass - This pass register allocates the input code
+ /// a basic block at a time, yielding code better than the simple register
+ /// allocator, but not as good as a global allocator.
+ ///
+ FunctionPass *createLocalRegisterAllocator();
+
+ /// BigBlockRegisterAllocation Pass - The BigBlock register allocator
+ /// munches single basic blocks at a time, like the local register
+ /// allocator. While the BigBlock allocator is a little slower, and uses
+ /// somewhat more memory than the local register allocator, it tends to
+ /// yield the best allocations (of any of the allocators) for blocks that
+ /// have hundreds or thousands of instructions in sequence.
+ ///
+ FunctionPass *createBigBlockRegisterAllocator();
+
+ /// LinearScanRegisterAllocation Pass - This pass implements the linear scan
+ /// register allocation algorithm, a global register allocator.
+ ///
+ FunctionPass *createLinearScanRegisterAllocator();
+
+ /// PrologEpilogCodeInserter Pass - This pass inserts prolog and epilog code,
+ /// and eliminates abstract frame references.
+ ///
+ FunctionPass *createPrologEpilogCodeInserter();
+
+ /// createPostRAScheduler - under development.
+ FunctionPass *createPostRAScheduler();
+
+ /// BranchFolding Pass - This pass performs machine code CFG based
+ /// optimizations to delete branches to branches, eliminate branches to
+ /// successor blocks (creating fall throughs), and eliminating branches over
+ /// branches.
+ FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge);
+
+ /// IfConverter Pass - This pass performs machine code if conversion.
+ FunctionPass *createIfConverterPass();
+
+ /// DebugLabelFoldingPass - This pass prunes out redundant debug labels. This
+ /// allows a debug emitter to determine if the range of two labels is empty,
+ /// by seeing if the labels map to the same reduced label.
+ FunctionPass *createDebugLabelFoldingPass();
+
+ /// MachineCodeDeletion Pass - This pass deletes all of the machine code for
+ /// the current function, which should happen after the function has been
+ /// emitted to a .s file or to memory.
+ FunctionPass *createMachineCodeDeleter();
+
+ /// getRegisterAllocator - This creates an instance of the register allocator
+ /// for the Sparc.
+ FunctionPass *getRegisterAllocator(TargetMachine &T);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/RegAllocRegistry.h b/include/llvm/CodeGen/RegAllocRegistry.h
new file mode 100644
index 0000000..ba6a879
--- /dev/null
+++ b/include/llvm/CodeGen/RegAllocRegistry.h
@@ -0,0 +1,64 @@
+//===-- llvm/CodeGen/RegAllocRegistry.h -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for register allocator function
+// pass registry (RegisterRegAlloc).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENREGALLOCREGISTRY_H
+#define LLVM_CODEGENREGALLOCREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterRegAlloc class - Track the registration of register allocators.
+///
+//===----------------------------------------------------------------------===//
+class RegisterRegAlloc : public MachinePassRegistryNode {
+
+public:
+
+ typedef FunctionPass *(*FunctionPassCtor)();
+
+ static MachinePassRegistry Registry;
+
+ RegisterRegAlloc(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ { Registry.Add(this); }
+ ~RegisterRegAlloc() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterRegAlloc *getNext() const {
+ return (RegisterRegAlloc *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterRegAlloc *getList() {
+ return (RegisterRegAlloc *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/include/llvm/CodeGen/RegisterScavenging.h b/include/llvm/CodeGen/RegisterScavenging.h
new file mode 100644
index 0000000..ec23e76
--- /dev/null
+++ b/include/llvm/CodeGen/RegisterScavenging.h
@@ -0,0 +1,148 @@
+//===-- RegisterScavenging.h - Machine register scavenging ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the machine register scavenger class. It can provide
+// information such as unused register at any point in a machine basic block.
+// It also provides a mechanism to make registers availbale by evicting them
+// to spill slots.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_REGISTER_SCAVENGING_H
+#define LLVM_CODEGEN_REGISTER_SCAVENGING_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/ADT/BitVector.h"
+
+namespace llvm {
+
+class MRegisterInfo;
+class TargetInstrInfo;
+class TargetRegisterClass;
+
+class RegScavenger {
+ MachineBasicBlock *MBB;
+ MachineBasicBlock::iterator MBBI;
+ unsigned NumPhysRegs;
+
+ /// Tracking - True if RegScavenger is currently tracking the liveness of
+ /// registers.
+ bool Tracking;
+
+ /// ScavengingFrameIndex - Special spill slot used for scavenging a register
+ /// post register allocation.
+ int ScavengingFrameIndex;
+
+ /// ScavengedReg - If none zero, the specific register is currently being
+ /// scavenged. That is, it is spilled to the special scavenging stack slot.
+ unsigned ScavengedReg;
+
+ /// ScavengedRC - Register class of the scavenged register.
+ ///
+ const TargetRegisterClass *ScavengedRC;
+
+ /// RegsAvailable - The current state of all the physical registers immediately
+ /// before MBBI. One bit per physical register. If bit is set that means it's
+ /// available, unset means the register is currently being used.
+ BitVector RegsAvailable;
+
+public:
+ RegScavenger()
+ : MBB(NULL), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
+
+ explicit RegScavenger(MachineBasicBlock *mbb)
+ : MBB(mbb), NumPhysRegs(0), Tracking(false),
+ ScavengingFrameIndex(-1), ScavengedReg(0), ScavengedRC(NULL) {};
+
+ /// enterBasicBlock - Start tracking liveness from the begin of the specific
+ /// basic block.
+ void enterBasicBlock(MachineBasicBlock *mbb);
+
+ /// forward / backward - Move the internal MBB iterator and update register
+ /// states.
+ void forward();
+ void backward();
+
+ /// forward / backward - Move the internal MBB iterator and update register
+ /// states until it has processed the specific iterator.
+ void forward(MachineBasicBlock::iterator I) {
+ while (MBBI != I) forward();
+ }
+ void backward(MachineBasicBlock::iterator I) {
+ while (MBBI != I) backward();
+ }
+
+ /// skipTo - Move the internal MBB iterator but do not update register states.
+ ///
+ void skipTo(MachineBasicBlock::iterator I) { MBBI = I; }
+
+ /// isReserved - Returns true if a register is reserved. It is never "unused".
+ bool isReserved(unsigned Reg) const { return ReservedRegs[Reg]; }
+
+ /// isUsed / isUsed - Test if a register is currently being used.
+ ///
+ bool isUsed(unsigned Reg) const { return !RegsAvailable[Reg]; }
+ bool isUnused(unsigned Reg) const { return RegsAvailable[Reg]; }
+
+ /// getRegsUsed - return all registers currently in use in used.
+ void getRegsUsed(BitVector &used, bool includeReserved);
+
+ /// setUsed / setUnused - Mark the state of one or a number of registers.
+ ///
+ void setUsed(unsigned Reg) { RegsAvailable.reset(Reg); }
+ void setUsed(BitVector Regs) { RegsAvailable &= ~Regs; }
+ void setUnused(unsigned Reg) { RegsAvailable.set(Reg); }
+ void setUnused(BitVector Regs) { RegsAvailable |= Regs; }
+
+ /// FindUnusedReg - Find a unused register of the specified register class
+ /// from the specified set of registers. It return 0 is none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
+ const BitVector &Candidates) const;
+
+ /// FindUnusedReg - Find a unused register of the specified register class.
+ /// Exclude callee saved registers if directed. It return 0 is none is found.
+ unsigned FindUnusedReg(const TargetRegisterClass *RegClass,
+ bool ExCalleeSaved = false) const;
+
+ /// setScavengingFrameIndex / getScavengingFrameIndex - accessor and setter of
+ /// ScavengingFrameIndex.
+ void setScavengingFrameIndex(int FI) { ScavengingFrameIndex = FI; }
+ int getScavengingFrameIndex() const { return ScavengingFrameIndex; }
+
+ /// scavengeRegister - Make a register of the specific register class
+ /// available and do the appropriate bookkeeping. SPAdj is the stack
+ /// adjustment due to call frame, it's passed along to eliminateFrameIndex().
+ /// Returns the scavenged register.
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass,
+ MachineBasicBlock::iterator I, int SPAdj);
+ unsigned scavengeRegister(const TargetRegisterClass *RegClass, int SPAdj) {
+ return scavengeRegister(RegClass, MBBI, SPAdj);
+ }
+
+private:
+ const MRegisterInfo *RegInfo;
+ const TargetInstrInfo *TII;
+
+ /// CalleeSavedrRegs - A bitvector of callee saved registers for the target.
+ ///
+ BitVector CalleeSavedRegs;
+
+ /// ReservedRegs - A bitvector of reserved registers.
+ ///
+ BitVector ReservedRegs;
+
+ /// restoreScavengedReg - Restore scavenged by loading it back from the
+ /// emergency spill slot. Mark it used.
+ void restoreScavengedReg();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h
new file mode 100644
index 0000000..2609c55
--- /dev/null
+++ b/include/llvm/CodeGen/RuntimeLibcalls.h
@@ -0,0 +1,109 @@
+//===-- CodeGen/RuntimeLibcall.h - Runtime Library Calls --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the enum representing the list of runtime library calls
+// the backend may emit during code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_RUNTIMELIBCALLS_H
+#define LLVM_CODEGEN_RUNTIMELIBCALLS_H
+
+namespace llvm {
+namespace RTLIB {
+ /// RTLIB::Libcall enum - This enum defines all of the runtime library calls
+ /// the backend can emit.
+ ///
+ enum Libcall {
+ // Integer
+ SHL_I32,
+ SHL_I64,
+ SRL_I32,
+ SRL_I64,
+ SRA_I32,
+ SRA_I64,
+ MUL_I32,
+ MUL_I64,
+ SDIV_I32,
+ SDIV_I64,
+ UDIV_I32,
+ UDIV_I64,
+ SREM_I32,
+ SREM_I64,
+ UREM_I32,
+ UREM_I64,
+ NEG_I32,
+ NEG_I64,
+
+ // FLOATING POINT
+ ADD_F32,
+ ADD_F64,
+ SUB_F32,
+ SUB_F64,
+ MUL_F32,
+ MUL_F64,
+ DIV_F32,
+ DIV_F64,
+ REM_F32,
+ REM_F64,
+ NEG_F32,
+ NEG_F64,
+ POWI_F32,
+ POWI_F64,
+ SQRT_F32,
+ SQRT_F64,
+ SIN_F32,
+ SIN_F64,
+ COS_F32,
+ COS_F64,
+
+ // CONVERSION
+ FPEXT_F32_F64,
+ FPROUND_F64_F32,
+ FPTOSINT_F32_I32,
+ FPTOSINT_F32_I64,
+ FPTOSINT_F64_I32,
+ FPTOSINT_F64_I64,
+ FPTOUINT_F32_I32,
+ FPTOUINT_F32_I64,
+ FPTOUINT_F64_I32,
+ FPTOUINT_F64_I64,
+ SINTTOFP_I32_F32,
+ SINTTOFP_I32_F64,
+ SINTTOFP_I64_F32,
+ SINTTOFP_I64_F64,
+ UINTTOFP_I32_F32,
+ UINTTOFP_I32_F64,
+ UINTTOFP_I64_F32,
+ UINTTOFP_I64_F64,
+
+ // COMPARISON
+ OEQ_F32,
+ OEQ_F64,
+ UNE_F32,
+ UNE_F64,
+ OGE_F32,
+ OGE_F64,
+ OLT_F32,
+ OLT_F64,
+ OLE_F32,
+ OLE_F64,
+ OGT_F32,
+ OGT_F64,
+ UO_F32,
+ UO_F64,
+ O_F32,
+ O_F64,
+
+ UNKNOWN_LIBCALL
+ };
+}
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SSARegMap.h b/include/llvm/CodeGen/SSARegMap.h
new file mode 100644
index 0000000..97d8d69
--- /dev/null
+++ b/include/llvm/CodeGen/SSARegMap.h
@@ -0,0 +1,55 @@
+//===-- llvm/CodeGen/SSARegMap.h --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Map register numbers to register classes that are correctly sized (typed) to
+// hold the information. Assists register allocation. Contained by
+// MachineFunction, should be deleted by register allocator when it is no
+// longer needed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SSAREGMAP_H
+#define LLVM_CODEGEN_SSAREGMAP_H
+
+#include "llvm/Target/MRegisterInfo.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+class TargetRegisterClass;
+
+class SSARegMap {
+ IndexedMap<const TargetRegisterClass*, VirtReg2IndexFunctor> RegClassMap;
+ unsigned NextRegNum;
+
+ public:
+ SSARegMap() : NextRegNum(MRegisterInfo::FirstVirtualRegister) { }
+
+ const TargetRegisterClass* getRegClass(unsigned Reg) {
+ return RegClassMap[Reg];
+ }
+
+ /// createVirtualRegister - Create and return a new virtual register in the
+ /// function with the specified register class.
+ ///
+ unsigned createVirtualRegister(const TargetRegisterClass *RegClass) {
+ assert(RegClass && "Cannot create register without RegClass!");
+ RegClassMap.grow(NextRegNum);
+ RegClassMap[NextRegNum] = RegClass;
+ return NextRegNum++;
+ }
+
+ unsigned getLastVirtReg() const {
+ return NextRegNum - 1;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/SchedGraphCommon.h b/include/llvm/CodeGen/SchedGraphCommon.h
new file mode 100644
index 0000000..4fcd9ac
--- /dev/null
+++ b/include/llvm/CodeGen/SchedGraphCommon.h
@@ -0,0 +1,289 @@
+//===-- SchedGraphCommon.h - Scheduling Base Graph --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A common graph class that is based on the SSA graph. It includes
+// extra dependencies that are caused by machine resources.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDGRAPHCOMMON_H
+#define LLVM_CODEGEN_SCHEDGRAPHCOMMON_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/iterator"
+#include "llvm/Support/Streams.h"
+#include <vector>
+
+namespace llvm {
+
+class SchedGraphEdge;
+class SchedGraphNode;
+
+/******************** Exported Data Types and Constants ********************/
+
+typedef int ResourceId;
+const ResourceId InvalidRID = -1;
+const ResourceId MachineCCRegsRID = -2; // use +ve numbers for actual regs
+const ResourceId MachineIntRegsRID = -3; // use +ve numbers for actual regs
+const ResourceId MachineFPRegsRID = -4; // use +ve numbers for actual regs
+
+
+//*********************** Public Class Declarations ************************/
+class SchedGraphNodeCommon {
+protected:
+ unsigned ID;
+ std::vector<SchedGraphEdge*> inEdges;
+ std::vector<SchedGraphEdge*> outEdges;
+ int latency;
+ int origIndexInBB; // original position of instr in BB
+
+public:
+ typedef std::vector<SchedGraphEdge*>::iterator iterator;
+ typedef std::vector<SchedGraphEdge*>::const_iterator const_iterator;
+ typedef std::vector<SchedGraphEdge*>::reverse_iterator reverse_iterator;
+ typedef std::vector<SchedGraphEdge*>::const_reverse_iterator const_reverse_iterator;
+
+ // Accessor methods
+ unsigned getNodeId() const { return ID; }
+ int getLatency() const { return latency; }
+ unsigned getNumInEdges() const { return inEdges.size(); }
+ unsigned getNumOutEdges() const { return outEdges.size(); }
+ int getOrigIndexInBB() const { return origIndexInBB; }
+
+ // Iterators
+ iterator beginInEdges() { return inEdges.begin(); }
+ iterator endInEdges() { return inEdges.end(); }
+ iterator beginOutEdges() { return outEdges.begin(); }
+ iterator endOutEdges() { return outEdges.end(); }
+
+ const_iterator beginInEdges() const { return inEdges.begin(); }
+ const_iterator endInEdges() const { return inEdges.end(); }
+ const_iterator beginOutEdges() const { return outEdges.begin(); }
+ const_iterator endOutEdges() const { return outEdges.end(); }
+
+ void dump(int indent=0) const;
+
+ // Debugging support
+ virtual void print(std::ostream &os) const = 0;
+ void print(std::ostream *os) const { if (os) print(*os); }
+
+protected:
+ friend class SchedGraphCommon;
+ friend class SchedGraphEdge; // give access for adding edges
+
+
+ // disable default constructor and provide a ctor for single-block graphs
+ SchedGraphNodeCommon(); // DO NOT IMPLEMENT
+
+ inline SchedGraphNodeCommon(unsigned Id, int index, int late=0) : ID(Id), latency(late), origIndexInBB(index) {}
+
+ virtual ~SchedGraphNodeCommon();
+
+ //Functions to add and remove edges
+ inline void addInEdge(SchedGraphEdge* edge) { inEdges.push_back(edge); }
+ inline void addOutEdge(SchedGraphEdge* edge) { outEdges.push_back(edge); }
+ void removeInEdge(const SchedGraphEdge* edge);
+ void removeOutEdge(const SchedGraphEdge* edge);
+
+};
+
+// ostream << operator for SchedGraphNode class
+inline std::ostream &operator<<(std::ostream &os,
+ const SchedGraphNodeCommon &node) {
+ node.print(os);
+ return os;
+}
+
+//
+// SchedGraphEdge - Edge class to represent dependencies
+//
+class SchedGraphEdge {
+public:
+ enum SchedGraphEdgeDepType {
+ CtrlDep, MemoryDep, ValueDep, MachineRegister, MachineResource
+ };
+ enum DataDepOrderType {
+ TrueDep = 0x1, AntiDep=0x2, OutputDep=0x4, NonDataDep=0x8
+ };
+
+protected:
+ SchedGraphNodeCommon* src;
+ SchedGraphNodeCommon* sink;
+ SchedGraphEdgeDepType depType;
+ unsigned int depOrderType;
+ int minDelay; // cached latency (assumes fixed target arch)
+ int iteDiff;
+
+ union {
+ const Value* val;
+ int machineRegNum;
+ ResourceId resourceId;
+ };
+
+public:
+ // For all constructors, if minDelay is unspecified, minDelay is
+ // set to _src->getLatency().
+
+ // constructor for CtrlDep or MemoryDep edges, selected by 3rd argument
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ SchedGraphEdgeDepType _depType, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for explicit value dependence (may be true/anti/output)
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ const Value* _val, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for machine register dependence
+ SchedGraphEdge(SchedGraphNodeCommon* _src,SchedGraphNodeCommon* _sink,
+ unsigned int _regNum, unsigned int _depOrderType,
+ int _minDelay = -1);
+
+ // constructor for any other machine resource dependences.
+ // DataDepOrderType is always NonDataDep. It it not an argument to
+ // avoid overloading ambiguity with previous constructor.
+ SchedGraphEdge(SchedGraphNodeCommon* _src, SchedGraphNodeCommon* _sink,
+ ResourceId _resourceId, int _minDelay = -1);
+
+ ~SchedGraphEdge() {}
+
+ SchedGraphNodeCommon* getSrc() const { return src; }
+ SchedGraphNodeCommon* getSink() const { return sink; }
+ int getMinDelay() const { return minDelay; }
+ SchedGraphEdgeDepType getDepType() const { return depType; }
+ unsigned int getDepOrderType() const { return depOrderType; }
+
+ const Value* getValue() const {
+ assert(depType == ValueDep); return val;
+ }
+
+ int getMachineReg() const {
+ assert(depType == MachineRegister); return machineRegNum;
+ }
+
+ int getResourceId() const {
+ assert(depType == MachineResource); return resourceId;
+ }
+
+ void setIteDiff(int _iteDiff) {
+ iteDiff = _iteDiff;
+ }
+
+ int getIteDiff() {
+ return iteDiff;
+ }
+
+public:
+ // Debugging support
+ void print(std::ostream &os) const;
+ void print(std::ostream *os) const { if (os) print(*os); }
+ void dump(int indent=0) const;
+
+private:
+ // disable default ctor
+ SchedGraphEdge(); // DO NOT IMPLEMENT
+};
+
+// ostream << operator for SchedGraphNode class
+inline std::ostream &operator<<(std::ostream &os, const SchedGraphEdge &edge) {
+ edge.print(os);
+ return os;
+}
+
+class SchedGraphCommon {
+
+protected:
+ SchedGraphNodeCommon* graphRoot; // the root and leaf are not inserted
+ SchedGraphNodeCommon* graphLeaf; // in the hash_map (see getNumNodes())
+
+public:
+ //
+ // Accessor methods
+ //
+ SchedGraphNodeCommon* getRoot() const { return graphRoot; }
+ SchedGraphNodeCommon* getLeaf() const { return graphLeaf; }
+
+ //
+ // Delete nodes or edges from the graph.
+ //
+ void eraseNode(SchedGraphNodeCommon* node);
+ void eraseIncomingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+ void eraseOutgoingEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+ void eraseIncidentEdges(SchedGraphNodeCommon* node, bool addDummyEdges = true);
+
+ SchedGraphCommon() {}
+ ~SchedGraphCommon();
+};
+
+
+//********************** Sched Graph Iterators *****************************/
+
+// Ok to make it a template because it shd get instantiated at most twice:
+// for <SchedGraphNode, SchedGraphNode::iterator> and
+// for <const SchedGraphNode, SchedGraphNode::const_iterator>.
+//
+template <class _NodeType, class _EdgeType, class _EdgeIter>
+class SGPredIterator: public bidirectional_iterator<_NodeType, ptrdiff_t> {
+protected:
+ _EdgeIter oi;
+public:
+ typedef SGPredIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
+
+ inline SGPredIterator(_EdgeIter startEdge) : oi(startEdge) {}
+
+ inline bool operator==(const _Self& x) const { return oi == x.oi; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ // operator*() differs for pred or succ iterator
+ inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSrc(); }
+ inline _NodeType* operator->() const { return operator*(); }
+
+ inline _EdgeType* getEdge() const { return *(oi); }
+
+ inline _Self &operator++() { ++oi; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp(*this); ++*this; return tmp;
+ }
+
+ inline _Self &operator--() { --oi; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+
+template <class _NodeType, class _EdgeType, class _EdgeIter>
+class SGSuccIterator : public bidirectional_iterator<_NodeType, ptrdiff_t> {
+protected:
+ _EdgeIter oi;
+public:
+ typedef SGSuccIterator<_NodeType, _EdgeType, _EdgeIter> _Self;
+
+ inline SGSuccIterator(_EdgeIter startEdge) : oi(startEdge) {}
+
+ inline bool operator==(const _Self& x) const { return oi == x.oi; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline _NodeType* operator*() const { return (_NodeType*)(*oi)->getSink(); }
+ inline _NodeType* operator->() const { return operator*(); }
+
+ inline _EdgeType* getEdge() const { return *(oi); }
+
+ inline _Self &operator++() { ++oi; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp(*this); ++*this; return tmp;
+ }
+
+ inline _Self &operator--() { --oi; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ScheduleDAG.h b/include/llvm/CodeGen/ScheduleDAG.h
new file mode 100644
index 0000000..06d2f2e
--- /dev/null
+++ b/include/llvm/CodeGen/ScheduleDAG.h
@@ -0,0 +1,306 @@
+//===------- llvm/CodeGen/ScheduleDAG.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the ScheduleDAG class, which is used as the common
+// base class for SelectionDAG-based instruction scheduler.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SCHEDULEDAG_H
+#define LLVM_CODEGEN_SCHEDULEDAG_H
+
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallSet.h"
+
+namespace llvm {
+ struct InstrStage;
+ class MachineConstantPool;
+ class MachineModuleInfo;
+ class MachineInstr;
+ class MRegisterInfo;
+ class SelectionDAG;
+ class SelectionDAGISel;
+ class SSARegMap;
+ class TargetInstrInfo;
+ class TargetInstrDescriptor;
+ class TargetMachine;
+
+ /// HazardRecognizer - This determines whether or not an instruction can be
+ /// issued this cycle, and whether or not a noop needs to be inserted to handle
+ /// the hazard.
+ class HazardRecognizer {
+ public:
+ virtual ~HazardRecognizer();
+
+ enum HazardType {
+ NoHazard, // This instruction can be emitted at this cycle.
+ Hazard, // This instruction can't be emitted at this cycle.
+ NoopHazard // This instruction can't be emitted, and needs noops.
+ };
+
+ /// getHazardType - Return the hazard type of emitting this node. There are
+ /// three possible results. Either:
+ /// * NoHazard: it is legal to issue this instruction on this cycle.
+ /// * Hazard: issuing this instruction would stall the machine. If some
+ /// other instruction is available, issue it first.
+ /// * NoopHazard: issuing this instruction would break the program. If
+ /// some other instruction can be issued, do so, otherwise issue a noop.
+ virtual HazardType getHazardType(SDNode *Node) {
+ return NoHazard;
+ }
+
+ /// EmitInstruction - This callback is invoked when an instruction is
+ /// emitted, to advance the hazard state.
+ virtual void EmitInstruction(SDNode *Node) {
+ }
+
+ /// AdvanceCycle - This callback is invoked when no instructions can be
+ /// issued on this cycle without a hazard. This should increment the
+ /// internal state of the hazard recognizer so that previously "Hazard"
+ /// instructions will now not be hazards.
+ virtual void AdvanceCycle() {
+ }
+
+ /// EmitNoop - This callback is invoked when a noop was added to the
+ /// instruction stream.
+ virtual void EmitNoop() {
+ }
+ };
+
+ /// SUnit - Scheduling unit. It's an wrapper around either a single SDNode or
+ /// a group of nodes flagged together.
+ struct SUnit {
+ SDNode *Node; // Representative node.
+ SmallVector<SDNode*,4> FlaggedNodes;// All nodes flagged to Node.
+
+ // Preds/Succs - The SUnits before/after us in the graph. The boolean value
+ // is true if the edge is a token chain edge, false if it is a value edge.
+ SmallVector<std::pair<SUnit*,bool>, 4> Preds; // All sunit predecessors.
+ SmallVector<std::pair<SUnit*,bool>, 4> Succs; // All sunit successors.
+
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator pred_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::iterator succ_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
+ const_pred_iterator;
+ typedef SmallVector<std::pair<SUnit*,bool>, 4>::const_iterator
+ const_succ_iterator;
+
+ short NumPreds; // # of preds.
+ short NumSuccs; // # of sucss.
+ short NumPredsLeft; // # of preds not scheduled.
+ short NumSuccsLeft; // # of succs not scheduled.
+ short NumChainPredsLeft; // # of chain preds not scheduled.
+ short NumChainSuccsLeft; // # of chain succs not scheduled.
+ bool isTwoAddress : 1; // Is a two-address instruction.
+ bool isCommutable : 1; // Is a commutable instruction.
+ bool isPending : 1; // True once pending.
+ bool isAvailable : 1; // True once available.
+ bool isScheduled : 1; // True once scheduled.
+ unsigned short Latency; // Node latency.
+ unsigned CycleBound; // Upper/lower cycle to be scheduled at.
+ unsigned Cycle; // Once scheduled, the cycle of the op.
+ unsigned Depth; // Node depth;
+ unsigned Height; // Node height;
+ unsigned NodeNum; // Entry # of node in the node vector.
+
+ SUnit(SDNode *node, unsigned nodenum)
+ : Node(node), NumPreds(0), NumSuccs(0), NumPredsLeft(0), NumSuccsLeft(0),
+ NumChainPredsLeft(0), NumChainSuccsLeft(0),
+ isTwoAddress(false), isCommutable(false),
+ isPending(false), isAvailable(false), isScheduled(false),
+ Latency(0), CycleBound(0), Cycle(0), Depth(0), Height(0),
+ NodeNum(nodenum) {}
+
+ /// addPred - This adds the specified node as a pred of the current node if
+ /// not already. This returns true if this is a new pred.
+ bool addPred(SUnit *N, bool isChain) {
+ for (unsigned i = 0, e = Preds.size(); i != e; ++i)
+ if (Preds[i].first == N && Preds[i].second == isChain)
+ return false;
+ Preds.push_back(std::make_pair(N, isChain));
+ return true;
+ }
+
+ /// addSucc - This adds the specified node as a succ of the current node if
+ /// not already. This returns true if this is a new succ.
+ bool addSucc(SUnit *N, bool isChain) {
+ for (unsigned i = 0, e = Succs.size(); i != e; ++i)
+ if (Succs[i].first == N && Succs[i].second == isChain)
+ return false;
+ Succs.push_back(std::make_pair(N, isChain));
+ return true;
+ }
+
+ void dump(const SelectionDAG *G) const;
+ void dumpAll(const SelectionDAG *G) const;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// SchedulingPriorityQueue - This interface is used to plug different
+ /// priorities computation algorithms into the list scheduler. It implements
+ /// the interface of a standard priority queue, where nodes are inserted in
+ /// arbitrary order and returned in priority order. The computation of the
+ /// priority and the representation of the queue are totally up to the
+ /// implementation to decide.
+ ///
+ class SchedulingPriorityQueue {
+ public:
+ virtual ~SchedulingPriorityQueue() {}
+
+ virtual void initNodes(DenseMap<SDNode*, SUnit*> &SUMap,
+ std::vector<SUnit> &SUnits) = 0;
+ virtual void releaseState() = 0;
+
+ virtual bool empty() const = 0;
+ virtual void push(SUnit *U) = 0;
+
+ virtual void push_all(const std::vector<SUnit *> &Nodes) = 0;
+ virtual SUnit *pop() = 0;
+
+ /// ScheduledNode - As each node is scheduled, this method is invoked. This
+ /// allows the priority function to adjust the priority of node that have
+ /// already been emitted.
+ virtual void ScheduledNode(SUnit *Node) {}
+ };
+
+ class ScheduleDAG {
+ public:
+ SelectionDAG &DAG; // DAG of the current basic block
+ MachineBasicBlock *BB; // Current basic block
+ const TargetMachine &TM; // Target processor
+ const TargetInstrInfo *TII; // Target instruction information
+ const MRegisterInfo *MRI; // Target processor register info
+ SSARegMap *RegMap; // Virtual/real register map
+ MachineConstantPool *ConstPool; // Target constant pool
+ std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s
+ // represent noop instructions.
+ DenseMap<SDNode*, SUnit*> SUnitMap; // SDNode to SUnit mapping (n -> 1).
+ std::vector<SUnit> SUnits; // The scheduling units.
+ SmallSet<SDNode*, 16> CommuteSet; // Nodes the should be commuted.
+
+ ScheduleDAG(SelectionDAG &dag, MachineBasicBlock *bb,
+ const TargetMachine &tm)
+ : DAG(dag), BB(bb), TM(tm) {}
+
+ virtual ~ScheduleDAG() {}
+
+ /// Run - perform scheduling.
+ ///
+ MachineBasicBlock *Run();
+
+ /// isPassiveNode - Return true if the node is a non-scheduled leaf.
+ ///
+ static bool isPassiveNode(SDNode *Node) {
+ if (isa<ConstantSDNode>(Node)) return true;
+ if (isa<RegisterSDNode>(Node)) return true;
+ if (isa<GlobalAddressSDNode>(Node)) return true;
+ if (isa<BasicBlockSDNode>(Node)) return true;
+ if (isa<FrameIndexSDNode>(Node)) return true;
+ if (isa<ConstantPoolSDNode>(Node)) return true;
+ if (isa<JumpTableSDNode>(Node)) return true;
+ if (isa<ExternalSymbolSDNode>(Node)) return true;
+ return false;
+ }
+
+ /// NewSUnit - Creates a new SUnit and return a ptr to it.
+ ///
+ SUnit *NewSUnit(SDNode *N) {
+ SUnits.push_back(SUnit(N, SUnits.size()));
+ return &SUnits.back();
+ }
+
+ /// BuildSchedUnits - Build SUnits from the selection dag that we are input.
+ /// This SUnit graph is similar to the SelectionDAG, but represents flagged
+ /// together nodes with a single SUnit.
+ void BuildSchedUnits();
+
+ /// CalculateDepths, CalculateHeights - Calculate node depth / height.
+ ///
+ void CalculateDepths();
+ void CalculateHeights();
+
+ /// CountResults - The results of target nodes have register or immediate
+ /// operands first, then an optional chain, and optional flag operands
+ /// (which do not go into the machine instrs.)
+ static unsigned CountResults(SDNode *Node);
+
+ /// CountOperands The inputs to target nodes have any actual inputs first,
+ /// followed by an optional chain operand, then flag operands. Compute the
+ /// number of actual operands that will go into the machine instr.
+ static unsigned CountOperands(SDNode *Node);
+
+ /// EmitNode - Generate machine code for an node and needed dependencies.
+ /// VRBaseMap contains, for each already emitted node, the first virtual
+ /// register number for the results of the node.
+ ///
+ void EmitNode(SDNode *Node, DenseMap<SDOperand, unsigned> &VRBaseMap);
+
+ /// EmitNoop - Emit a noop instruction.
+ ///
+ void EmitNoop();
+
+ void EmitSchedule();
+
+ void dumpSchedule() const;
+
+ /// Schedule - Order nodes according to selected style.
+ ///
+ virtual void Schedule() {}
+
+ private:
+ void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
+ const TargetInstrDescriptor *II,
+ DenseMap<SDOperand, unsigned> &VRBaseMap);
+ };
+
+ /// createBFS_DAGScheduler - This creates a simple breadth first instruction
+ /// scheduler.
+ ScheduleDAG *createBFS_DAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createSimpleDAGScheduler - This creates a simple two pass instruction
+ /// scheduler using instruction itinerary.
+ ScheduleDAG* createSimpleDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createNoItinsDAGScheduler - This creates a simple two pass instruction
+ /// scheduler without using instruction itinerary.
+ ScheduleDAG* createNoItinsDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createBURRListDAGScheduler - This creates a bottom up register usage
+ /// reduction list scheduler.
+ ScheduleDAG* createBURRListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createTDRRListDAGScheduler - This creates a top down register usage
+ /// reduction list scheduler.
+ ScheduleDAG* createTDRRListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createTDListDAGScheduler - This creates a top-down list scheduler with
+ /// a hazard recognizer.
+ ScheduleDAG* createTDListDAGScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+
+ /// createDefaultScheduler - This creates an instruction scheduler appropriate
+ /// for the target.
+ ScheduleDAG* createDefaultScheduler(SelectionDAGISel *IS,
+ SelectionDAG *DAG,
+ MachineBasicBlock *BB);
+}
+
+#endif
diff --git a/include/llvm/CodeGen/SchedulerRegistry.h b/include/llvm/CodeGen/SchedulerRegistry.h
new file mode 100644
index 0000000..ed5e0ba
--- /dev/null
+++ b/include/llvm/CodeGen/SchedulerRegistry.h
@@ -0,0 +1,71 @@
+//===-- llvm/CodeGen/SchedulerRegistry.h ------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation for instruction scheduler function
+// pass registry (RegisterScheduler).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGENSCHEDULERREGISTRY_H
+#define LLVM_CODEGENSCHEDULERREGISTRY_H
+
+#include "llvm/CodeGen/MachinePassRegistry.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// RegisterScheduler class - Track the registration of instruction schedulers.
+///
+//===----------------------------------------------------------------------===//
+
+class SelectionDAGISel;
+class ScheduleDAG;
+class SelectionDAG;
+class MachineBasicBlock;
+
+class RegisterScheduler : public MachinePassRegistryNode {
+
+public:
+
+ typedef ScheduleDAG *(*FunctionPassCtor)(SelectionDAGISel*, SelectionDAG*,
+ MachineBasicBlock*);
+
+ static MachinePassRegistry Registry;
+
+ RegisterScheduler(const char *N, const char *D, FunctionPassCtor C)
+ : MachinePassRegistryNode(N, D, (MachinePassCtor)C)
+ { Registry.Add(this); }
+ ~RegisterScheduler() { Registry.Remove(this); }
+
+
+ // Accessors.
+ //
+ RegisterScheduler *getNext() const {
+ return (RegisterScheduler *)MachinePassRegistryNode::getNext();
+ }
+ static RegisterScheduler *getList() {
+ return (RegisterScheduler *)Registry.getList();
+ }
+ static FunctionPassCtor getDefault() {
+ return (FunctionPassCtor)Registry.getDefault();
+ }
+ static void setDefault(FunctionPassCtor C) {
+ Registry.setDefault((MachinePassCtor)C);
+ }
+ static void setListener(MachinePassRegistryListener *L) {
+ Registry.setListener(L);
+ }
+
+};
+
+} // end namespace llvm
+
+
+#endif
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
new file mode 100644
index 0000000..9388df1
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -0,0 +1,524 @@
+//===-- llvm/CodeGen/SelectionDAG.h - InstSelection DAG ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SelectionDAG class, and transitively defines the
+// SDNode class and subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_H
+#define LLVM_CODEGEN_SELECTIONDAG_H
+
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/ilist"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <string>
+
+namespace llvm {
+ class AliasAnalysis;
+ class TargetLowering;
+ class TargetMachine;
+ class MachineModuleInfo;
+ class MachineFunction;
+ class MachineConstantPoolValue;
+
+/// SelectionDAG class - This is used to represent a portion of an LLVM function
+/// in a low-level Data Dependence DAG representation suitable for instruction
+/// selection. This DAG is constructed as the first step of instruction
+/// selection in order to allow implementation of machine specific optimizations
+/// and code simplifications.
+///
+/// The representation used by the SelectionDAG is a target-independent
+/// representation, which has some similarities to the GCC RTL representation,
+/// but is significantly more simple, powerful, and is a graph form instead of a
+/// linear form.
+///
+class SelectionDAG {
+ TargetLowering &TLI;
+ MachineFunction &MF;
+ MachineModuleInfo *MMI;
+
+ /// Root - The root of the entire DAG. EntryNode - The starting token.
+ SDOperand Root, EntryNode;
+
+ /// AllNodes - A linked list of nodes in the current DAG.
+ ilist<SDNode> AllNodes;
+
+ /// CSEMap - This structure is used to memoize nodes, automatically performing
+ /// CSE with existing nodes with a duplicate is requested.
+ FoldingSet<SDNode> CSEMap;
+
+public:
+ SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineModuleInfo *mmi)
+ : TLI(tli), MF(mf), MMI(mmi) {
+ EntryNode = Root = getNode(ISD::EntryToken, MVT::Other);
+ }
+ ~SelectionDAG();
+
+ MachineFunction &getMachineFunction() const { return MF; }
+ const TargetMachine &getTarget() const;
+ TargetLowering &getTargetLoweringInfo() const { return TLI; }
+ MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
+
+ /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
+ ///
+ void viewGraph();
+
+#ifndef NDEBUG
+ std::map<const SDNode *, std::string> NodeGraphAttrs;
+#endif
+
+ /// clearGraphAttrs - Clear all previously defined node graph attributes.
+ /// Intended to be used from a debugging tool (eg. gdb).
+ void clearGraphAttrs();
+
+ /// setGraphAttrs - Set graph attributes for a node. (eg. "color=red".)
+ ///
+ void setGraphAttrs(const SDNode *N, const char *Attrs);
+
+ /// getGraphAttrs - Get graph attributes for a node. (eg. "color=red".)
+ /// Used from getNodeAttributes.
+ const std::string getGraphAttrs(const SDNode *N) const;
+
+ /// setGraphColor - Convenience for setting node color attribute.
+ ///
+ void setGraphColor(const SDNode *N, const char *Color);
+
+ typedef ilist<SDNode>::const_iterator allnodes_const_iterator;
+ allnodes_const_iterator allnodes_begin() const { return AllNodes.begin(); }
+ allnodes_const_iterator allnodes_end() const { return AllNodes.end(); }
+ typedef ilist<SDNode>::iterator allnodes_iterator;
+ allnodes_iterator allnodes_begin() { return AllNodes.begin(); }
+ allnodes_iterator allnodes_end() { return AllNodes.end(); }
+
+ /// getRoot - Return the root tag of the SelectionDAG.
+ ///
+ const SDOperand &getRoot() const { return Root; }
+
+ /// getEntryNode - Return the token chain corresponding to the entry of the
+ /// function.
+ const SDOperand &getEntryNode() const { return EntryNode; }
+
+ /// setRoot - Set the current root tag of the SelectionDAG.
+ ///
+ const SDOperand &setRoot(SDOperand N) { return Root = N; }
+
+ /// Combine - This iterates over the nodes in the SelectionDAG, folding
+ /// certain types of nodes together, or eliminating superfluous nodes. When
+ /// the AfterLegalize argument is set to 'true', Combine takes care not to
+ /// generate any nodes that will be illegal on the target.
+ void Combine(bool AfterLegalize, AliasAnalysis &AA);
+
+ /// Legalize - This transforms the SelectionDAG into a SelectionDAG that is
+ /// compatible with the target instruction selector, as indicated by the
+ /// TargetLowering object.
+ ///
+ /// Note that this is an involved process that may invalidate pointers into
+ /// the graph.
+ void Legalize();
+
+ /// RemoveDeadNodes - This method deletes all unreachable nodes in the
+ /// SelectionDAG.
+ void RemoveDeadNodes();
+
+ /// RemoveDeadNode - Remove the specified node from the system. If any of its
+ /// operands then becomes dead, remove them as well. The vector Deleted is
+ /// populated with nodes that are deleted.
+ void RemoveDeadNode(SDNode *N, std::vector<SDNode*> &Deleted);
+
+ /// DeleteNode - Remove the specified node from the system. This node must
+ /// have no referrers.
+ void DeleteNode(SDNode *N);
+
+ /// getVTList - Return an SDVTList that represents the list of values
+ /// specified.
+ SDVTList getVTList(MVT::ValueType VT);
+ SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2);
+ SDVTList getVTList(MVT::ValueType VT1, MVT::ValueType VT2,MVT::ValueType VT3);
+ SDVTList getVTList(const MVT::ValueType *VTs, unsigned NumVTs);
+
+ /// getNodeValueTypes - These are obsolete, use getVTList instead.
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT) {
+ return getVTList(VT).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1,
+ MVT::ValueType VT2) {
+ return getVTList(VT1, VT2).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(MVT::ValueType VT1,MVT::ValueType VT2,
+ MVT::ValueType VT3) {
+ return getVTList(VT1, VT2, VT3).VTs;
+ }
+ const MVT::ValueType *getNodeValueTypes(std::vector<MVT::ValueType> &VTList) {
+ return getVTList(&VTList[0], VTList.size()).VTs;
+ }
+
+
+ //===--------------------------------------------------------------------===//
+ // Node creation methods.
+ //
+ SDOperand getString(const std::string &Val);
+ SDOperand getConstant(uint64_t Val, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetConstant(uint64_t Val, MVT::ValueType VT) {
+ return getConstant(Val, VT, true);
+ }
+ SDOperand getConstantFP(double Val, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetConstantFP(double Val, MVT::ValueType VT) {
+ return getConstantFP(Val, VT, true);
+ }
+ SDOperand getGlobalAddress(const GlobalValue *GV, MVT::ValueType VT,
+ int offset = 0, bool isTargetGA = false);
+ SDOperand getTargetGlobalAddress(const GlobalValue *GV, MVT::ValueType VT,
+ int offset = 0) {
+ return getGlobalAddress(GV, VT, offset, true);
+ }
+ SDOperand getFrameIndex(int FI, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetFrameIndex(int FI, MVT::ValueType VT) {
+ return getFrameIndex(FI, VT, true);
+ }
+ SDOperand getJumpTable(int JTI, MVT::ValueType VT, bool isTarget = false);
+ SDOperand getTargetJumpTable(int JTI, MVT::ValueType VT) {
+ return getJumpTable(JTI, VT, true);
+ }
+ SDOperand getConstantPool(Constant *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false);
+ SDOperand getTargetConstantPool(Constant *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offset = 0) {
+ return getConstantPool(C, VT, Align, Offset, true);
+ }
+ SDOperand getConstantPool(MachineConstantPoolValue *C, MVT::ValueType VT,
+ unsigned Align = 0, int Offs = 0, bool isT=false);
+ SDOperand getTargetConstantPool(MachineConstantPoolValue *C,
+ MVT::ValueType VT, unsigned Align = 0,
+ int Offset = 0) {
+ return getConstantPool(C, VT, Align, Offset, true);
+ }
+ SDOperand getBasicBlock(MachineBasicBlock *MBB);
+ SDOperand getExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getTargetExternalSymbol(const char *Sym, MVT::ValueType VT);
+ SDOperand getValueType(MVT::ValueType);
+ SDOperand getRegister(unsigned Reg, MVT::ValueType VT);
+
+ SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N) {
+ return getNode(ISD::CopyToReg, MVT::Other, Chain,
+ getRegister(Reg, N.getValueType()), N);
+ }
+
+ // This version of the getCopyToReg method takes an extra operand, which
+ // indicates that there is potentially an incoming flag value (if Flag is not
+ // null) and that there should be a flag result.
+ SDOperand getCopyToReg(SDOperand Chain, unsigned Reg, SDOperand N,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, getRegister(Reg, N.getValueType()), N, Flag };
+ return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+ }
+
+ // Similar to last getCopyToReg() except parameter Reg is a SDOperand
+ SDOperand getCopyToReg(SDOperand Chain, SDOperand Reg, SDOperand N,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, Reg, N, Flag };
+ return getNode(ISD::CopyToReg, VTs, 2, Ops, Flag.Val ? 4 : 3);
+ }
+
+ SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT) {
+ const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other);
+ SDOperand Ops[] = { Chain, getRegister(Reg, VT) };
+ return getNode(ISD::CopyFromReg, VTs, 2, Ops, 2);
+ }
+
+ // This version of the getCopyFromReg method takes an extra operand, which
+ // indicates that there is potentially an incoming flag value (if Flag is not
+ // null) and that there should be a flag result.
+ SDOperand getCopyFromReg(SDOperand Chain, unsigned Reg, MVT::ValueType VT,
+ SDOperand Flag) {
+ const MVT::ValueType *VTs = getNodeValueTypes(VT, MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, getRegister(Reg, VT), Flag };
+ return getNode(ISD::CopyFromReg, VTs, 3, Ops, Flag.Val ? 3 : 2);
+ }
+
+ SDOperand getCondCode(ISD::CondCode Cond);
+
+ /// getZeroExtendInReg - Return the expression required to zero extend the Op
+ /// value assuming it was the smaller SrcTy value.
+ SDOperand getZeroExtendInReg(SDOperand Op, MVT::ValueType SrcTy);
+
+ /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have
+ /// a flag result (to ensure it's not CSE'd).
+ SDOperand getCALLSEQ_START(SDOperand Chain, SDOperand Op) {
+ const MVT::ValueType *VTs = getNodeValueTypes(MVT::Other, MVT::Flag);
+ SDOperand Ops[] = { Chain, Op };
+ return getNode(ISD::CALLSEQ_START, VTs, 2, Ops, 2);
+ }
+
+ /// getNode - Gets or creates the specified node.
+ ///
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT, SDOperand N);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4,
+ SDOperand N5);
+ SDOperand getNode(unsigned Opcode, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, std::vector<MVT::ValueType> &ResultTys,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, const MVT::ValueType *VTs, unsigned NumVTs,
+ const SDOperand *Ops, unsigned NumOps);
+ SDOperand getNode(unsigned Opcode, SDVTList VTs,
+ const SDOperand *Ops, unsigned NumOps);
+
+ /// getSetCC - Helper function to make it easier to build SetCC's if you just
+ /// have an ISD::CondCode instead of an SDOperand.
+ ///
+ SDOperand getSetCC(MVT::ValueType VT, SDOperand LHS, SDOperand RHS,
+ ISD::CondCode Cond) {
+ return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
+ }
+
+ /// getSelectCC - Helper function to make it easier to build SelectCC's if you
+ /// just have an ISD::CondCode instead of an SDOperand.
+ ///
+ SDOperand getSelectCC(SDOperand LHS, SDOperand RHS,
+ SDOperand True, SDOperand False, ISD::CondCode Cond) {
+ return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False,
+ getCondCode(Cond));
+ }
+
+ /// getVAArg - VAArg produces a result and token chain, and takes a pointer
+ /// and a source value as input.
+ SDOperand getVAArg(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
+ SDOperand SV);
+
+ /// getLoad - Loads are not normal binary operators: their result type is not
+ /// determined by their operands, and they produce a value AND a token chain.
+ ///
+ SDOperand getLoad(MVT::ValueType VT, SDOperand Chain, SDOperand Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getExtLoad(ISD::LoadExtType ExtType, MVT::ValueType VT,
+ SDOperand Chain, SDOperand Ptr, const Value *SV,
+ int SVOffset, MVT::ValueType EVT, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getIndexedLoad(SDOperand OrigLoad, SDOperand Base,
+ SDOperand Offset, ISD::MemIndexedMode AM);
+
+ /// getStore - Helper function to build ISD::STORE nodes.
+ ///
+ SDOperand getStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
+ const Value *SV, int SVOffset, bool isVolatile=false,
+ unsigned Alignment=0);
+ SDOperand getTruncStore(SDOperand Chain, SDOperand Val, SDOperand Ptr,
+ const Value *SV, int SVOffset, MVT::ValueType TVT,
+ bool isVolatile=false, unsigned Alignment=0);
+ SDOperand getIndexedStore(SDOperand OrigStoe, SDOperand Base,
+ SDOperand Offset, ISD::MemIndexedMode AM);
+
+ // getSrcValue - construct a node to track a Value* through the backend
+ SDOperand getSrcValue(const Value* I, int offset = 0);
+
+ /// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+ /// specified operands. If the resultant node already exists in the DAG,
+ /// this does not modify the specified node, instead it returns the node that
+ /// already exists. If the resultant node does not exist in the DAG, the
+ /// input node is returned. As a degenerate case, if you specify the same
+ /// input operands as the node already has, the input node is returned.
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3, SDOperand Op4);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3, SDOperand Op4, SDOperand Op5);
+ SDOperand UpdateNodeOperands(SDOperand N, SDOperand *Ops, unsigned NumOps);
+
+ /// SelectNodeTo - These are used for target selectors to *mutate* the
+ /// specified node to have the specified return type, Target opcode, and
+ /// operands. Note that target opcodes are stored as
+ /// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field. The 0th value
+ /// of the resultant node is returned.
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2);
+ SDNode *SelectNodeTo(SDNode *N, unsigned TargetOpc, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+
+
+ /// getTargetNode - These are used for target selectors to create a new node
+ /// with specified return type(s), target opcode, and operands.
+ ///
+ /// Note that getTargetNode returns the resultant node. If there is already a
+ /// node of the specified opcode and operands, it returns that node instead of
+ /// the current one.
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2,
+ const SDOperand *Ops, unsigned NumOps);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ SDOperand Op1, SDOperand Op2);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ SDOperand Op1, SDOperand Op2, SDOperand Op3);
+ SDNode *getTargetNode(unsigned Opcode, MVT::ValueType VT1,
+ MVT::ValueType VT2, MVT::ValueType VT3,
+ const SDOperand *Ops, unsigned NumOps);
+
+ /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+ /// This can cause recursive merging of nodes in the DAG. Use the first
+ /// version if 'From' is known to have a single result, use the second
+ /// if you have two nodes with identical results, use the third otherwise.
+ ///
+ /// These methods all take an optional vector, which (if not null) is
+ /// populated with any nodes that are deleted from the SelectionDAG, due to
+ /// new equivalences that are discovered.
+ ///
+ void ReplaceAllUsesWith(SDOperand From, SDOperand Op,
+ std::vector<SDNode*> *Deleted = 0);
+ void ReplaceAllUsesWith(SDNode *From, SDNode *To,
+ std::vector<SDNode*> *Deleted = 0);
+ void ReplaceAllUsesWith(SDNode *From, const SDOperand *To,
+ std::vector<SDNode*> *Deleted = 0);
+
+ /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
+ /// uses of other values produced by From.Val alone. The Deleted vector is
+ /// handled the same was as for ReplaceAllUsesWith, but it is required for
+ /// this method.
+ void ReplaceAllUsesOfValueWith(SDOperand From, SDOperand To,
+ std::vector<SDNode*> &Deleted);
+
+ /// AssignNodeIds - Assign a unique node id for each node in the DAG based on
+ /// their allnodes order. It returns the maximum id.
+ unsigned AssignNodeIds();
+
+ /// AssignTopologicalOrder - Assign a unique node id for each node in the DAG
+ /// based on their topological order. It returns the maximum id and a vector
+ /// of the SDNodes* in assigned order by reference.
+ unsigned AssignTopologicalOrder(std::vector<SDNode*> &TopOrder);
+
+ /// isCommutativeBinOp - Returns true if the opcode is a commutative binary
+ /// operation.
+ static bool isCommutativeBinOp(unsigned Opcode) {
+ switch (Opcode) {
+ case ISD::ADD:
+ case ISD::MUL:
+ case ISD::MULHU:
+ case ISD::MULHS:
+ case ISD::FADD:
+ case ISD::FMUL:
+ case ISD::AND:
+ case ISD::OR:
+ case ISD::XOR:
+ case ISD::ADDC:
+ case ISD::ADDE: return true;
+ default: return false;
+ }
+ }
+
+ void dump() const;
+
+ /// FoldSetCC - Constant fold a setcc to true or false.
+ SDOperand FoldSetCC(MVT::ValueType VT, SDOperand N1,
+ SDOperand N2, ISD::CondCode Cond);
+
+ /// MaskedValueIsZero - Return true if 'Op & Mask' is known to be zero. We
+ /// use this predicate to simplify operations downstream. Op and Mask are
+ /// known to be the same type.
+ bool MaskedValueIsZero(SDOperand Op, uint64_t Mask, unsigned Depth = 0)
+ const;
+
+ /// ComputeMaskedBits - Determine which of the bits specified in Mask are
+ /// known to be either zero or one and return them in the KnownZero/KnownOne
+ /// bitsets. This code only analyzes bits in Mask, in order to short-circuit
+ /// processing. Targets can implement the computeMaskedBitsForTargetNode
+ /// method in the TargetLowering class to allow target nodes to be understood.
+ void ComputeMaskedBits(SDOperand Op, uint64_t Mask, uint64_t &KnownZero,
+ uint64_t &KnownOne, unsigned Depth = 0) const;
+
+ /// ComputeNumSignBits - Return the number of times the sign bit of the
+ /// register is replicated into the other bits. We know that at least 1 bit
+ /// is always equal to the sign bit (itself), but other cases can give us
+ /// information. For example, immediately after an "SRA X, 2", we know that
+ /// the top 3 bits are all equal to each other, so we return 3. Targets can
+ /// implement the ComputeNumSignBitsForTarget method in the TargetLowering
+ /// class to allow target nodes to be understood.
+ unsigned ComputeNumSignBits(SDOperand Op, unsigned Depth = 0) const;
+
+private:
+ void RemoveNodeFromCSEMaps(SDNode *N);
+ SDNode *AddNonLeafNodeToCSEMaps(SDNode *N);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op, void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, SDOperand Op1, SDOperand Op2,
+ void *&InsertPos);
+ SDNode *FindModifiedNodeSlot(SDNode *N, const SDOperand *Ops, unsigned NumOps,
+ void *&InsertPos);
+
+ void DeleteNodeNotInCSEMaps(SDNode *N);
+
+ // List of non-single value types.
+ std::list<std::vector<MVT::ValueType> > VTList;
+
+ // Maps to auto-CSE operations.
+ std::vector<CondCodeSDNode*> CondCodeNodes;
+
+ std::vector<SDNode*> ValueTypeNodes;
+ std::map<std::string, SDNode*> ExternalSymbols;
+ std::map<std::string, SDNode*> TargetExternalSymbols;
+ std::map<std::string, StringSDNode*> StringNodes;
+};
+
+template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
+ typedef SelectionDAG::allnodes_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(SelectionDAG *G) {
+ return G->allnodes_begin();
+ }
+ static nodes_iterator nodes_end(SelectionDAG *G) {
+ return G->allnodes_end();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h
new file mode 100644
index 0000000..497040d
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGISel.h
@@ -0,0 +1,194 @@
+//===-- llvm/CodeGen/SelectionDAGISel.h - Common Base Class------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the SelectionDAGISel class, which is used as the common
+// base class for SelectionDAG-based instruction selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAG_ISEL_H
+#define LLVM_CODEGEN_SELECTIONDAG_ISEL_H
+
+#include "llvm/Pass.h"
+#include "llvm/Constant.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+
+namespace llvm {
+ class SelectionDAGLowering;
+ class SDOperand;
+ class SSARegMap;
+ class MachineBasicBlock;
+ class MachineFunction;
+ class MachineInstr;
+ class TargetLowering;
+ class FunctionLoweringInfo;
+ class HazardRecognizer;
+
+/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
+/// pattern-matching instruction selectors.
+class SelectionDAGISel : public FunctionPass {
+public:
+ TargetLowering &TLI;
+ SSARegMap *RegMap;
+ SelectionDAG *CurDAG;
+ MachineBasicBlock *BB;
+ std::vector<SDNode*> TopOrder;
+ unsigned DAGSize;
+ static char ID;
+
+ explicit SelectionDAGISel(TargetLowering &tli) :
+ FunctionPass((intptr_t)&ID), TLI(tli), DAGSize(0) {}
+
+ TargetLowering &getTargetLowering() { return TLI; }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ virtual bool runOnFunction(Function &Fn);
+
+ unsigned MakeReg(MVT::ValueType VT);
+
+ virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {}
+ virtual void InstructionSelectBasicBlock(SelectionDAG &SD) = 0;
+ virtual void SelectRootInit() {
+ DAGSize = CurDAG->AssignTopologicalOrder(TopOrder);
+ }
+
+ /// SelectInlineAsmMemoryOperand - Select the specified address as a target
+ /// addressing mode, according to the specified constraint code. 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 SDOperand &Op,
+ char ConstraintCode,
+ std::vector<SDOperand> &OutOps,
+ SelectionDAG &DAG) {
+ return true;
+ }
+
+ /// CanBeFoldedBy - Returns true if the specific operand node N of U can be
+ /// folded during instruction selection that starts at Root?
+ virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) { return true;}
+
+ /// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
+ /// to use for this target when scheduling the DAG.
+ virtual HazardRecognizer *CreateTargetHazardRecognizer();
+
+ /// CaseBlock - This structure is used to communicate between SDLowering and
+ /// SDISel for the code generation of additional basic blocks needed by multi-
+ /// case switch statements.
+ struct CaseBlock {
+ CaseBlock(ISD::CondCode cc, Value *cmplhs, Value *cmprhs, Value *cmpmiddle,
+ MachineBasicBlock *truebb, MachineBasicBlock *falsebb,
+ MachineBasicBlock *me)
+ : CC(cc), CmpLHS(cmplhs), CmpMHS(cmpmiddle), CmpRHS(cmprhs),
+ TrueBB(truebb), FalseBB(falsebb), ThisBB(me) {}
+ // CC - the condition code to use for the case block's setcc node
+ ISD::CondCode CC;
+ // CmpLHS/CmpRHS/CmpMHS - The LHS/MHS/RHS of the comparison to emit.
+ // Emit by default LHS op RHS. MHS is used for range comparisons:
+ // If MHS is not null: (LHS <= MHS) and (MHS <= RHS).
+ Value *CmpLHS, *CmpMHS, *CmpRHS;
+ // TrueBB/FalseBB - the block to branch to if the setcc is true/false.
+ MachineBasicBlock *TrueBB, *FalseBB;
+ // ThisBB - the block into which to emit the code for the setcc and branches
+ MachineBasicBlock *ThisBB;
+ };
+ struct JumpTable {
+ JumpTable(unsigned R, unsigned J, MachineBasicBlock *M,
+ MachineBasicBlock *D): Reg(R), JTI(J), MBB(M), Default(D) {};
+
+ /// Reg - the virtual register containing the index of the jump table entry
+ //. to jump to.
+ unsigned Reg;
+ /// JTI - the JumpTableIndex for this jump table in the function.
+ unsigned JTI;
+ /// MBB - the MBB into which to emit the code for the indirect jump.
+ MachineBasicBlock *MBB;
+ /// Default - the MBB of the default bb, which is a successor of the range
+ /// check MBB. This is when updating PHI nodes in successors.
+ MachineBasicBlock *Default;
+ };
+ struct JumpTableHeader {
+ JumpTableHeader(uint64_t F, uint64_t L, Value* SV, MachineBasicBlock* H,
+ bool E = false):
+ First(F), Last(L), SValue(SV), HeaderBB(H), Emitted(E) {};
+ uint64_t First;
+ uint64_t Last;
+ Value *SValue;
+ MachineBasicBlock *HeaderBB;
+ bool Emitted;
+ };
+ typedef std::pair<JumpTableHeader, JumpTable> JumpTableBlock;
+
+ struct BitTestCase {
+ BitTestCase(uint64_t M, MachineBasicBlock* T, MachineBasicBlock* Tr):
+ Mask(M), ThisBB(T), TargetBB(Tr) { };
+ uint64_t Mask;
+ MachineBasicBlock* ThisBB;
+ MachineBasicBlock* TargetBB;
+ };
+
+ typedef SmallVector<BitTestCase, 3> BitTestInfo;
+
+ struct BitTestBlock {
+ BitTestBlock(uint64_t F, uint64_t R, Value* SV,
+ unsigned Rg, bool E,
+ MachineBasicBlock* P, MachineBasicBlock* D,
+ const BitTestInfo& C):
+ First(F), Range(R), SValue(SV), Reg(Rg), Emitted(E),
+ Parent(P), Default(D), Cases(C) { };
+ uint64_t First;
+ uint64_t Range;
+ Value *SValue;
+ unsigned Reg;
+ bool Emitted;
+ MachineBasicBlock *Parent;
+ MachineBasicBlock *Default;
+ BitTestInfo Cases;
+ };
+protected:
+ /// Pick a safe ordering and emit instructions for each target node in the
+ /// graph.
+ void ScheduleAndEmitDAG(SelectionDAG &DAG);
+
+ /// SelectInlineAsmMemoryOperands - Calls to this are automatically generated
+ /// by tblgen. Others should not call it.
+ void SelectInlineAsmMemoryOperands(std::vector<SDOperand> &Ops,
+ SelectionDAG &DAG);
+
+ // Calls to these predicates are generated by tblgen.
+ bool CheckAndMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);
+ bool CheckOrMask(SDOperand LHS, ConstantSDNode *RHS, int64_t DesiredMaskS);
+
+private:
+ void SelectBasicBlock(BasicBlock *BB, MachineFunction &MF,
+ FunctionLoweringInfo &FuncInfo);
+
+ void BuildSelectionDAG(SelectionDAG &DAG, BasicBlock *LLVMBB,
+ std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate,
+ FunctionLoweringInfo &FuncInfo);
+ void CodeGenAndEmitDAG(SelectionDAG &DAG);
+ void LowerArguments(BasicBlock *BB, SelectionDAGLowering &SDL,
+ std::vector<SDOperand> &UnorderedChains);
+
+ /// SwitchCases - Vector of CaseBlock structures used to communicate
+ /// SwitchInst code generation information.
+ std::vector<CaseBlock> SwitchCases;
+
+ /// JTCases - Vector of JumpTable structures which holds necessary information
+ /// for emitting a jump tables during SwitchInst code generation.
+ std::vector<JumpTableBlock> JTCases;
+
+ std::vector<BitTestBlock> BitTestCases;
+};
+
+}
+
+#endif /* LLVM_CODEGEN_SELECTIONDAG_ISEL_H */
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
new file mode 100644
index 0000000..c96d516
--- /dev/null
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -0,0 +1,1641 @@
+//===-- llvm/CodeGen/SelectionDAGNodes.h - SelectionDAG Nodes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SDNode class and derived classes, which are used to
+// represent the nodes and operations present in a SelectionDAG. These nodes
+// and operations are machine code level operations, with some similarities to
+// the GCC RTL representation.
+//
+// Clients should include the SelectionDAG.h file instead of this file directly.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SELECTIONDAGNODES_H
+#define LLVM_CODEGEN_SELECTIONDAGNODES_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include "llvm/CodeGen/ValueTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include <cassert>
+
+namespace llvm {
+
+class SelectionDAG;
+class GlobalValue;
+class MachineBasicBlock;
+class MachineConstantPoolValue;
+class SDNode;
+template <typename T> struct DenseMapKeyInfo;
+template <typename T> struct simplify_type;
+template <typename T> struct ilist_traits;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename NodeTy> class ilist_iterator;
+
+/// SDVTList - 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(...).
+///
+struct SDVTList {
+ const MVT::ValueType *VTs;
+ unsigned short NumVTs;
+};
+
+/// ISD namespace - This namespace contains an enum which represents all of the
+/// SelectionDAG node types and value types.
+///
+namespace ISD {
+ namespace ParamFlags {
+ enum Flags {
+ NoFlagSet = 0,
+ ZExt = 1<<0, ///< Parameter should be zero extended
+ ZExtOffs = 0,
+ SExt = 1<<1, ///< Parameter should be sign extended
+ SExtOffs = 1,
+ InReg = 1<<2, ///< Parameter should be passed in register
+ InRegOffs = 2,
+ StructReturn = 1<<3, ///< Hidden struct-return pointer
+ StructReturnOffs = 3,
+ ByVal = 1<<4, ///< Struct passed by value
+ ByValOffs = 4,
+ OrigAlignment = 0x1F<<27,
+ OrigAlignmentOffs = 27
+ };
+ }
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::NodeType enum - This enum defines all of the operators valid in a
+ /// SelectionDAG.
+ ///
+ enum NodeType {
+ // DELETED_NODE - This is an illegal flag value that is used to catch
+ // errors. This opcode is not a legal opcode for any node.
+ DELETED_NODE,
+
+ // EntryToken - This is the marker used to indicate the start of the region.
+ EntryToken,
+
+ // Token factor - This node takes multiple tokens as input and produces a
+ // single token result. This is used to represent the fact that the operand
+ // operators are independent of each other.
+ TokenFactor,
+
+ // AssertSext, AssertZext - These nodes record if a register contains a
+ // value that has already been zero or sign extended from a narrower type.
+ // These nodes take two operands. The first is the node that has already
+ // been extended, and the second is a value type node indicating the width
+ // of the extension
+ AssertSext, AssertZext,
+
+ // Various leaf nodes.
+ STRING, BasicBlock, VALUETYPE, CONDCODE, Register,
+ Constant, ConstantFP,
+ GlobalAddress, GlobalTLSAddress, FrameIndex,
+ JumpTable, ConstantPool, ExternalSymbol,
+
+ // The address of the GOT
+ GLOBAL_OFFSET_TABLE,
+
+ // FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
+ // llvm.returnaddress on the DAG. These nodes take one operand, the index
+ // of the frame or return address to return. An index of zero corresponds
+ // to the current function's frame or return address, an index of one to the
+ // parent's frame or return address, and so on.
+ FRAMEADDR, RETURNADDR,
+
+ // FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
+ // first (possible) on-stack argument. This is needed for correct stack
+ // adjustment during unwind.
+ FRAME_TO_ARGS_OFFSET,
+
+ // RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
+ // address of the exception block on entry to an landing pad block.
+ EXCEPTIONADDR,
+
+ // RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
+ // the selection index of the exception thrown.
+ EHSELECTION,
+
+ // OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
+ // 'eh_return' gcc dwarf builtin, which is used to return from
+ // exception. The general meaning is: adjust stack by OFFSET and pass
+ // execution to HANDLER. Many platform-related details also :)
+ EH_RETURN,
+
+ // TargetConstant* - Like Constant*, but the DAG does not do any folding or
+ // simplification of the constant.
+ TargetConstant,
+ TargetConstantFP,
+
+ // TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
+ // anything else with this node, and this is valid in the target-specific
+ // dag, turning into a GlobalAddress operand.
+ TargetGlobalAddress,
+ TargetGlobalTLSAddress,
+ TargetFrameIndex,
+ TargetJumpTable,
+ TargetConstantPool,
+ TargetExternalSymbol,
+
+ /// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with no side effects.
+ /// The first operand is the ID number of the intrinsic from the
+ /// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
+ /// node has returns the result of the intrinsic.
+ INTRINSIC_WO_CHAIN,
+
+ /// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// returns a result. The first operand is a chain pointer. The second is
+ /// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
+ /// operands to the intrinsic follow. The node has two results, the result
+ /// of the intrinsic and an output chain.
+ INTRINSIC_W_CHAIN,
+
+ /// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
+ /// This node represents a target intrinsic function with side effects that
+ /// does not return a result. The first operand is a chain pointer. The
+ /// second is the ID number of the intrinsic from the llvm::Intrinsic
+ /// namespace. The operands to the intrinsic follow.
+ INTRINSIC_VOID,
+
+ // CopyToReg - This node has three operands: a chain, a register number to
+ // set to this value, and a value.
+ CopyToReg,
+
+ // CopyFromReg - This node indicates that the input value is a virtual or
+ // physical register that is defined outside of the scope of this
+ // SelectionDAG. The register is available from the RegSDNode object.
+ CopyFromReg,
+
+ // UNDEF - An undefined node
+ UNDEF,
+
+ /// FORMAL_ARGUMENTS(CHAIN, CC#, ISVARARG, FLAG0, ..., FLAGn) - This node
+ /// represents the formal arguments for a function. CC# is a Constant value
+ /// indicating the calling convention of the function, and ISVARARG is a
+ /// flag that indicates whether the function is varargs or not. This node
+ /// has one result value for each incoming argument, plus one for the output
+ /// chain. It must be custom legalized. See description of CALL node for
+ /// FLAG argument contents explanation.
+ ///
+ FORMAL_ARGUMENTS,
+
+ /// RV1, RV2...RVn, CHAIN = CALL(CHAIN, CC#, ISVARARG, ISTAILCALL, CALLEE,
+ /// ARG0, FLAG0, ARG1, FLAG1, ... ARGn, FLAGn)
+ /// This node represents a fully general function call, before the legalizer
+ /// runs. This has one result value for each argument / flag pair, plus
+ /// a chain result. It must be custom legalized. Flag argument indicates
+ /// misc. argument attributes. Currently:
+ /// Bit 0 - signness
+ /// Bit 1 - 'inreg' attribute
+ /// Bit 2 - 'sret' attribute
+ /// Bits 31:27 - argument ABI alignment in the first argument piece and
+ /// alignment '1' in other argument pieces.
+ CALL,
+
+ // EXTRACT_ELEMENT - This is used to get the first or second (determined by
+ // a Constant, which is required to be operand #1), element of the aggregate
+ // value specified as operand #0. This is only for use before legalization,
+ // for values that will be broken into multiple registers.
+ EXTRACT_ELEMENT,
+
+ // BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
+ // two values of the same integer value type, this produces a value twice as
+ // big. Like EXTRACT_ELEMENT, this can only be used before legalization.
+ BUILD_PAIR,
+
+ // MERGE_VALUES - This node takes multiple discrete operands and returns
+ // them all as its individual results. This nodes has exactly the same
+ // number of inputs and outputs, and is only valid before legalization.
+ // This node is useful for some pieces of the code generator that want to
+ // think about a single node with multiple results, not multiple nodes.
+ MERGE_VALUES,
+
+ // Simple integer binary arithmetic operators.
+ ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
+
+ // CARRY_FALSE - This node is used when folding other nodes,
+ // like ADDC/SUBC, which indicate the carry result is always false.
+ CARRY_FALSE,
+
+ // Carry-setting nodes for multiple precision addition and subtraction.
+ // These nodes take two operands of the same value type, and produce two
+ // results. The first result is the normal add or sub result, the second
+ // result is the carry flag result.
+ ADDC, SUBC,
+
+ // Carry-using nodes for multiple precision addition and subtraction. These
+ // nodes take three operands: The first two are the normal lhs and rhs to
+ // the add or sub, and the third is the input carry flag. These nodes
+ // produce two results; the normal result of the add or sub, and the output
+ // carry flag. These nodes both read and write a carry flag to allow them
+ // to them to be chained together for add and sub of arbitrarily large
+ // values.
+ ADDE, SUBE,
+
+ // Simple binary floating point operators.
+ FADD, FSUB, FMUL, FDIV, FREM,
+
+ // FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
+ // DAG node does not require that X and Y have the same type, just that they
+ // are both floating point. X and the result must have the same type.
+ // FCOPYSIGN(f32, f64) is allowed.
+ FCOPYSIGN,
+
+ /// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector
+ /// with the specified, possibly variable, elements. The number of elements
+ /// is required to be a power of two.
+ BUILD_VECTOR,
+
+ /// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
+ /// at IDX replaced with VAL.
+ INSERT_VECTOR_ELT,
+
+ /// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
+ /// identified by the (potentially variable) element number IDX.
+ EXTRACT_VECTOR_ELT,
+
+ /// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
+ /// vector type with the same length and element type, this produces a
+ /// concatenated vector result value, with length equal to the sum of the
+ /// lengths of the input vectors.
+ CONCAT_VECTORS,
+
+ /// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
+ /// vector value) starting with the (potentially variable) element number
+ /// IDX, which must be a multiple of the result vector length.
+ EXTRACT_SUBVECTOR,
+
+ /// VECTOR_SHUFFLE(VEC1, VEC2, SHUFFLEVEC) - Returns a vector, of the same
+ /// type as VEC1/VEC2. SHUFFLEVEC is a BUILD_VECTOR of constant int values
+ /// (regardless of whether its datatype is legal or not) that indicate
+ /// which value each result element will get. The elements of VEC1/VEC2 are
+ /// enumerated in order. This is quite similar to the Altivec 'vperm'
+ /// instruction, except that the indices must be constants and are in terms
+ /// of the element size of VEC1/VEC2, not in terms of bytes.
+ VECTOR_SHUFFLE,
+
+ /// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
+ /// scalar value into the low element of the resultant vector type. The top
+ /// elements of the vector are undefined.
+ SCALAR_TO_VECTOR,
+
+ // MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
+ // an unsigned/signed value of type i[2*n], then return the top part.
+ MULHU, MULHS,
+
+ // Bitwise operators - logical and, logical or, logical xor, shift left,
+ // shift right algebraic (shift in sign bits), shift right logical (shift in
+ // zeroes), rotate left, rotate right, and byteswap.
+ AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
+
+ // Counting operators
+ CTTZ, CTLZ, CTPOP,
+
+ // Select(COND, TRUEVAL, FALSEVAL)
+ SELECT,
+
+ // Select with condition operator - This selects between a true value and
+ // a false value (ops #2 and #3) based on the boolean result of comparing
+ // the lhs and rhs (ops #0 and #1) of a conditional expression with the
+ // condition code in op #4, a CondCodeSDNode.
+ SELECT_CC,
+
+ // SetCC operator - This evaluates to a boolean (i1) true value if the
+ // condition is true. The operands to this are the left and right operands
+ // to compare (ops #0, and #1) and the condition code to compare them with
+ // (op #2) as a CondCodeSDNode.
+ SETCC,
+
+ // SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
+ // integer shift operations, just like ADD/SUB_PARTS. The operation
+ // ordering is:
+ // [Lo,Hi] = op [LoLHS,HiLHS], Amt
+ SHL_PARTS, SRA_PARTS, SRL_PARTS,
+
+ // Conversion operators. These are all single input single output
+ // operations. For all of these, the result type must be strictly
+ // wider or narrower (depending on the operation) than the source
+ // type.
+
+ // SIGN_EXTEND - Used for integer types, replicating the sign bit
+ // into new bits.
+ SIGN_EXTEND,
+
+ // ZERO_EXTEND - Used for integer types, zeroing the new bits.
+ ZERO_EXTEND,
+
+ // ANY_EXTEND - Used for integer types. The high bits are undefined.
+ ANY_EXTEND,
+
+ // TRUNCATE - Completely drop the high bits.
+ TRUNCATE,
+
+ // [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
+ // depends on the first letter) to floating point.
+ SINT_TO_FP,
+ UINT_TO_FP,
+
+ // SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
+ // sign extend a small value in a large integer register (e.g. sign
+ // extending the low 8 bits of a 32-bit register to fill the top 24 bits
+ // with the 7th bit). The size of the smaller type is indicated by the 1th
+ // operand, a ValueType node.
+ SIGN_EXTEND_INREG,
+
+ // FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
+ // integer.
+ FP_TO_SINT,
+ FP_TO_UINT,
+
+ // FP_ROUND - Perform a rounding operation from the current
+ // precision down to the specified precision (currently always 64->32).
+ FP_ROUND,
+
+ // FP_ROUND_INREG - This operator takes a floating point register, and
+ // rounds it to a floating point value. It then promotes it and returns it
+ // in a register of the same size. This operation effectively just discards
+ // excess precision. The type to round down to is specified by the 1th
+ // operation, a VTSDNode (currently always 64->32->64).
+ FP_ROUND_INREG,
+
+ // FP_EXTEND - Extend a smaller FP type into a larger FP type.
+ FP_EXTEND,
+
+ // BIT_CONVERT - Theis operator converts between integer and FP values, as
+ // if one was stored to memory as integer and the other was loaded from the
+ // same address (or equivalently for vector format conversions, etc). The
+ // source and result are required to have the same bit size (e.g.
+ // f32 <-> i32). This can also be used for int-to-int or fp-to-fp
+ // conversions, but that is a noop, deleted by getNode().
+ BIT_CONVERT,
+
+ // FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI - Perform unary floating point
+ // negation, absolute value, square root, sine and cosine, and powi
+ // operations.
+ FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI,
+
+ // LOAD and STORE have token chains as their first operand, then the same
+ // operands as an LLVM load/store instruction, then an offset node that
+ // is added / subtracted from the base pointer to form the address (for
+ // indexed memory ops).
+ LOAD, STORE,
+
+ // TRUNCSTORE - This operators truncates (for integer) or rounds (for FP) a
+ // value and stores it to memory in one operation. This can be used for
+ // either integer or floating point operands. The first four operands of
+ // this are the same as a standard store. The fifth is the ValueType to
+ // store it as (which will be smaller than the source value).
+ TRUNCSTORE,
+
+ // DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
+ // to a specified boundary. This node always has two return values: a new
+ // stack pointer value and a chain. The first operand is the token chain,
+ // the second is the number of bytes to allocate, and the third is the
+ // alignment boundary. The size is guaranteed to be a multiple of the stack
+ // alignment, and the alignment is guaranteed to be bigger than the stack
+ // alignment (if required) or 0 to get standard stack alignment.
+ DYNAMIC_STACKALLOC,
+
+ // Control flow instructions. These all have token chains.
+
+ // BR - Unconditional branch. The first operand is the chain
+ // operand, the second is the MBB to branch to.
+ BR,
+
+ // BRIND - Indirect branch. The first operand is the chain, the second
+ // is the value to branch to, which must be of the same type as the target's
+ // pointer type.
+ BRIND,
+
+ // BR_JT - Jumptable branch. The first operand is the chain, the second
+ // is the jumptable index, the last one is the jumptable entry index.
+ BR_JT,
+
+ // BRCOND - Conditional branch. The first operand is the chain,
+ // the second is the condition, the third is the block to branch
+ // to if the condition is true.
+ BRCOND,
+
+ // BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
+ // that the condition is represented as condition code, and two nodes to
+ // compare, rather than as a combined SetCC node. The operands in order are
+ // chain, cc, lhs, rhs, block to branch to if condition is true.
+ BR_CC,
+
+ // RET - Return from function. The first operand is the chain,
+ // and any subsequent operands are pairs of return value and return value
+ // signness for the function. This operation can have variable number of
+ // operands.
+ RET,
+
+ // INLINEASM - Represents an inline asm block. This node always has two
+ // return values: a chain and a flag result. The inputs are as follows:
+ // Operand #0 : Input chain.
+ // Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
+ // Operand #2n+2: A RegisterNode.
+ // Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
+ // Operand #last: Optional, an incoming flag.
+ INLINEASM,
+
+ // LABEL - Represents a label in mid basic block used to track
+ // locations needed for debug and exception handling tables. This node
+ // returns a chain.
+ // Operand #0 : input chain.
+ // Operand #1 : module unique number use to identify the label.
+ LABEL,
+
+ // STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
+ // value, the same type as the pointer type for the system, and an output
+ // chain.
+ STACKSAVE,
+
+ // STACKRESTORE has two operands, an input chain and a pointer to restore to
+ // it returns an output chain.
+ STACKRESTORE,
+
+ // MEMSET/MEMCPY/MEMMOVE - The first operand is the chain, and the rest
+ // correspond to the operands of the LLVM intrinsic functions. The only
+ // result is a token chain. The alignment argument is guaranteed to be a
+ // Constant node.
+ MEMSET,
+ MEMMOVE,
+ MEMCPY,
+
+ // CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
+ // a call sequence, and carry arbitrary information that target might want
+ // to know. The first operand is a chain, the rest are specified by the
+ // target and not touched by the DAG optimizers.
+ CALLSEQ_START, // Beginning of a call sequence
+ CALLSEQ_END, // End of a call sequence
+
+ // VAARG - VAARG has three operands: an input chain, a pointer, and a
+ // SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
+ VAARG,
+
+ // VACOPY - VACOPY has five operands: an input chain, a destination pointer,
+ // a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
+ // source.
+ VACOPY,
+
+ // VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
+ // pointer, and a SRCVALUE.
+ VAEND, VASTART,
+
+ // SRCVALUE - This corresponds to a Value*, and is used to associate memory
+ // locations with their value. This allows one use alias analysis
+ // information in the backend.
+ SRCVALUE,
+
+ // PCMARKER - This corresponds to the pcmarker intrinsic.
+ PCMARKER,
+
+ // READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
+ // The only operand is a chain and a value and a chain are produced. The
+ // value is the contents of the architecture specific cycle counter like
+ // register (or other high accuracy low latency clock source)
+ READCYCLECOUNTER,
+
+ // HANDLENODE node - Used as a handle for various purposes.
+ HANDLENODE,
+
+ // LOCATION - This node is used to represent a source location for debug
+ // info. It takes token chain as input, then a line number, then a column
+ // number, then a filename, then a working dir. It produces a token chain
+ // as output.
+ LOCATION,
+
+ // DEBUG_LOC - This node is used to represent source line information
+ // embedded in the code. It takes a token chain as input, then a line
+ // number, then a column then a file id (provided by MachineModuleInfo.) It
+ // produces a token chain as output.
+ DEBUG_LOC,
+
+ // BUILTIN_OP_END - This must be the last enum value in this list.
+ BUILTIN_OP_END
+ };
+
+ /// Node predicates
+
+ /// isBuildVectorAllOnes - 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
+ /// BUILD_VECTOR where all of the elements are 0 or undef.
+ bool isBuildVectorAllZeros(const SDNode *N);
+
+ //===--------------------------------------------------------------------===//
+ /// MemIndexedMode enum - This enum defines the load / store indexed
+ /// addressing modes.
+ ///
+ /// UNINDEXED "Normal" load / store. The effective address is already
+ /// computed and is available in the base pointer. The offset
+ /// operand is always undefined. In addition to producing a
+ /// chain, an unindexed load produces one value (result of the
+ /// load); an unindexed store does not produces a value.
+ ///
+ /// PRE_INC Similar to the unindexed mode where the effective address is
+ /// PRE_DEC the value of the base pointer add / subtract the offset.
+ /// It considers the computation as being folded into the load /
+ /// store operation (i.e. the load / store does the address
+ /// computation as well as performing the memory transaction).
+ /// The base operand is always undefined. In addition to
+ /// producing a chain, pre-indexed load produces two values
+ /// (result of the load and the result of the address
+ /// computation); a pre-indexed store produces one value (result
+ /// of the address computation).
+ ///
+ /// POST_INC The effective address is the value of the base pointer. The
+ /// POST_DEC value of the offset operand is then added to / subtracted
+ /// from the base after memory transaction. In addition to
+ /// producing a chain, post-indexed load produces two values
+ /// (the result of the load and the result of the base +/- offset
+ /// computation); a post-indexed store produces one value (the
+ /// the result of the base +/- offset computation).
+ ///
+ enum MemIndexedMode {
+ UNINDEXED = 0,
+ PRE_INC,
+ PRE_DEC,
+ POST_INC,
+ POST_DEC,
+ LAST_INDEXED_MODE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// LoadExtType enum - This enum defines the three variants of LOADEXT
+ /// (load with extension).
+ ///
+ /// SEXTLOAD loads the integer operand and sign extends it to a larger
+ /// integer result type.
+ /// ZEXTLOAD loads the integer operand and zero extends it to a larger
+ /// integer result type.
+ /// EXTLOAD is used for three things: floating point extending loads,
+ /// integer extending loads [the top bits are undefined], and vector
+ /// extending loads [load into low elt].
+ ///
+ enum LoadExtType {
+ NON_EXTLOAD = 0,
+ EXTLOAD,
+ SEXTLOAD,
+ ZEXTLOAD,
+ LAST_LOADX_TYPE
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// ISD::CondCode enum - These are ordered carefully to make the bitfields
+ /// below work out, when considering SETFALSE (something that never exists
+ /// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
+ /// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
+ /// to. If the "N" column is 1, the result of the comparison is undefined if
+ /// the input is a NAN.
+ ///
+ /// All of these (except for the 'always folded ops') should be handled for
+ /// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
+ /// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
+ ///
+ /// Note that these are laid out in a specific order to allow bit-twiddling
+ /// to transform conditions.
+ enum CondCode {
+ // Opcode N U L G E Intuitive operation
+ SETFALSE, // 0 0 0 0 Always false (always folded)
+ SETOEQ, // 0 0 0 1 True if ordered and equal
+ SETOGT, // 0 0 1 0 True if ordered and greater than
+ SETOGE, // 0 0 1 1 True if ordered and greater than or equal
+ SETOLT, // 0 1 0 0 True if ordered and less than
+ SETOLE, // 0 1 0 1 True if ordered and less than or equal
+ SETONE, // 0 1 1 0 True if ordered and operands are unequal
+ SETO, // 0 1 1 1 True if ordered (no nans)
+ SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ SETUEQ, // 1 0 0 1 True if unordered or equal
+ SETUGT, // 1 0 1 0 True if unordered or greater than
+ SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
+ SETULT, // 1 1 0 0 True if unordered or less than
+ SETULE, // 1 1 0 1 True if unordered, less than, or equal
+ SETUNE, // 1 1 1 0 True if unordered or not equal
+ SETTRUE, // 1 1 1 1 Always true (always folded)
+ // Don't care operations: undefined if the input is a nan.
+ SETFALSE2, // 1 X 0 0 0 Always false (always folded)
+ SETEQ, // 1 X 0 0 1 True if equal
+ SETGT, // 1 X 0 1 0 True if greater than
+ SETGE, // 1 X 0 1 1 True if greater than or equal
+ SETLT, // 1 X 1 0 0 True if less than
+ SETLE, // 1 X 1 0 1 True if less than or equal
+ SETNE, // 1 X 1 1 0 True if not equal
+ SETTRUE2, // 1 X 1 1 1 Always true (always folded)
+
+ SETCC_INVALID // Marker value.
+ };
+
+ /// isSignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs a signed comparison when used with integer operands.
+ inline bool isSignedIntSetCC(CondCode Code) {
+ return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
+ }
+
+ /// isUnsignedIntSetCC - Return true if this is a setcc instruction that
+ /// performs an unsigned comparison when used with integer operands.
+ inline bool isUnsignedIntSetCC(CondCode Code) {
+ return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
+ }
+
+ /// isTrueWhenEqual - Return true if the specified condition returns true if
+ /// the two operands to the condition are equal. Note that if one of the two
+ /// operands is a NaN, this value is meaningless.
+ inline bool isTrueWhenEqual(CondCode Cond) {
+ return ((int)Cond & 1) != 0;
+ }
+
+ /// getUnorderedFlavor - This function returns 0 if the condition is always
+ /// false if an operand is a NaN, 1 if the condition is always true if the
+ /// operand is a NaN, and 2 if the condition is undefined if the operand is a
+ /// NaN.
+ inline unsigned getUnorderedFlavor(CondCode Cond) {
+ return ((int)Cond >> 3) & 3;
+ }
+
+ /// getSetCCInverse - Return the operation corresponding to !(X op Y), where
+ /// 'op' is a valid SetCC operation.
+ CondCode getSetCCInverse(CondCode Operation, bool isInteger);
+
+ /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
+ /// when given the operation for (X op Y).
+ CondCode getSetCCSwappedOperands(CondCode Operation);
+
+ /// getSetCCOrOperation - Return the result of a logical OR between different
+ /// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
+
+ /// getSetCCAndOperation - Return the result of a logical AND between
+ /// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
+ /// function returns SETCC_INVALID if it is not possible to represent the
+ /// resultant comparison.
+ CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
+} // end llvm::ISD namespace
+
+
+//===----------------------------------------------------------------------===//
+/// SDOperand - 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
+/// of values).
+///
+/// As such, each use of a SelectionDAG computation must indicate the node that
+/// computes it as well as which return value to use from that node. This pair
+/// of information is represented with the SDOperand value type.
+///
+class SDOperand {
+public:
+ SDNode *Val; // The node defining the value we are using.
+ unsigned ResNo; // Which return value of the node we are using.
+
+ SDOperand() : Val(0), ResNo(0) {}
+ SDOperand(SDNode *val, unsigned resno) : Val(val), ResNo(resno) {}
+
+ bool operator==(const SDOperand &O) const {
+ return Val == O.Val && ResNo == O.ResNo;
+ }
+ bool operator!=(const SDOperand &O) const {
+ return !operator==(O);
+ }
+ bool operator<(const SDOperand &O) const {
+ return Val < O.Val || (Val == O.Val && ResNo < O.ResNo);
+ }
+
+ SDOperand getValue(unsigned R) const {
+ return SDOperand(Val, R);
+ }
+
+ // isOperand - Return true if this node is an operand of N.
+ bool isOperand(SDNode *N) const;
+
+ /// getValueType - Return the ValueType of the referenced return value.
+ ///
+ inline MVT::ValueType getValueType() const;
+
+ // Forwarding methods - These forward to the corresponding methods in SDNode.
+ inline unsigned getOpcode() const;
+ inline unsigned getNumOperands() const;
+ inline const SDOperand &getOperand(unsigned i) const;
+ inline uint64_t getConstantOperandVal(unsigned i) const;
+ inline bool isTargetOpcode() const;
+ inline unsigned getTargetOpcode() const;
+
+ /// hasOneUse - Return true if there is exactly one operation using this
+ /// result value of the defining operator.
+ inline bool hasOneUse() const;
+};
+
+
+template<> struct DenseMapKeyInfo<SDOperand> {
+ static inline SDOperand getEmptyKey() { return SDOperand((SDNode*)-1, -1U); }
+ static inline SDOperand getTombstoneKey() { return SDOperand((SDNode*)-1, 0);}
+ static unsigned getHashValue(const SDOperand &Val) {
+ return (unsigned)((uintptr_t)Val.Val >> 4) ^
+ (unsigned)((uintptr_t)Val.Val >> 9) + Val.ResNo;
+ }
+ static bool isPod() { return true; }
+};
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDOperands as if they were SDNode*'s.
+template<> struct simplify_type<SDOperand> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDOperand &Val) {
+ return static_cast<SimpleType>(Val.Val);
+ }
+};
+template<> struct simplify_type<const SDOperand> {
+ typedef SDNode* SimpleType;
+ static SimpleType getSimplifiedValue(const SDOperand &Val) {
+ return static_cast<SimpleType>(Val.Val);
+ }
+};
+
+
+/// SDNode - Represents one node in the SelectionDAG.
+///
+class SDNode : public FoldingSetNode {
+ /// NodeType - The operation that this node performs.
+ ///
+ unsigned short NodeType;
+
+ /// OperandsNeedDelete - This is true if OperandList was new[]'d. If true,
+ /// then they will be delete[]'d when the node is destroyed.
+ bool OperandsNeedDelete : 1;
+
+ /// NodeId - Unique id per SDNode in the DAG.
+ int NodeId;
+
+ /// OperandList - The values that are used by this operation.
+ ///
+ SDOperand *OperandList;
+
+ /// ValueList - The types of the values this node defines. SDNode's may
+ /// define multiple values simultaneously.
+ const MVT::ValueType *ValueList;
+
+ /// NumOperands/NumValues - The number of entries in the Operand/Value list.
+ unsigned short NumOperands, NumValues;
+
+ /// Prev/Next pointers - These pointers form the linked list of of the
+ /// AllNodes list in the current DAG.
+ SDNode *Prev, *Next;
+ friend struct ilist_traits<SDNode>;
+
+ /// Uses - These are all of the SDNode's that use a value produced by this
+ /// node.
+ SmallVector<SDNode*,3> Uses;
+
+ // Out-of-line virtual method to give class a home.
+ virtual void ANCHOR();
+public:
+ virtual ~SDNode() {
+ assert(NumOperands == 0 && "Operand list not cleared before deletion");
+ NodeType = ISD::DELETED_NODE;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Accessors
+ //
+ unsigned getOpcode() const { return NodeType; }
+ bool isTargetOpcode() const { return NodeType >= ISD::BUILTIN_OP_END; }
+ unsigned getTargetOpcode() const {
+ assert(isTargetOpcode() && "Not a target opcode!");
+ return NodeType - ISD::BUILTIN_OP_END;
+ }
+
+ size_t use_size() const { return Uses.size(); }
+ bool use_empty() const { return Uses.empty(); }
+ bool hasOneUse() const { return Uses.size() == 1; }
+
+ /// getNodeId - Return the unique node id.
+ ///
+ int getNodeId() const { return NodeId; }
+
+ typedef SmallVector<SDNode*,3>::const_iterator use_iterator;
+ use_iterator use_begin() const { return Uses.begin(); }
+ use_iterator use_end() const { return Uses.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.
+ bool hasNUsesOfValue(unsigned NUses, unsigned Value) const;
+
+ /// isOnlyUse - Return true if this node is the only use of N.
+ ///
+ bool isOnlyUse(SDNode *N) const;
+
+ /// isOperand - Return true if this node is an operand of N.
+ ///
+ bool isOperand(SDNode *N) const;
+
+ /// isPredecessor - Return true if this node is a predecessor of N. This node
+ /// is either an operand of N or it can be reached by recursively traversing
+ /// up the operands.
+ /// NOTE: this is an expensive method. Use it carefully.
+ bool isPredecessor(SDNode *N) const;
+
+ /// getNumOperands - 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.
+ uint64_t getConstantOperandVal(unsigned Num) const;
+
+ const SDOperand &getOperand(unsigned Num) const {
+ assert(Num < NumOperands && "Invalid child # of SDNode!");
+ return OperandList[Num];
+ }
+
+ typedef const SDOperand* op_iterator;
+ op_iterator op_begin() const { return OperandList; }
+ op_iterator op_end() const { return OperandList+NumOperands; }
+
+
+ SDVTList getVTList() const {
+ SDVTList X = { ValueList, NumValues };
+ return X;
+ };
+
+ /// getNumValues - Return the number of values defined/returned by this
+ /// operator.
+ ///
+ unsigned getNumValues() const { return NumValues; }
+
+ /// getValueType - Return the type of a specified result.
+ ///
+ MVT::ValueType getValueType(unsigned ResNo) const {
+ assert(ResNo < NumValues && "Illegal result number!");
+ return ValueList[ResNo];
+ }
+
+ typedef const MVT::ValueType* value_iterator;
+ value_iterator value_begin() const { return ValueList; }
+ value_iterator value_end() const { return ValueList+NumValues; }
+
+ /// getOperationName - Return the opcode of this operation for printing.
+ ///
+ std::string getOperationName(const SelectionDAG *G = 0) const;
+ static const char* getIndexedModeName(ISD::MemIndexedMode AM);
+ void dump() const;
+ void dump(const SelectionDAG *G) const;
+
+ static bool classof(const SDNode *) { return true; }
+
+ /// Profile - Gather unique data for the node.
+ ///
+ void Profile(FoldingSetNodeID &ID);
+
+protected:
+ friend class SelectionDAG;
+
+ /// getValueTypeList - Return a pointer to the specified value type.
+ ///
+ static MVT::ValueType *getValueTypeList(MVT::ValueType VT);
+ static SDVTList getSDVTList(MVT::ValueType VT) {
+ SDVTList Ret = { getValueTypeList(VT), 1 };
+ return Ret;
+ }
+
+ SDNode(unsigned Opc, SDVTList VTs, const SDOperand *Ops, unsigned NumOps)
+ : NodeType(Opc), NodeId(-1) {
+ OperandsNeedDelete = true;
+ NumOperands = NumOps;
+ OperandList = NumOps ? new SDOperand[NumOperands] : 0;
+
+ for (unsigned i = 0; i != NumOps; ++i) {
+ OperandList[i] = Ops[i];
+ Ops[i].Val->Uses.push_back(this);
+ }
+
+ ValueList = VTs.VTs;
+ NumValues = VTs.NumVTs;
+ Prev = 0; Next = 0;
+ }
+ SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), NodeId(-1) {
+ OperandsNeedDelete = false; // Operands set with InitOperands.
+ NumOperands = 0;
+ OperandList = 0;
+
+ ValueList = VTs.VTs;
+ NumValues = VTs.NumVTs;
+ Prev = 0; Next = 0;
+ }
+
+ /// InitOperands - Initialize the operands list of this node with the
+ /// specified values, which are part of the node (thus they don't need to be
+ /// copied in or allocated).
+ void InitOperands(SDOperand *Ops, unsigned NumOps) {
+ assert(OperandList == 0 && "Operands already set!");
+ NumOperands = NumOps;
+ OperandList = Ops;
+
+ for (unsigned i = 0; i != NumOps; ++i)
+ Ops[i].Val->Uses.push_back(this);
+ }
+
+ /// MorphNodeTo - This frees the operands of the current node, resets the
+ /// opcode, types, and operands to the specified value. This should only be
+ /// used by the SelectionDAG class.
+ void MorphNodeTo(unsigned Opc, SDVTList L,
+ const SDOperand *Ops, unsigned NumOps);
+
+ void addUser(SDNode *User) {
+ Uses.push_back(User);
+ }
+ void removeUser(SDNode *User) {
+ // Remove this user from the operand's use list.
+ for (unsigned i = Uses.size(); ; --i) {
+ assert(i != 0 && "Didn't find user!");
+ if (Uses[i-1] == User) {
+ Uses[i-1] = Uses.back();
+ Uses.pop_back();
+ return;
+ }
+ }
+ }
+
+ void setNodeId(int Id) {
+ NodeId = Id;
+ }
+};
+
+
+// Define inline functions from the SDOperand class.
+
+inline unsigned SDOperand::getOpcode() const {
+ return Val->getOpcode();
+}
+inline MVT::ValueType SDOperand::getValueType() const {
+ return Val->getValueType(ResNo);
+}
+inline unsigned SDOperand::getNumOperands() const {
+ return Val->getNumOperands();
+}
+inline const SDOperand &SDOperand::getOperand(unsigned i) const {
+ return Val->getOperand(i);
+}
+inline uint64_t SDOperand::getConstantOperandVal(unsigned i) const {
+ return Val->getConstantOperandVal(i);
+}
+inline bool SDOperand::isTargetOpcode() const {
+ return Val->isTargetOpcode();
+}
+inline unsigned SDOperand::getTargetOpcode() const {
+ return Val->getTargetOpcode();
+}
+inline bool SDOperand::hasOneUse() const {
+ return Val->hasNUsesOfValue(1, ResNo);
+}
+
+/// UnarySDNode - 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 {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Op;
+public:
+ UnarySDNode(unsigned Opc, SDVTList VTs, SDOperand X)
+ : SDNode(Opc, VTs), Op(X) {
+ InitOperands(&Op, 1);
+ }
+};
+
+/// BinarySDNode - 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 {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[2];
+public:
+ BinarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ InitOperands(Ops, 2);
+ }
+};
+
+/// TernarySDNode - 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 {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[3];
+public:
+ TernarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y,
+ SDOperand Z)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ Ops[2] = Z;
+ InitOperands(Ops, 3);
+ }
+};
+
+
+/// HandleSDNode - This class is used to form a handle around another node that
+/// is persistant 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.
+class HandleSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Op;
+public:
+ explicit HandleSDNode(SDOperand X)
+ : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)), Op(X) {
+ InitOperands(&Op, 1);
+ }
+ ~HandleSDNode();
+ SDOperand getValue() const { return Op; }
+};
+
+class StringSDNode : public SDNode {
+ std::string Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit StringSDNode(const std::string &val)
+ : SDNode(ISD::STRING, getSDVTList(MVT::Other)), Value(val) {
+ }
+public:
+ const std::string &getValue() const { return Value; }
+ static bool classof(const StringSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STRING;
+ }
+};
+
+class ConstantSDNode : public SDNode {
+ uint64_t Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantSDNode(bool isTarget, uint64_t val, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetConstant : ISD::Constant, getSDVTList(VT)),
+ Value(val) {
+ }
+public:
+
+ uint64_t getValue() const { return Value; }
+
+ int64_t getSignExtended() const {
+ unsigned Bits = MVT::getSizeInBits(getValueType(0));
+ return ((int64_t)Value << (64-Bits)) >> (64-Bits);
+ }
+
+ bool isNullValue() const { return Value == 0; }
+ bool isAllOnesValue() const {
+ return Value == MVT::getIntVTBitMask(getValueType(0));
+ }
+
+ static bool classof(const ConstantSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::Constant ||
+ N->getOpcode() == ISD::TargetConstant;
+ }
+};
+
+class ConstantFPSDNode : public SDNode {
+ double Value;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantFPSDNode(bool isTarget, double val, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetConstantFP : ISD::ConstantFP,
+ getSDVTList(VT)), Value(val) {
+ }
+public:
+
+ double getValue() const { return Value; }
+
+ /// isExactlyValue - 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.
+ bool isExactlyValue(double V) const;
+
+ static bool classof(const ConstantFPSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ConstantFP ||
+ N->getOpcode() == ISD::TargetConstantFP;
+ }
+};
+
+class GlobalAddressSDNode : public SDNode {
+ GlobalValue *TheGlobal;
+ int Offset;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MVT::ValueType VT,
+ int o = 0);
+public:
+
+ GlobalValue *getGlobal() const { return TheGlobal; }
+ int getOffset() const { return Offset; }
+
+ static bool classof(const GlobalAddressSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::GlobalAddress ||
+ N->getOpcode() == ISD::TargetGlobalAddress ||
+ N->getOpcode() == ISD::GlobalTLSAddress ||
+ N->getOpcode() == ISD::TargetGlobalTLSAddress;
+ }
+};
+
+class FrameIndexSDNode : public SDNode {
+ int FI;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ FrameIndexSDNode(int fi, MVT::ValueType VT, bool isTarg)
+ : SDNode(isTarg ? ISD::TargetFrameIndex : ISD::FrameIndex, getSDVTList(VT)),
+ FI(fi) {
+ }
+public:
+
+ int getIndex() const { return FI; }
+
+ static bool classof(const FrameIndexSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::FrameIndex ||
+ N->getOpcode() == ISD::TargetFrameIndex;
+ }
+};
+
+class JumpTableSDNode : public SDNode {
+ int JTI;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ JumpTableSDNode(int jti, MVT::ValueType VT, bool isTarg)
+ : SDNode(isTarg ? ISD::TargetJumpTable : ISD::JumpTable, getSDVTList(VT)),
+ JTI(jti) {
+ }
+public:
+
+ int getIndex() const { return JTI; }
+
+ static bool classof(const JumpTableSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::JumpTable ||
+ N->getOpcode() == ISD::TargetJumpTable;
+ }
+};
+
+class ConstantPoolSDNode : public SDNode {
+ union {
+ Constant *ConstVal;
+ MachineConstantPoolValue *MachineCPVal;
+ } Val;
+ int Offset; // It's a MachineConstantPoolValue if top bit is set.
+ unsigned Alignment;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT,
+ int o=0)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(0) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = c;
+ }
+ ConstantPoolSDNode(bool isTarget, Constant *c, MVT::ValueType VT, int o,
+ unsigned Align)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(Align) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.ConstVal = c;
+ }
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+ MVT::ValueType VT, int o=0)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(0) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = v;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+ ConstantPoolSDNode(bool isTarget, MachineConstantPoolValue *v,
+ MVT::ValueType VT, int o, unsigned Align)
+ : SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
+ getSDVTList(VT)), Offset(o), Alignment(Align) {
+ assert((int)Offset >= 0 && "Offset is too large");
+ Val.MachineCPVal = v;
+ Offset |= 1 << (sizeof(unsigned)*8-1);
+ }
+public:
+
+ bool isMachineConstantPoolEntry() const {
+ return (int)Offset < 0;
+ }
+
+ Constant *getConstVal() const {
+ assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.ConstVal;
+ }
+
+ MachineConstantPoolValue *getMachineCPVal() const {
+ assert(isMachineConstantPoolEntry() && "Wrong constantpool type");
+ return Val.MachineCPVal;
+ }
+
+ int getOffset() const {
+ return Offset & ~(1 << (sizeof(unsigned)*8-1));
+ }
+
+ // Return the alignment of this constant pool object, which is either 0 (for
+ // default alignment) or log2 of the desired value.
+ unsigned getAlignment() const { return Alignment; }
+
+ const Type *getType() const;
+
+ static bool classof(const ConstantPoolSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ConstantPool ||
+ N->getOpcode() == ISD::TargetConstantPool;
+ }
+};
+
+class BasicBlockSDNode : public SDNode {
+ MachineBasicBlock *MBB;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit BasicBlockSDNode(MachineBasicBlock *mbb)
+ : SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) {
+ }
+public:
+
+ MachineBasicBlock *getBasicBlock() const { return MBB; }
+
+ static bool classof(const BasicBlockSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::BasicBlock;
+ }
+};
+
+class SrcValueSDNode : public SDNode {
+ const Value *V;
+ int offset;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ SrcValueSDNode(const Value* v, int o)
+ : SDNode(ISD::SRCVALUE, getSDVTList(MVT::Other)), V(v), offset(o) {
+ }
+
+public:
+ const Value *getValue() const { return V; }
+ int getOffset() const { return offset; }
+
+ static bool classof(const SrcValueSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::SRCVALUE;
+ }
+};
+
+
+class RegisterSDNode : public SDNode {
+ unsigned Reg;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ RegisterSDNode(unsigned reg, MVT::ValueType VT)
+ : SDNode(ISD::Register, getSDVTList(VT)), Reg(reg) {
+ }
+public:
+
+ unsigned getReg() const { return Reg; }
+
+ static bool classof(const RegisterSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::Register;
+ }
+};
+
+class ExternalSymbolSDNode : public SDNode {
+ const char *Symbol;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ ExternalSymbolSDNode(bool isTarget, const char *Sym, MVT::ValueType VT)
+ : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol,
+ getSDVTList(VT)), Symbol(Sym) {
+ }
+public:
+
+ const char *getSymbol() const { return Symbol; }
+
+ static bool classof(const ExternalSymbolSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::ExternalSymbol ||
+ N->getOpcode() == ISD::TargetExternalSymbol;
+ }
+};
+
+class CondCodeSDNode : public SDNode {
+ ISD::CondCode Condition;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit CondCodeSDNode(ISD::CondCode Cond)
+ : SDNode(ISD::CONDCODE, getSDVTList(MVT::Other)), Condition(Cond) {
+ }
+public:
+
+ ISD::CondCode get() const { return Condition; }
+
+ static bool classof(const CondCodeSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::CONDCODE;
+ }
+};
+
+/// VTSDNode - This class is used to represent MVT::ValueType's, which are used
+/// to parameterize some operations.
+class VTSDNode : public SDNode {
+ MVT::ValueType ValueType;
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+protected:
+ friend class SelectionDAG;
+ explicit VTSDNode(MVT::ValueType VT)
+ : SDNode(ISD::VALUETYPE, getSDVTList(MVT::Other)), ValueType(VT) {
+ }
+public:
+
+ MVT::ValueType getVT() const { return ValueType; }
+
+ static bool classof(const VTSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::VALUETYPE;
+ }
+};
+
+/// LoadSDNode - This class is used to represent ISD::LOAD nodes.
+///
+class LoadSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[3];
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // ExtType - non-ext, anyext, sext, zext.
+ ISD::LoadExtType ExtType;
+
+ // LoadedVT - VT of loaded value before extension.
+ MVT::ValueType LoadedVT;
+
+ // SrcValue - Memory location for alias analysis.
+ const Value *SrcValue;
+
+ // SVOffset - Memory location offset.
+ int SVOffset;
+
+ // Alignment - Alignment of memory location in bytes.
+ unsigned Alignment;
+
+ // IsVolatile - True if the load is volatile.
+ bool IsVolatile;
+protected:
+ friend class SelectionDAG;
+ LoadSDNode(SDOperand *ChainPtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT::ValueType LVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : SDNode(ISD::LOAD, VTs),
+ AddrMode(AM), ExtType(ETy), LoadedVT(LVT), SrcValue(SV), SVOffset(O),
+ Alignment(Align), IsVolatile(Vol) {
+ Ops[0] = ChainPtrOff[0]; // Chain
+ Ops[1] = ChainPtrOff[1]; // Ptr
+ Ops[2] = ChainPtrOff[2]; // Off
+ InitOperands(Ops, 3);
+ assert(Align != 0 && "Loads should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF ||
+ AddrMode != ISD::UNINDEXED) &&
+ "Only indexed load has a non-undef offset operand");
+ }
+public:
+
+ const SDOperand getChain() const { return getOperand(0); }
+ const SDOperand getBasePtr() const { return getOperand(1); }
+ const SDOperand getOffset() const { return getOperand(2); }
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+ ISD::LoadExtType getExtensionType() const { return ExtType; }
+ MVT::ValueType getLoadedVT() const { return LoadedVT; }
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ bool isVolatile() const { return IsVolatile; }
+
+ static bool classof(const LoadSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD;
+ }
+};
+
+/// StoreSDNode - This class is used to represent ISD::STORE nodes.
+///
+class StoreSDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[4];
+
+ // AddrMode - unindexed, pre-indexed, post-indexed.
+ ISD::MemIndexedMode AddrMode;
+
+ // IsTruncStore - True is the op does a truncation before store.
+ bool IsTruncStore;
+
+ // StoredVT - VT of the value after truncation.
+ MVT::ValueType StoredVT;
+
+ // SrcValue - Memory location for alias analysis.
+ const Value *SrcValue;
+
+ // SVOffset - Memory location offset.
+ int SVOffset;
+
+ // Alignment - Alignment of memory location in bytes.
+ unsigned Alignment;
+
+ // IsVolatile - True if the store is volatile.
+ bool IsVolatile;
+protected:
+ friend class SelectionDAG;
+ StoreSDNode(SDOperand *ChainValuePtrOff, SDVTList VTs,
+ ISD::MemIndexedMode AM, bool isTrunc, MVT::ValueType SVT,
+ const Value *SV, int O=0, unsigned Align=0, bool Vol=false)
+ : SDNode(ISD::STORE, VTs),
+ AddrMode(AM), IsTruncStore(isTrunc), StoredVT(SVT), SrcValue(SV),
+ SVOffset(O), Alignment(Align), IsVolatile(Vol) {
+ Ops[0] = ChainValuePtrOff[0]; // Chain
+ Ops[1] = ChainValuePtrOff[1]; // Value
+ Ops[2] = ChainValuePtrOff[2]; // Ptr
+ Ops[3] = ChainValuePtrOff[3]; // Off
+ InitOperands(Ops, 4);
+ assert(Align != 0 && "Stores should have non-zero aligment");
+ assert((getOffset().getOpcode() == ISD::UNDEF ||
+ AddrMode != ISD::UNINDEXED) &&
+ "Only indexed store has a non-undef offset operand");
+ }
+public:
+
+ const SDOperand getChain() const { return getOperand(0); }
+ const SDOperand getValue() const { return getOperand(1); }
+ const SDOperand getBasePtr() const { return getOperand(2); }
+ const SDOperand getOffset() const { return getOperand(3); }
+ ISD::MemIndexedMode getAddressingMode() const { return AddrMode; }
+ bool isTruncatingStore() const { return IsTruncStore; }
+ MVT::ValueType getStoredVT() const { return StoredVT; }
+ const Value *getSrcValue() const { return SrcValue; }
+ int getSrcValueOffset() const { return SVOffset; }
+ unsigned getAlignment() const { return Alignment; }
+ bool isVolatile() const { return IsVolatile; }
+
+ static bool classof(const StoreSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE;
+ }
+};
+
+
+class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> {
+ SDNode *Node;
+ unsigned Operand;
+
+ SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
+public:
+ bool operator==(const SDNodeIterator& x) const {
+ return Operand == x.Operand;
+ }
+ 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).Val;
+ }
+ pointer operator->() const { return operator*(); }
+
+ SDNodeIterator& operator++() { // Preincrement
+ ++Operand;
+ return *this;
+ }
+ SDNodeIterator operator++(int) { // Postincrement
+ SDNodeIterator tmp = *this; ++*this; return tmp;
+ }
+
+ static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
+ static SDNodeIterator end (SDNode *N) {
+ return SDNodeIterator(N, N->getNumOperands());
+ }
+
+ unsigned getOperand() const { return Operand; }
+ const SDNode *getNode() const { return Node; }
+};
+
+template <> struct GraphTraits<SDNode*> {
+ typedef SDNode NodeType;
+ typedef SDNodeIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(SDNode *N) { return N; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return SDNodeIterator::begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return SDNodeIterator::end(N);
+ }
+};
+
+template<>
+struct ilist_traits<SDNode> {
+ static SDNode *getPrev(const SDNode *N) { return N->Prev; }
+ static SDNode *getNext(const SDNode *N) { return N->Next; }
+
+ static void setPrev(SDNode *N, SDNode *Prev) { N->Prev = Prev; }
+ static void setNext(SDNode *N, SDNode *Next) { N->Next = Next; }
+
+ static SDNode *createSentinel() {
+ return new SDNode(ISD::EntryToken, SDNode::getSDVTList(MVT::Other));
+ }
+ static void destroySentinel(SDNode *N) { delete N; }
+ //static SDNode *createNode(const SDNode &V) { return new SDNode(V); }
+
+
+ void addNodeToList(SDNode *NTy) {}
+ void removeNodeFromList(SDNode *NTy) {}
+ void transferNodesFromList(iplist<SDNode, ilist_traits> &L2,
+ const ilist_iterator<SDNode> &X,
+ const ilist_iterator<SDNode> &Y) {}
+};
+
+namespace ISD {
+ /// isNON_EXTLoad - Returns true if the specified node is a non-extending
+ /// load.
+ inline bool isNON_EXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
+ }
+
+ /// isEXTLoad - Returns true if the specified node is a EXTLOAD.
+ ///
+ inline bool isEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::EXTLOAD;
+ }
+
+ /// isSEXTLoad - Returns true if the specified node is a SEXTLOAD.
+ ///
+ inline bool isSEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
+ }
+
+ /// isZEXTLoad - Returns true if the specified node is a ZEXTLOAD.
+ ///
+ inline bool isZEXTLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getExtensionType() == ISD::ZEXTLOAD;
+ }
+
+ /// isUNINDEXEDLoad - Returns true if the specified node is a unindexed load.
+ ///
+ inline bool isUNINDEXEDLoad(const SDNode *N) {
+ return N->getOpcode() == ISD::LOAD &&
+ cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED;
+ }
+
+ /// isNON_TRUNCStore - Returns true if the specified node is a non-truncating
+ /// store.
+ inline bool isNON_TRUNCStore(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE &&
+ !cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+
+ /// isTRUNCStore - Returns true if the specified node is a truncating
+ /// store.
+ inline bool isTRUNCStore(const SDNode *N) {
+ return N->getOpcode() == ISD::STORE &&
+ cast<StoreSDNode>(N)->isTruncatingStore();
+ }
+}
+
+
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/SimpleRegisterCoalescing.h b/include/llvm/CodeGen/SimpleRegisterCoalescing.h
new file mode 100644
index 0000000..20bcb89
--- /dev/null
+++ b/include/llvm/CodeGen/SimpleRegisterCoalescing.h
@@ -0,0 +1,160 @@
+//===-- SimpleRegisterCoalescing.h - Register Coalescing --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a simple register copy coalescing phase.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H
+#define LLVM_CODEGEN_SIMPLE_REGISTER_COALESCING_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/LiveInterval.h"
+#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/IndexedMap.h"
+
+namespace llvm {
+
+ class LiveVariables;
+ class MRegisterInfo;
+ class TargetInstrInfo;
+ class VirtRegMap;
+
+ class SimpleRegisterCoalescing : public MachineFunctionPass {
+ MachineFunction* mf_;
+ const TargetMachine* tm_;
+ const MRegisterInfo* mri_;
+ const TargetInstrInfo* tii_;
+ LiveIntervals *li_;
+ LiveVariables *lv_;
+
+ typedef IndexedMap<unsigned> Reg2RegMap;
+ Reg2RegMap r2rMap_;
+
+ BitVector allocatableRegs_;
+ DenseMap<const TargetRegisterClass*, BitVector> allocatableRCRegs_;
+
+ /// JoinedLIs - Keep track which register intervals have been coalesced
+ /// with other intervals.
+ BitVector JoinedLIs;
+
+ public:
+ static char ID; // Pass identifcation, replacement for typeid
+ SimpleRegisterCoalescing() : MachineFunctionPass((intptr_t)&ID) {};
+
+ struct CopyRec {
+ MachineInstr *MI;
+ unsigned SrcReg, DstReg;
+ };
+ CopyRec getCopyRec(MachineInstr *MI, unsigned SrcReg, unsigned DstReg) {
+ CopyRec R;
+ R.MI = MI;
+ R.SrcReg = SrcReg;
+ R.DstReg = DstReg;
+ return R;
+ }
+ struct InstrSlots {
+ enum {
+ LOAD = 0,
+ USE = 1,
+ DEF = 2,
+ STORE = 3,
+ NUM = 4
+ };
+ };
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+ virtual void releaseMemory();
+
+ /// runOnMachineFunction - pass entry point
+ virtual bool runOnMachineFunction(MachineFunction&);
+
+ /// print - Implement the dump method.
+ virtual void print(std::ostream &O, const Module* = 0) const;
+ void print(std::ostream *O, const Module* M = 0) const {
+ if (O) print(*O, M);
+ }
+
+ private:
+ /// joinIntervals - join compatible live intervals
+ void joinIntervals();
+
+ /// CopyCoalesceInMBB - Coalesce copies in the specified MBB, putting
+ /// copies that cannot yet be coalesced into the "TryAgain" list.
+ void CopyCoalesceInMBB(MachineBasicBlock *MBB,
+ std::vector<CopyRec> *TryAgain, bool PhysOnly = false);
+
+ /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg,
+ /// which are the src/dst of the copy instruction CopyMI. This returns true
+ /// if the copy was successfully coalesced away, or if it is never possible
+ /// to coalesce these this copy, due to register constraints. It returns
+ /// false if it is not currently possible to coalesce this interval, but
+ /// it may be possible if other things get coalesced.
+ bool JoinCopy(MachineInstr *CopyMI, unsigned SrcReg, unsigned DstReg,
+ bool PhysOnly = false);
+
+ /// JoinIntervals - Attempt to join these two intervals. On failure, this
+ /// returns false. Otherwise, if one of the intervals being joined is a
+ /// physreg, this method always canonicalizes DestInt to be it. The output
+ /// "SrcInt" will not have been modified, so we can use this information
+ /// below to update aliases.
+ bool JoinIntervals(LiveInterval &LHS, LiveInterval &RHS);
+
+ /// SimpleJoin - Attempt to join the specified interval into this one. The
+ /// caller of this method must guarantee that the RHS only contains a single
+ /// value number and that the RHS is not defined by a copy from this
+ /// interval. This returns false if the intervals are not joinable, or it
+ /// joins them and returns true.
+ bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS);
+
+ /// Return true if the two specified registers belong to different
+ /// register classes. The registers may be either phys or virt regs.
+ bool differingRegisterClasses(unsigned RegA, unsigned RegB) const;
+
+
+ bool AdjustCopiesBackFrom(LiveInterval &IntA, LiveInterval &IntB,
+ MachineInstr *CopyMI);
+
+ /// lastRegisterUse - Returns the last use of the specific register between
+ /// cycles Start and End. It also returns the use operand by reference. It
+ /// returns NULL if there are no uses.
+ MachineInstr *lastRegisterUse(unsigned Start, unsigned End, unsigned Reg,
+ MachineOperand *&MOU);
+
+ /// findDefOperand - Returns the MachineOperand that is a def of the specific
+ /// register. It returns NULL if the def is not found.
+ MachineOperand *findDefOperand(MachineInstr *MI, unsigned Reg);
+
+ /// unsetRegisterKill - Unset IsKill property of all uses of the specific
+ /// register of the specific instruction.
+ void unsetRegisterKill(MachineInstr *MI, unsigned Reg);
+
+ /// unsetRegisterKills - Unset IsKill property of all uses of specific register
+ /// between cycles Start and End.
+ void unsetRegisterKills(unsigned Start, unsigned End, unsigned Reg);
+
+ /// hasRegisterDef - True if the instruction defines the specific register.
+ ///
+ bool hasRegisterDef(MachineInstr *MI, unsigned Reg);
+
+ /// rep - returns the representative of this register
+ unsigned rep(unsigned Reg) {
+ unsigned Rep = r2rMap_[Reg];
+ if (Rep)
+ return r2rMap_[Reg] = rep(Rep);
+ return Reg;
+ }
+
+ void printRegName(unsigned reg) const;
+ };
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.h b/include/llvm/CodeGen/ValueTypes.h
new file mode 100644
index 0000000..d2a6414
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.h
@@ -0,0 +1,284 @@
+//===- CodeGen/ValueTypes.h - Low-Level Target independ. types --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the set of low-level target independent types which various
+// values in the code generator are. This allows the target specific behavior
+// of instructions to be described to target independent passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CODEGEN_VALUETYPES_H
+#define LLVM_CODEGEN_VALUETYPES_H
+
+#include <cassert>
+#include <string>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class Type;
+
+/// MVT namespace - This namespace defines the SimpleValueType enum, which
+/// contains the various low-level value types, and the ValueType typedef.
+///
+namespace MVT { // MVT = Machine Value Types
+ enum SimpleValueType {
+ // If you change this numbering, you must change the values in ValueTypes.td
+ // well!
+ Other = 0, // This is a non-standard value
+ i1 = 1, // This is a 1 bit integer value
+ i8 = 2, // This is an 8 bit integer value
+ i16 = 3, // This is a 16 bit integer value
+ i32 = 4, // This is a 32 bit integer value
+ i64 = 5, // This is a 64 bit integer value
+ i128 = 6, // This is a 128 bit integer value
+
+ f32 = 7, // This is a 32 bit floating point value
+ f64 = 8, // This is a 64 bit floating point value
+ f80 = 9, // This is a 80 bit floating point value
+ f128 = 10, // This is a 128 bit floating point value
+ Flag = 11, // This is a condition code or machine flag.
+
+ isVoid = 12, // This has no value
+
+ v8i8 = 13, // 8 x i8
+ v4i16 = 14, // 4 x i16
+ v2i32 = 15, // 2 x i32
+ v1i64 = 16, // 1 x i64
+ v16i8 = 17, // 16 x i8
+ v8i16 = 18, // 8 x i16
+ v4i32 = 19, // 4 x i32
+ v2i64 = 20, // 2 x i64
+
+ v2f32 = 21, // 2 x f32
+ v4f32 = 22, // 4 x f32
+ v2f64 = 23, // 2 x f64
+ FIRST_VECTOR_VALUETYPE = v8i8,
+ LAST_VECTOR_VALUETYPE = v2f64,
+
+ LAST_VALUETYPE = 24, // This always remains at the end of the list.
+
+ // iAny - An integer value of any bit width. This is used for intrinsics
+ // that have overloadings based on integer bit widths. This is only for
+ // tblgen's consumption!
+ iAny = 254,
+
+ // iPTR - An int value the size of the pointer of the current
+ // target. This should only be used internal to tblgen!
+ iPTR = 255
+ };
+
+ /// MVT::ValueType - This type holds low-level value types. Valid values
+ /// include any of the values in the SimpleValueType enum, or any value
+ /// returned from a function in the MVT namespace that has a ValueType
+ /// return type. Any value type equal to one of the SimpleValueType enum
+ /// values is a "simple" value type. All other value types are "extended".
+ ///
+ /// Note that simple doesn't necessary mean legal for the target machine.
+ /// All legal value types must be simple, but often there are some simple
+ /// value types that are not legal.
+ ///
+ /// @internal
+ /// Currently extended types are always vector types. Extended types are
+ /// encoded by having the first SimpleTypeBits bits encode the vector
+ /// element type (which must be a scalar type) and the remaining upper
+ /// bits encode the vector length, offset by one.
+ typedef uint32_t ValueType;
+
+ static const int SimpleTypeBits = 8;
+
+ static const uint32_t SimpleTypeMask =
+ (~uint32_t(0) << (32 - SimpleTypeBits)) >> (32 - SimpleTypeBits);
+
+ /// MVT::isExtendedVT - Test if the given ValueType is extended
+ /// (as opposed to being simple).
+ static inline bool isExtendedVT(ValueType VT) {
+ return VT > SimpleTypeMask;
+ }
+
+ /// MVT::isInteger - Return true if this is an integer, or a vector integer
+ /// type.
+ static inline bool isInteger(ValueType VT) {
+ ValueType SVT = VT & SimpleTypeMask;
+ return (SVT >= i1 && SVT <= i128) || (SVT >= v8i8 && SVT <= v2i64);
+ }
+
+ /// MVT::isFloatingPoint - Return true if this is an FP, or a vector FP type.
+ static inline bool isFloatingPoint(ValueType VT) {
+ ValueType SVT = VT & SimpleTypeMask;
+ return (SVT >= f32 && SVT <= f128) || (SVT >= v2f32 && SVT <= v2f64);
+ }
+
+ /// MVT::isVector - Return true if this is a vector value type.
+ static inline bool isVector(ValueType VT) {
+ return (VT >= FIRST_VECTOR_VALUETYPE && VT <= LAST_VECTOR_VALUETYPE) ||
+ isExtendedVT(VT);
+ }
+
+ /// MVT::getVectorElementType - Given a vector type, return the type of
+ /// each element.
+ static inline ValueType getVectorElementType(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return VT & SimpleTypeMask;
+ assert(0 && "Invalid vector type!");
+ case v8i8 :
+ case v16i8: return i8;
+ case v4i16:
+ case v8i16: return i16;
+ case v2i32:
+ case v4i32: return i32;
+ case v1i64:
+ case v2i64: return i64;
+ case v2f32:
+ case v4f32: return f32;
+ case v2f64: return f64;
+ }
+ }
+
+ /// MVT::getVectorNumElements - Given a vector type, return the
+ /// number of elements it contains.
+ static inline unsigned getVectorNumElements(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return ((VT & ~SimpleTypeMask) >> SimpleTypeBits) - 1;
+ assert(0 && "Invalid vector type!");
+ case v16i8: return 16;
+ case v8i8 :
+ case v8i16: return 8;
+ case v4i16:
+ case v4i32:
+ case v4f32: return 4;
+ case v2i32:
+ case v2i64:
+ case v2f32:
+ case v2f64: return 2;
+ case v1i64: return 1;
+ }
+ }
+
+ /// MVT::getSizeInBits - Return the size of the specified value type
+ /// in bits.
+ ///
+ static inline unsigned getSizeInBits(ValueType VT) {
+ switch (VT) {
+ default:
+ if (isExtendedVT(VT))
+ return getSizeInBits(getVectorElementType(VT)) *
+ getVectorNumElements(VT);
+ assert(0 && "ValueType has no known size!");
+ case MVT::i1 : return 1;
+ case MVT::i8 : return 8;
+ case MVT::i16 : return 16;
+ case MVT::f32 :
+ case MVT::i32 : return 32;
+ case MVT::f64 :
+ case MVT::i64 :
+ case MVT::v8i8:
+ case MVT::v4i16:
+ case MVT::v2i32:
+ case MVT::v1i64:
+ case MVT::v2f32: return 64;
+ case MVT::f80 : return 80;
+ case MVT::f128:
+ case MVT::i128:
+ case MVT::v16i8:
+ case MVT::v8i16:
+ case MVT::v4i32:
+ case MVT::v2i64:
+ case MVT::v4f32:
+ case MVT::v2f64: return 128;
+ }
+ }
+
+ /// MVT::getVectorType - Returns the ValueType that represents a vector
+ /// NumElements in length, where each element is of type VT.
+ ///
+ static inline ValueType getVectorType(ValueType VT, unsigned NumElements) {
+ switch (VT) {
+ default:
+ break;
+ case MVT::i8:
+ if (NumElements == 8) return MVT::v8i8;
+ if (NumElements == 16) return MVT::v16i8;
+ break;
+ case MVT::i16:
+ if (NumElements == 4) return MVT::v4i16;
+ if (NumElements == 8) return MVT::v8i16;
+ break;
+ case MVT::i32:
+ if (NumElements == 2) return MVT::v2i32;
+ if (NumElements == 4) return MVT::v4i32;
+ break;
+ case MVT::i64:
+ if (NumElements == 1) return MVT::v1i64;
+ if (NumElements == 2) return MVT::v2i64;
+ break;
+ case MVT::f32:
+ if (NumElements == 2) return MVT::v2f32;
+ if (NumElements == 4) return MVT::v4f32;
+ break;
+ case MVT::f64:
+ if (NumElements == 2) return MVT::v2f64;
+ break;
+ }
+ ValueType Result = VT | ((NumElements + 1) << SimpleTypeBits);
+ assert(getVectorElementType(Result) == VT &&
+ "Bad vector element type!");
+ assert(getVectorNumElements(Result) == NumElements &&
+ "Bad vector length!");
+ return Result;
+ }
+
+ /// MVT::getIntVectorWithNumElements - Return any integer vector type that has
+ /// the specified number of elements.
+ static inline ValueType getIntVectorWithNumElements(unsigned NumElts) {
+ switch (NumElts) {
+ default: return getVectorType(i8, NumElts);
+ case 1: return v1i64;
+ case 2: return v2i32;
+ case 4: return v4i16;
+ case 8: return v8i8;
+ case 16: return v16i8;
+ }
+ }
+
+
+ /// MVT::getIntVTBitMask - Return an integer with 1's every place there are
+ /// bits in the specified integer value type.
+ static inline uint64_t getIntVTBitMask(ValueType VT) {
+ assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!");
+ return ~uint64_t(0UL) >> (64-getSizeInBits(VT));
+ }
+ /// MVT::getIntVTSignBit - Return an integer with a 1 in the position of the
+ /// sign bit for the specified integer value type.
+ static inline uint64_t getIntVTSignBit(ValueType VT) {
+ assert(isInteger(VT) && !isVector(VT) && "Only applies to int scalars!");
+ return uint64_t(1UL) << (getSizeInBits(VT)-1);
+ }
+
+ /// MVT::getValueTypeString - This function returns value type as a string,
+ /// e.g. "i32".
+ std::string getValueTypeString(ValueType VT);
+
+ /// MVT::getTypeForValueType - This method returns an LLVM type corresponding
+ /// to the specified ValueType. For integer types, this returns an unsigned
+ /// type. Note that this will abort for types that cannot be represented.
+ const Type *getTypeForValueType(ValueType VT);
+
+ /// MVT::getValueType - Return the value type corresponding to the specified
+ /// type. This returns all pointers as MVT::iPTR. If HandleUnknown is true,
+ /// unknown types are returned as Other, otherwise they are invalid.
+ ValueType getValueType(const Type *Ty, bool HandleUnknown = false);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/CodeGen/ValueTypes.td b/include/llvm/CodeGen/ValueTypes.td
new file mode 100644
index 0000000..557a02b
--- /dev/null
+++ b/include/llvm/CodeGen/ValueTypes.td
@@ -0,0 +1,52 @@
+//===- ValueTypes.td - ValueType definitions ---------------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Value types - These values correspond to the register types defined in the
+// ValueTypes.h file. If you update anything here, you must update it there as
+// well!
+//
+//===----------------------------------------------------------------------===//
+
+class ValueType<int size, int value> {
+ string Namespace = "MVT";
+ int Size = size;
+ int Value = value;
+}
+
+def OtherVT: ValueType<0 , 0>; // "Other" value
+def i1 : ValueType<1 , 1>; // One bit boolean value
+def i8 : ValueType<8 , 2>; // 8-bit integer value
+def i16 : ValueType<16 , 3>; // 16-bit integer value
+def i32 : ValueType<32 , 4>; // 32-bit integer value
+def i64 : ValueType<64 , 5>; // 64-bit integer value
+def i128 : ValueType<128, 6>; // 128-bit integer value
+def f32 : ValueType<32 , 7>; // 32-bit floating point value
+def f64 : ValueType<64 , 8>; // 64-bit floating point value
+def f80 : ValueType<80 , 9>; // 80-bit floating point value
+def f128 : ValueType<128, 10>; // 128-bit floating point value
+def FlagVT : ValueType<0 , 11>; // Condition code or machine flag
+def isVoid : ValueType<0 , 12>; // Produces no value
+def v8i8 : ValueType<64 , 13>; // 8 x i8 vector value
+def v4i16 : ValueType<64 , 14>; // 4 x i16 vector value
+def v2i32 : ValueType<64 , 15>; // 2 x i32 vector value
+def v1i64 : ValueType<64 , 16>; // 1 x i64 vector value
+
+def v16i8 : ValueType<128, 17>; // 16 x i8 vector value
+def v8i16 : ValueType<128, 18>; // 8 x i16 vector value
+def v4i32 : ValueType<128, 19>; // 4 x i32 vector value
+def v2i64 : ValueType<128, 20>; // 2 x i64 vector value
+def v2f32 : ValueType<64, 21>; // 2 x f32 vector value
+def v4f32 : ValueType<128, 22>; // 4 x f32 vector value
+def v2f64 : ValueType<128, 23>; // 2 x f64 vector value
+
+// Pseudo valuetype to represent "integer of any bit width"
+def iAny : ValueType<0 , 254>; // integer value of any bit width
+
+// Pseudo valuetype mapped to the current pointer size.
+def iPTR : ValueType<0 , 255>;
diff --git a/include/llvm/Config/alloca.h b/include/llvm/Config/alloca.h
new file mode 100644
index 0000000..10fa74d
--- /dev/null
+++ b/include/llvm/Config/alloca.h
@@ -0,0 +1,50 @@
+/*
+ * The LLVM Compiler Infrastructure
+ *
+ * This file was developed by the LLVM research group and is distributed under
+ * the University of Illinois Open Source License. See LICENSE.TXT for details.
+ *
+ ******************************************************************************
+ *
+ * Description:
+ * This header file includes the infamous alloc.h header file if the
+ * autoconf system has found it. It hides all of the autoconf details
+ * from the rest of the application source code.
+ */
+
+#ifndef _CONFIG_ALLOC_H
+#define _CONFIG_ALLOC_H
+
+#include "llvm/Config/config.h"
+
+/*
+ * This is a modified version of that suggested by the Autoconf manual.
+ * 1) The #pragma is indented so that pre-ANSI C compilers ignore it.
+ * 2) If alloca.h cannot be found, then try stdlib.h. Some platforms
+ * (notably FreeBSD) defined alloca() there.
+ */
+#ifdef _MSC_VER
+#include <malloc.h>
+#define alloca _alloca
+#elif defined(HAVE_ALLOCA_H)
+#include <alloca.h>
+#elif defined(__MINGW32__) && defined(HAVE_MALLOC_H)
+#include <malloc.h>
+#elif !defined(__GNUC__)
+# ifdef _AIX
+# pragma alloca
+# else
+# ifndef alloca
+ char * alloca ();
+# endif
+# endif
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# else
+# error "The function alloca() is required but not found!"
+# endif
+#endif
+
+#endif
+
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
new file mode 100644
index 0000000..80b443f
--- /dev/null
+++ b/include/llvm/Config/config.h.in
@@ -0,0 +1,564 @@
+/* include/llvm/Config/config.h.in. Generated from autoconf/configure.ac by autoheader. */
+
+/* Define if dlopen(0) will open the symbols of the program */
+#undef CAN_DLOPEN_SELF
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+ systems. This function is required for `alloca.c' support on those systems.
+ */
+#undef CRAY_STACKSEG_END
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if CBE is enabled for printf %a output */
+#undef ENABLE_CBE_PRINTF_A
+
+/* Define if position independent code is enabled */
+#undef ENABLE_PIC
+
+/* Define if threads enabled */
+#undef ENABLE_THREADS
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+ */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `argz_append' function. */
+#undef HAVE_ARGZ_APPEND
+
+/* Define to 1 if you have the `argz_create_sep' function. */
+#undef HAVE_ARGZ_CREATE_SEP
+
+/* Define to 1 if you have the <argz.h> header file. */
+#undef HAVE_ARGZ_H
+
+/* Define to 1 if you have the `argz_insert' function. */
+#undef HAVE_ARGZ_INSERT
+
+/* Define to 1 if you have the `argz_next' function. */
+#undef HAVE_ARGZ_NEXT
+
+/* Define to 1 if you have the `argz_stringify' function. */
+#undef HAVE_ARGZ_STRINGIFY
+
+/* Define to 1 if you have the <assert.h> header file. */
+#undef HAVE_ASSERT_H
+
+/* Define to 1 if you have the `backtrace' function. */
+#undef HAVE_BACKTRACE
+
+/* Define to 1 if you have the `bcopy' function. */
+#undef HAVE_BCOPY
+
+/* Does not have bi-directional iterator */
+#undef HAVE_BI_ITERATOR
+
+/* Define to 1 if you have the `ceilf' function. */
+#undef HAVE_CEILF
+
+/* Define to 1 if you have the `closedir' function. */
+#undef HAVE_CLOSEDIR
+
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define to 1 if you have the <dld.h> header file. */
+#undef HAVE_DLD_H
+
+/* Define to 1 if you have the `dlerror' function. */
+#undef HAVE_DLERROR
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if dlopen() is available on this platform. */
+#undef HAVE_DLOPEN
+
+/* Define to 1 if you have the <dl.h> header file. */
+#undef HAVE_DL_H
+
+/* Define if the dot program is available */
+#undef HAVE_DOT
+
+/* Define if the dotty program is available */
+#undef HAVE_DOTTY
+
+/* Define if you have the _dyld_func_lookup function. */
+#undef HAVE_DYLD
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if the system has the type `error_t'. */
+#undef HAVE_ERROR_T
+
+/* Define to 1 if you have the <execinfo.h> header file. */
+#undef HAVE_EXECINFO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_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
+
+/* Does not have forward iterator */
+#undef HAVE_FWD_ITERATOR
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the `getrlimit' function. */
+#undef HAVE_GETRLIMIT
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Does not have <hash_map> */
+#undef HAVE_GLOBAL_HASH_MAP
+
+/* Does not have hash_set in global namespace */
+#undef HAVE_GLOBAL_HASH_SET
+
+/* Does not have ext/hash_map */
+#undef HAVE_GNU_EXT_HASH_MAP
+
+/* Does not have hash_set in gnu namespace */
+#undef HAVE_GNU_EXT_HASH_SET
+
+/* Define if the Graphviz program is available */
+#undef HAVE_GRAPHVIZ
+
+/* Define if the gv program is available */
+#undef HAVE_GV
+
+/* Define to 1 if you have the `index' function. */
+#undef HAVE_INDEX
+
+/* Define to 1 if the system has the type `int64_t'. */
+#undef HAVE_INT64_T
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* 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 you have the libdl library or equivalent. */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `elf' library (-lelf). */
+#undef HAVE_LIBELF
+
+/* Define to 1 if you have the `imagehlp' library (-limagehlp). */
+#undef HAVE_LIBIMAGEHLP
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `psapi' library (-lpsapi). */
+#undef HAVE_LIBPSAPI
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `udis86' library (-ludis86). */
+#undef HAVE_LIBUDIS86
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define to 1 if you have the <link.h> header file. */
+#undef HAVE_LINK_H
+
+/* Define if you can use -Wl,-R. to pass -R. to the linker, in order to add
+ the current directory to the dynamic linker search path. */
+#undef HAVE_LINK_R
+
+/* Define to 1 if you have the `longjmp' function. */
+#undef HAVE_LONGJMP
+
+/* Define if lt_dlopen() is available on this platform */
+#undef HAVE_LT_DLOPEN
+
+/* Define to 1 if you have the <mach/mach.h> header file. */
+#undef HAVE_MACH_MACH_H
+
+/* Define to 1 if you have the <mach-o/dyld.h> header file. */
+#undef HAVE_MACH_O_DYLD_H
+
+/* Define if mallinfo() is available on this platform. */
+#undef HAVE_MALLINFO
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define to 1 if you have the <malloc/malloc.h> header file. */
+#undef HAVE_MALLOC_MALLOC_H
+
+/* Define to 1 if you have the `malloc_zone_statistics' function. */
+#undef HAVE_MALLOC_ZONE_STATISTICS
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mktemp' function. */
+#undef HAVE_MKTEMP
+
+/* Define to 1 if you have a working `mmap' system call. */
+#undef HAVE_MMAP
+
+/* Define if mmap() uses MAP_ANONYMOUS to map anonymous pages, or undefine if
+ it uses MAP_ANON */
+#undef HAVE_MMAP_ANONYMOUS
+
+/* Define if mmap() can map files into memory */
+#undef HAVE_MMAP_FILE
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* 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 `opendir' function. */
+#undef HAVE_OPENDIR
+
+/* Define to 1 if you have the `powf' function. */
+#undef HAVE_POWF
+
+/* Define if libtool can extract symbol lists from object files. */
+#undef HAVE_PRELOADED_SYMBOLS
+
+/* Define to have the %a format string */
+#undef HAVE_PRINTF_A
+
+/* Have pthread_mutex_lock */
+#undef HAVE_PTHREAD_MUTEX_LOCK
+
+/* Define to 1 if srand48/lrand48/drand48 exist in <stdlib.h> */
+#undef HAVE_RAND48
+
+/* Define to 1 if you have the `readdir' function. */
+#undef HAVE_READDIR
+
+/* Define to 1 if you have the `realpath' function. */
+#undef HAVE_REALPATH
+
+/* Define to 1 if you have the `rindex' function. */
+#undef HAVE_RINDEX
+
+/* 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
+
+/* Define to 1 if you have the `setjmp' function. */
+#undef HAVE_SETJMP
+
+/* Define to 1 if you have the <setjmp.h> header file. */
+#undef HAVE_SETJMP_H
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
+
+/* Define to 1 if you have the `siglongjmp' function. */
+#undef HAVE_SIGLONGJMP
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `sigsetjmp' function. */
+#undef HAVE_SIGSETJMP
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Does not have ext/hash_map> */
+#undef HAVE_STD_EXT_HASH_MAP
+
+/* Does not have hash_set in std namespace */
+#undef HAVE_STD_EXT_HASH_SET
+
+/* 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
+
+/* Does not have std namespace iterator */
+#undef HAVE_STD_ITERATOR
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcmp' function. */
+#undef HAVE_STRCMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the `strerror_r' function. */
+#undef HAVE_STRERROR_R
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strrchr' function. */
+#undef HAVE_STRRCHR
+
+/* Define to 1 if you have the `strtof' function. */
+#undef HAVE_STRTOF
+
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the `strtoq' function. */
+#undef HAVE_STRTOQ
+
+/* Define to 1 if you have the `sysconf' function. */
+#undef HAVE_SYSCONF
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/dl.h> header file. */
+#undef HAVE_SYS_DL_H
+
+/* Define to 1 if you have the <sys/mman.h> header file. */
+#undef HAVE_SYS_MMAN_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+ */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if the system has the type `uint64_t'. */
+#undef HAVE_UINT64_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <utime.h> header file. */
+#undef HAVE_UTIME_H
+
+/* Define to 1 if the system has the type `u_int64_t'. */
+#undef HAVE_U_INT64_T
+
+/* Define to 1 if you have the <windows.h> header file. */
+#undef HAVE_WINDOWS_H
+
+/* Installation directory for binary executables */
+#undef LLVM_BINDIR
+
+/* Time at which LLVM was configured */
+#undef LLVM_CONFIGTIME
+
+/* Installation directory for documentation */
+#undef LLVM_DATADIR
+
+/* Installation directory for config files */
+#undef LLVM_ETCDIR
+
+/* Installation directory for include files */
+#undef LLVM_INCLUDEDIR
+
+/* Installation directory for .info files */
+#undef LLVM_INFODIR
+
+/* Installation directory for libraries */
+#undef LLVM_LIBDIR
+
+/* Installation directory for man pages */
+#undef LLVM_MANDIR
+
+/* Define if this is Unixish platform */
+#undef LLVM_ON_UNIX
+
+/* Define if this is Win32ish platform */
+#undef LLVM_ON_WIN32
+
+/* Define to path to dot program if found or 'echo dot' otherwise */
+#undef LLVM_PATH_DOT
+
+/* Define to path to dotty program if found or 'echo dotty' otherwise */
+#undef LLVM_PATH_DOTTY
+
+/* Define to path to Graphviz program if found or 'echo Graphviz' otherwise */
+#undef LLVM_PATH_GRAPHVIZ
+
+/* Define to path to gv program if found or 'echo gv' otherwise */
+#undef LLVM_PATH_GV
+
+/* Installation prefix directory */
+#undef LLVM_PREFIX
+
+/* Define if the OS needs help to load dependent libraries for dlopen(). */
+#undef LTDL_DLOPEN_DEPLIBS
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#undef LTDL_OBJDIR
+
+/* Define to the name of the environment variable that determines the dynamic
+ library search path. */
+#undef LTDL_SHLIBPATH_VAR
+
+/* Define to the extension used for shared libraries, say, ".so". */
+#undef LTDL_SHLIB_EXT
+
+/* Define to the system default library search path. */
+#undef LTDL_SYSSEARCHPATH
+
+/* Define if /dev/zero should be used when mapping RWX memory, or undefine if
+ its not necessary */
+#undef NEED_DEV_ZERO_FOR_MMAP
+
+/* Define if dlsym() requires a leading underscore in symbol names. */
+#undef NEED_USCORE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#undef RETSIGTYPE
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at runtime.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Define if use udis86 library */
+#undef USE_UDIS86
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to a type to use for `error_t' if it is not otherwise available. */
+#undef error_t
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
diff --git a/include/llvm/Constant.h b/include/llvm/Constant.h
new file mode 100644
index 0000000..d925fdb
--- /dev/null
+++ b/include/llvm/Constant.h
@@ -0,0 +1,129 @@
+//===-- llvm/Constant.h - Constant class definition -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Constant class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CONSTANT_H
+#define LLVM_CONSTANT_H
+
+#include "llvm/User.h"
+
+namespace llvm {
+
+/// This is an important base class in LLVM. It provides the common facilities
+/// of all constant values in an LLVM program. A constant is a value that is
+/// immutable at runtime. Functions are constants because their address is
+/// immutable. Same with global variables.
+///
+/// All constants share the capabilities provided in this class. All constants
+/// can have a null value. They can have an operand list. Constants can be
+/// simple (integer and floating point values), complex (arrays and structures),
+/// or expression based (computations yielding a constant value composed of
+/// only certain operators and other constant values).
+///
+/// Note that Constants are immutable (once created they never change)
+/// and are fully shared by structural equivalence. This means that two
+/// structurally equivalent constants will always have the same address.
+/// Constant's are created on demand as needed and never deleted: thus clients
+/// don't have to worry about the lifetime of the objects.
+/// @brief LLVM Constant Representation
+class Constant : public User {
+ void operator=(const Constant &); // Do not implement
+ Constant(const Constant &); // Do not implement
+protected:
+ Constant(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps)
+ : User(Ty, vty, Ops, NumOps) {}
+
+ void destroyConstantImpl();
+public:
+ /// Static constructor to get a '0' constant of arbitrary type...
+ ///
+ static Constant *getNullValue(const Type *Ty);
+
+ /// Static constructor to get a '-1' constant. This supports integers and
+ /// vectors.
+ ///
+ static Constant *getAllOnesValue(const Type *Ty);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ virtual bool isNullValue() const = 0;
+
+ virtual void print(std::ostream &O) const;
+ void print(std::ostream *O) const { if (O) print(*O); }
+
+ /// canTrap - Return true if evaluation of this constant could trap. This is
+ /// true for things like constant expressions that could divide by zero.
+ bool canTrap() const;
+
+ /// ContaintsRelocations - Return true if the constant value contains
+ /// relocations which cannot be resolved at compile time.
+ bool ContainsRelocations() const;
+
+ // Specialize get/setOperand for Constant's as their operands are always
+ // constants as well.
+ Constant *getOperand(unsigned i) {
+ return static_cast<Constant*>(User::getOperand(i));
+ }
+ const Constant *getOperand(unsigned i) const {
+ return static_cast<const Constant*>(User::getOperand(i));
+ }
+ void setOperand(unsigned i, Constant *C) {
+ User::setOperand(i, C);
+ }
+
+ /// destroyConstant - Called if some element of this constant is no longer
+ /// valid. At this point only other constants may be on the use_list for this
+ /// constant. Any constants on our Use list must also be destroy'd. The
+ /// implementation must be sure to remove the constant from the list of
+ /// available cached constants. Implementations should call
+ /// destroyConstantImpl as the last thing they do, to destroy all users and
+ /// delete this.
+ virtual void destroyConstant() { assert(0 && "Not reached!"); }
+
+ //// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Constant *) { return true; }
+ static inline bool classof(const GlobalValue *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() >= ConstantFirstVal &&
+ V->getValueID() <= ConstantLastVal;
+ }
+
+ /// replaceUsesOfWithOnConstant - This method is a special form of
+ /// User::replaceUsesOfWith (which does not work on constants) that does work
+ /// on constants. Basically this method goes through the trouble of building
+ /// a new constant that is equivalent to the current one, with all uses of
+ /// From replaced with uses of To. After this construction is completed, all
+ /// of the users of 'this' are replaced to use the new constant, and then
+ /// 'this' is deleted. In general, you should not call this method, instead,
+ /// use Value::replaceAllUsesWith, which automatically dispatches to this
+ /// method as needed.
+ ///
+ virtual void replaceUsesOfWithOnConstant(Value *, Value *, Use *) {
+ // Provide a default implementation for constants (like integers) that
+ // cannot use any other values. This cannot be called at runtime, but needs
+ // to be here to avoid link errors.
+ assert(getNumOperands() == 0 && "replaceUsesOfWithOnConstant must be "
+ "implemented for all constants that have operands!");
+ assert(0 && "Constants that do not have operands cannot be using 'From'!");
+ }
+
+ /// getStringValue - Turn an LLVM constant pointer that eventually points to a
+ /// global into a string value. Return an empty string if we can't do it.
+ /// Parameter Chop determines if the result is chopped at the first null
+ /// terminator.
+ ///
+ std::string getStringValue(bool Chop = true, unsigned Offset = 0);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h
new file mode 100644
index 0000000..526f19c
--- /dev/null
+++ b/include/llvm/Constants.h
@@ -0,0 +1,713 @@
+//===-- llvm/Constants.h - Constant class subclass definitions --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file This file contains the declarations for the subclasses of Constant,
+/// which represent the different flavors of constant values that live in LLVM.
+/// Note that Constants are immutable (once created they never change) and are
+/// fully shared by structural equivalence. This means that two structurally
+/// equivalent constants will always have the same address. Constant's are
+/// created on demand as needed and never deleted: thus clients don't have to
+/// worry about the lifetime of the objects.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CONSTANTS_H
+#define LLVM_CONSTANTS_H
+
+#include "llvm/Constant.h"
+#include "llvm/Type.h"
+#include "llvm/ADT/APInt.h"
+
+namespace llvm {
+
+class ArrayType;
+class StructType;
+class PointerType;
+class VectorType;
+
+template<class ConstantClass, class TypeClass, class ValType>
+struct ConstantCreator;
+template<class ConstantClass, class TypeClass>
+struct ConvertConstantType;
+
+//===----------------------------------------------------------------------===//
+/// This is the shared class of boolean and integer constants. This class
+/// represents both boolean and integral constants.
+/// @brief Class for constant integers.
+class ConstantInt : public Constant {
+ static ConstantInt *TheTrueVal, *TheFalseVal;
+ ConstantInt(const ConstantInt &); // DO NOT IMPLEMENT
+ ConstantInt(const IntegerType *Ty, const APInt& V);
+ APInt Val;
+public:
+ /// Return the constant as an APInt value reference. This allows clients to
+ /// obtain a copy of the value, with all its precision in tact.
+ /// @brief Return the constant's value.
+ inline const APInt& getValue() const {
+ return Val;
+ }
+
+ /// getBitWidth - Return the bitwidth of this constant.
+ unsigned getBitWidth() const { return Val.getBitWidth(); }
+
+ /// Return the constant as a 64-bit unsigned integer value after it
+ /// has been zero extended as appropriate for the type of this constant. Note
+ /// that this method can assert if the value does not fit in 64 bits.
+ /// @deprecated
+ /// @brief Return the zero extended value.
+ inline uint64_t getZExtValue() const {
+ return Val.getZExtValue();
+ }
+
+ /// Return the constant as a 64-bit integer value after it has been sign
+ /// sign extended as appropriate for the type of this constant. Note that
+ /// this method can assert if the value does not fit in 64 bits.
+ /// @deprecated
+ /// @brief Return the sign extended value.
+ inline int64_t getSExtValue() const {
+ return Val.getSExtValue();
+ }
+
+ /// A helper method that can be used to determine if the constant contained
+ /// within is equal to a constant. This only works for very small values,
+ /// because this is all that can be represented with all types.
+ /// @brief Determine if this constant's value is same as an unsigned char.
+ bool equalsInt(uint64_t V) const {
+ return Val == V;
+ }
+
+ /// getTrue/getFalse - Return the singleton true/false values.
+ static inline ConstantInt *getTrue() {
+ if (TheTrueVal) return TheTrueVal;
+ return CreateTrueFalseVals(true);
+ }
+ static inline ConstantInt *getFalse() {
+ if (TheFalseVal) return TheFalseVal;
+ return CreateTrueFalseVals(false);
+ }
+
+ /// Return a ConstantInt with the specified value for the specified type. The
+ /// value V will be canonicalized to a an unsigned APInt. Accessing it with
+ /// either getSExtValue() or getZExtValue() will yield a correctly sized and
+ /// signed value for the type Ty.
+ /// @brief Get a ConstantInt for a specific value.
+ static ConstantInt *get(const Type *Ty, uint64_t V, bool isSigned = false);
+
+ /// Return a ConstantInt with the specified value and an implied Type. The
+ /// type is the integer type that corresponds to the bit width of the value.
+ static ConstantInt *get(const APInt &V);
+
+ /// getType - Specialize the getType() method to always return an IntegerType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline const IntegerType *getType() const {
+ return reinterpret_cast<const IntegerType*>(Value::getType());
+ }
+
+ /// This static method returns true if the type Ty is big enough to
+ /// represent the value V. This can be used to avoid having the get method
+ /// assert when V is larger than Ty can represent. Note that there are two
+ /// versions of this method, one for unsigned and one for signed integers.
+ /// Although ConstantInt canonicalizes everything to an unsigned integer,
+ /// the signed version avoids callers having to convert a signed quantity
+ /// to the appropriate unsigned type before calling the method.
+ /// @returns true if V is a valid value for type Ty
+ /// @brief Determine if the value is in range for the given type.
+ static bool isValueValidForType(const Type *Ty, uint64_t V);
+ static bool isValueValidForType(const Type *Ty, int64_t V);
+
+ /// This function will return true iff this constant represents the "null"
+ /// value that would be returned by the getNullValue method.
+ /// @returns true if this is the null integer value.
+ /// @brief Determine if the value is null.
+ virtual bool isNullValue() const {
+ return Val == 0;
+ }
+
+ /// This is just a convenience method to make client code smaller for a
+ /// common code. It also correctly performs the comparison without the
+ /// potential for an assertion from getZExtValue().
+ bool isZero() const {
+ return Val == 0;
+ }
+
+ /// This is just a convenience method to make client code smaller for a
+ /// common case. It also correctly performs the comparison without the
+ /// potential for an assertion from getZExtValue().
+ /// @brief Determine if the value is one.
+ bool isOne() const {
+ return Val == 1;
+ }
+
+ /// This function will return true iff every bit in this constant is set
+ /// to true.
+ /// @returns true iff this constant's bits are all set to true.
+ /// @brief Determine if the value is all ones.
+ bool isAllOnesValue() const {
+ return Val.isAllOnesValue();
+ }
+
+ /// This function will return true iff this constant represents the largest
+ /// value that may be represented by the constant's type.
+ /// @returns true iff this is the largest value that may be represented
+ /// by this type.
+ /// @brief Determine if the value is maximal.
+ bool isMaxValue(bool isSigned) const {
+ if (isSigned)
+ return Val.isMaxSignedValue();
+ else
+ return Val.isMaxValue();
+ }
+
+ /// This function will return true iff this constant represents the smallest
+ /// value that may be represented by this constant's type.
+ /// @returns true if this is the smallest value that may be represented by
+ /// this type.
+ /// @brief Determine if the value is minimal.
+ bool isMinValue(bool isSigned) const {
+ if (isSigned)
+ return Val.isMinSignedValue();
+ else
+ return Val.isMinValue();
+ }
+
+ /// This function will return true iff this constant represents a value with
+ /// active bits bigger than 64 bits or a value greater than the given uint64_t
+ /// value.
+ /// @returns true iff this constant is greater or equal to the given number.
+ /// @brief Determine if the value is greater or equal to the given number.
+ bool uge(uint64_t Num) {
+ return Val.getActiveBits() > 64 || Val.getZExtValue() >= Num;
+ }
+
+ /// @returns the 64-bit value of this constant if its active bits number is
+ /// not greater than 64, otherwise, just return the given uint64_t number.
+ /// @brief Get the constant's value if possible.
+ uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
+ return Val.getLimitedValue(Limit);
+ }
+
+ /// @returns the value for an integer constant of the given type that has all
+ /// its bits set to true.
+ /// @brief Get the all ones value
+ static ConstantInt *getAllOnesValue(const Type *Ty);
+
+ /// @brief Methods to support type inquiry through isa, cast, and dyn_cast.
+ static inline bool classof(const ConstantInt *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantIntVal;
+ }
+ static void ResetTrueFalse() { TheTrueVal = TheFalseVal = 0; }
+private:
+ static ConstantInt *CreateTrueFalseVals(bool WhichOne);
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantFP - Floating Point Values [float, double]
+///
+class ConstantFP : public Constant {
+ double Val;
+ ConstantFP(const ConstantFP &); // DO NOT IMPLEMENT
+protected:
+ ConstantFP(const Type *Ty, double V);
+public:
+ /// get() - Static factory methods - Return objects of the specified value
+ static ConstantFP *get(const Type *Ty, double V);
+
+ /// isValueValidForType - return true if Ty is big enough to represent V.
+ static bool isValueValidForType(const Type *Ty, double V);
+ inline double getValue() const { return Val; }
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. Don't depend on == for doubles to tell us it's zero, it
+ /// considers -0.0 to be null as well as 0.0. :(
+ virtual bool isNullValue() const;
+
+ /// isExactlyValue - 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.
+ bool isExactlyValue(double V) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantFP *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantFPVal;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantAggregateZero - All zero aggregate value
+///
+class ConstantAggregateZero : public Constant {
+ friend struct ConstantCreator<ConstantAggregateZero, Type, char>;
+ ConstantAggregateZero(const ConstantAggregateZero &); // DO NOT IMPLEMENT
+protected:
+ explicit ConstantAggregateZero(const Type *Ty)
+ : Constant(Ty, ConstantAggregateZeroVal, 0, 0) {}
+public:
+ /// get() - static factory method for creating a null aggregate. It is
+ /// illegal to call this method with a non-aggregate type.
+ static Constant *get(const Type *Ty);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ virtual bool isNullValue() const { return true; }
+
+ virtual void destroyConstant();
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ ///
+ static bool classof(const ConstantAggregateZero *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantAggregateZeroVal;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ConstantArray - Constant Array Declarations
+///
+class ConstantArray : public Constant {
+ friend struct ConstantCreator<ConstantArray, ArrayType,
+ std::vector<Constant*> >;
+ ConstantArray(const ConstantArray &); // DO NOT IMPLEMENT
+protected:
+ ConstantArray(const ArrayType *T, const std::vector<Constant*> &Val);
+ ~ConstantArray();
+public:
+ /// get() - Static factory methods - Return objects of the specified value
+ static Constant *get(const ArrayType *T, const std::vector<Constant*> &);
+ static Constant *get(const ArrayType *T,
+ Constant*const*Vals, unsigned NumVals) {
+ // FIXME: make this the primary ctor method.
+ return get(T, std::vector<Constant*>(Vals, Vals+NumVals));
+ }
+
+ /// This method constructs a ConstantArray and initializes it with a text
+ /// string. The default behavior (AddNull==true) causes a null terminator to
+ /// be placed at the end of the array. This effectively increases the length
+ /// of the array by one (you've been warned). However, in some situations
+ /// this is not desired so if AddNull==false then the string is copied without
+ /// null termination.
+ static Constant *get(const std::string &Initializer, bool AddNull = true);
+
+ /// getType - Specialize the getType() method to always return an ArrayType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline const ArrayType *getType() const {
+ return reinterpret_cast<const ArrayType*>(Value::getType());
+ }
+
+ /// isString - This method returns true if the array is an array of sbyte or
+ /// ubyte, and if the elements of the array are all ConstantInt's.
+ bool isString() const;
+
+ /// isCString - This method returns true if the array is a string (see
+ /// isString) and it ends in a null byte \0 and does not contains any other
+ /// null bytes except its terminator.
+ bool isCString() const;
+
+ /// getAsString - If this array is isString(), then this method converts the
+ /// array to an std::string and returns it. Otherwise, it asserts out.
+ ///
+ std::string getAsString() const;
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. This always returns false because zero arrays are always
+ /// created as ConstantAggregateZero objects.
+ virtual bool isNullValue() const { return false; }
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantArray *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantArrayVal;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// ConstantStruct - Constant Struct Declarations
+//
+class ConstantStruct : public Constant {
+ friend struct ConstantCreator<ConstantStruct, StructType,
+ std::vector<Constant*> >;
+ ConstantStruct(const ConstantStruct &); // DO NOT IMPLEMENT
+protected:
+ ConstantStruct(const StructType *T, const std::vector<Constant*> &Val);
+ ~ConstantStruct();
+public:
+ /// get() - Static factory methods - Return objects of the specified value
+ ///
+ static Constant *get(const StructType *T, const std::vector<Constant*> &V);
+ static Constant *get(const std::vector<Constant*> &V, bool Packed = false);
+ static Constant *get(Constant*const* Vals, unsigned NumVals,
+ bool Packed = false) {
+ // FIXME: make this the primary ctor method.
+ return get(std::vector<Constant*>(Vals, Vals+NumVals), Packed);
+ }
+
+ /// getType() specialization - Reduce amount of casting...
+ ///
+ inline const StructType *getType() const {
+ return reinterpret_cast<const StructType*>(Value::getType());
+ }
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. This always returns false because zero structs are always
+ /// created as ConstantAggregateZero objects.
+ virtual bool isNullValue() const {
+ return false;
+ }
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantStruct *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantStructVal;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantVector - Constant Vector Declarations
+///
+class ConstantVector : public Constant {
+ friend struct ConstantCreator<ConstantVector, VectorType,
+ std::vector<Constant*> >;
+ ConstantVector(const ConstantVector &); // DO NOT IMPLEMENT
+protected:
+ ConstantVector(const VectorType *T, const std::vector<Constant*> &Val);
+ ~ConstantVector();
+public:
+ /// get() - Static factory methods - Return objects of the specified value
+ static Constant *get(const VectorType *T, const std::vector<Constant*> &);
+ static Constant *get(const std::vector<Constant*> &V);
+ static Constant *get(Constant*const* Vals, unsigned NumVals) {
+ // FIXME: make this the primary ctor method.
+ return get(std::vector<Constant*>(Vals, Vals+NumVals));
+ }
+
+ /// getType - Specialize the getType() method to always return a VectorType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline const VectorType *getType() const {
+ return reinterpret_cast<const VectorType*>(Value::getType());
+ }
+
+ /// @returns the value for a vector integer constant of the given type that
+ /// has all its bits set to true.
+ /// @brief Get the all ones value
+ static ConstantVector *getAllOnesValue(const VectorType *Ty);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue. This always returns false because zero vectors are always
+ /// created as ConstantAggregateZero objects.
+ virtual bool isNullValue() const { return false; }
+
+ /// This function will return true iff every element in this vector constant
+ /// is set to all ones.
+ /// @returns true iff this constant's emements are all set to all ones.
+ /// @brief Determine if the value is all ones.
+ bool isAllOnesValue() const;
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantVector *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantVectorVal;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// ConstantPointerNull - a constant pointer value that points to null
+///
+class ConstantPointerNull : public Constant {
+ friend struct ConstantCreator<ConstantPointerNull, PointerType, char>;
+ ConstantPointerNull(const ConstantPointerNull &); // DO NOT IMPLEMENT
+protected:
+ explicit ConstantPointerNull(const PointerType *T)
+ : Constant(reinterpret_cast<const Type*>(T),
+ Value::ConstantPointerNullVal, 0, 0) {}
+
+public:
+
+ /// get() - Static factory methods - Return objects of the specified value
+ static ConstantPointerNull *get(const PointerType *T);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ virtual bool isNullValue() const { return true; }
+
+ virtual void destroyConstant();
+
+ /// getType - Specialize the getType() method to always return an PointerType,
+ /// which reduces the amount of casting needed in parts of the compiler.
+ ///
+ inline const PointerType *getType() const {
+ return reinterpret_cast<const PointerType*>(Value::getType());
+ }
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantPointerNull *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == ConstantPointerNullVal;
+ }
+};
+
+
+/// ConstantExpr - a constant value that is initialized with an expression using
+/// other constant values.
+///
+/// This class uses the standard Instruction opcodes to define the various
+/// constant expressions. The Opcode field for the ConstantExpr class is
+/// maintained in the Value::SubclassData field.
+class ConstantExpr : public Constant {
+ friend struct ConstantCreator<ConstantExpr,Type,
+ std::pair<unsigned, std::vector<Constant*> > >;
+ friend struct ConvertConstantType<ConstantExpr, Type>;
+
+protected:
+ ConstantExpr(const Type *Ty, unsigned Opcode, Use *Ops, unsigned NumOps)
+ : Constant(Ty, ConstantExprVal, Ops, NumOps) {
+ // Operation type (an Instruction opcode) is stored as the SubclassData.
+ SubclassData = Opcode;
+ }
+
+ // These private methods are used by the type resolution code to create
+ // ConstantExprs in intermediate forms.
+ static Constant *getTy(const Type *Ty, unsigned Opcode,
+ Constant *C1, Constant *C2);
+ static Constant *getCompareTy(unsigned short pred, Constant *C1,
+ Constant *C2);
+ static Constant *getSelectTy(const Type *Ty,
+ Constant *C1, Constant *C2, Constant *C3);
+ static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
+ Value* const *Idxs, unsigned NumIdxs);
+ static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
+ Constant *Idx);
+ static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
+ Constant *Elt, Constant *Idx);
+ static Constant *getShuffleVectorTy(const Type *Ty, Constant *V1,
+ Constant *V2, Constant *Mask);
+
+public:
+ // Static methods to construct a ConstantExpr of different kinds. Note that
+ // these methods may return a object that is not an instance of the
+ // ConstantExpr class, because they will attempt to fold the constant
+ // expression into something simpler if possible.
+
+ /// Cast constant expr
+ ///
+ static Constant *getTrunc (Constant *C, const Type *Ty);
+ static Constant *getSExt (Constant *C, const Type *Ty);
+ static Constant *getZExt (Constant *C, const Type *Ty);
+ static Constant *getFPTrunc (Constant *C, const Type *Ty);
+ static Constant *getFPExtend(Constant *C, const Type *Ty);
+ static Constant *getUIToFP (Constant *C, const Type *Ty);
+ static Constant *getSIToFP (Constant *C, const Type *Ty);
+ static Constant *getFPToUI (Constant *C, const Type *Ty);
+ static Constant *getFPToSI (Constant *C, const Type *Ty);
+ static Constant *getPtrToInt(Constant *C, const Type *Ty);
+ static Constant *getIntToPtr(Constant *C, const Type *Ty);
+ static Constant *getBitCast (Constant *C, const Type *Ty);
+
+ // @brief Convenience function for getting one of the casting operations
+ // using a CastOps opcode.
+ static Constant *getCast(
+ unsigned ops, ///< The opcode for the conversion
+ Constant *C, ///< The constant to be converted
+ const Type *Ty ///< The type to which the constant is converted
+ );
+
+ // @brief Create a ZExt or BitCast cast constant expression
+ static Constant *getZExtOrBitCast(
+ Constant *C, ///< The constant to zext or bitcast
+ const Type *Ty ///< The type to zext or bitcast C to
+ );
+
+ // @brief Create a SExt or BitCast cast constant expression
+ static Constant *getSExtOrBitCast(
+ Constant *C, ///< The constant to sext or bitcast
+ const Type *Ty ///< The type to sext or bitcast C to
+ );
+
+ // @brief Create a Trunc or BitCast cast constant expression
+ static Constant *getTruncOrBitCast(
+ Constant *C, ///< The constant to trunc or bitcast
+ const Type *Ty ///< The type to trunc or bitcast C to
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast constant expression
+ static Constant *getPointerCast(
+ Constant *C, ///< The pointer value to be casted (operand 0)
+ const Type *Ty ///< The type to which cast should be made
+ );
+
+ /// @brief Create a ZExt, Bitcast or Trunc for integer -> integer casts
+ static Constant *getIntegerCast(
+ Constant *C, ///< The integer constant to be casted
+ const Type *Ty, ///< The integer type to cast to
+ bool isSigned ///< Whether C should be treated as signed or not
+ );
+
+ /// @brief Create a FPExt, Bitcast or FPTrunc for fp -> fp casts
+ static Constant *getFPCast(
+ Constant *C, ///< The integer constant to be casted
+ const Type *Ty ///< The integer type to cast to
+ );
+
+ /// @brief Return true if this is a convert constant expression
+ bool isCast() const;
+
+ /// @brief Return true if this is a compare constant expression
+ bool isCompare() const;
+
+ /// Select constant expr
+ ///
+ static Constant *getSelect(Constant *C, Constant *V1, Constant *V2) {
+ return getSelectTy(V1->getType(), C, V1, V2);
+ }
+
+ /// getSizeOf constant expr - computes the size of a type in a target
+ /// independent way (Note: the return type is a ULong).
+ ///
+ static Constant *getSizeOf(const Type *Ty);
+
+ /// ConstantExpr::get - Return a binary or shift operator constant expression,
+ /// folding if possible.
+ ///
+ static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
+
+ /// @brief Return an ICmp or FCmp comparison operator constant expression.
+ static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
+
+ /// ConstantExpr::get* - Return some common constants without having to
+ /// specify the full Instruction::OPCODE identifier.
+ ///
+ static Constant *getNeg(Constant *C);
+ static Constant *getNot(Constant *C);
+ static Constant *getAdd(Constant *C1, Constant *C2);
+ static Constant *getSub(Constant *C1, Constant *C2);
+ static Constant *getMul(Constant *C1, Constant *C2);
+ static Constant *getUDiv(Constant *C1, Constant *C2);
+ static Constant *getSDiv(Constant *C1, Constant *C2);
+ static Constant *getFDiv(Constant *C1, Constant *C2);
+ static Constant *getURem(Constant *C1, Constant *C2); // unsigned rem
+ static Constant *getSRem(Constant *C1, Constant *C2); // signed rem
+ static Constant *getFRem(Constant *C1, Constant *C2);
+ static Constant *getAnd(Constant *C1, Constant *C2);
+ static Constant *getOr(Constant *C1, Constant *C2);
+ static Constant *getXor(Constant *C1, Constant *C2);
+ static Constant* getICmp(unsigned short pred, Constant* LHS, Constant* RHS);
+ static Constant* getFCmp(unsigned short pred, Constant* LHS, Constant* RHS);
+ static Constant *getShl(Constant *C1, Constant *C2);
+ static Constant *getLShr(Constant *C1, Constant *C2);
+ static Constant *getAShr(Constant *C1, Constant *C2);
+
+ /// Getelementptr form. std::vector<Value*> is only accepted for convenience:
+ /// all elements must be Constant's.
+ ///
+ static Constant *getGetElementPtr(Constant *C,
+ Constant* const *IdxList, unsigned NumIdx);
+ static Constant *getGetElementPtr(Constant *C,
+ Value* const *IdxList, unsigned NumIdx);
+
+ static Constant *getExtractElement(Constant *Vec, Constant *Idx);
+ static Constant *getInsertElement(Constant *Vec, Constant *Elt,Constant *Idx);
+ static Constant *getShuffleVector(Constant *V1, Constant *V2, Constant *Mask);
+
+ /// Floating point negation must be implemented with f(x) = -0.0 - x. This
+ /// method returns the negative zero constant for floating point or vector
+ /// floating point types; for all other types, it returns the null value.
+ static Constant *getZeroValueForNegationExpr(const Type *Ty);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ virtual bool isNullValue() const { return false; }
+
+ /// getOpcode - Return the opcode at the root of this constant expression
+ unsigned getOpcode() const { return SubclassData; }
+
+ /// getPredicate - Return the ICMP or FCMP predicate value. Assert if this is
+ /// not an ICMP or FCMP constant expression.
+ unsigned getPredicate() const;
+
+ /// getOpcodeName - Return a string representation for an opcode.
+ const char *getOpcodeName() const;
+
+ /// getWithOperandReplaced - Return a constant expression identical to this
+ /// one, but with the specified operand set to the specified value.
+ Constant *getWithOperandReplaced(unsigned OpNo, Constant *Op) const;
+
+ /// getWithOperands - This returns the current constant expression with the
+ /// operands replaced with the specified values. The specified operands must
+ /// match count and type with the existing ones.
+ Constant *getWithOperands(const std::vector<Constant*> &Ops) const;
+
+ virtual void destroyConstant();
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ /// Override methods to provide more type information...
+ inline Constant *getOperand(unsigned i) {
+ return cast<Constant>(User::getOperand(i));
+ }
+ inline Constant *getOperand(unsigned i) const {
+ return const_cast<Constant*>(cast<Constant>(User::getOperand(i)));
+ }
+
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ConstantExpr *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == ConstantExprVal;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+/// UndefValue - 'undef' values are things that do not have specified contents.
+/// These are used for a variety of purposes, including global variable
+/// initializers and operands to instructions. 'undef' values can occur with
+/// any type.
+///
+class UndefValue : public Constant {
+ friend struct ConstantCreator<UndefValue, Type, char>;
+ UndefValue(const UndefValue &); // DO NOT IMPLEMENT
+protected:
+ explicit UndefValue(const Type *T) : Constant(T, UndefValueVal, 0, 0) {}
+public:
+ /// get() - Static factory methods - Return an 'undef' object of the specified
+ /// type.
+ ///
+ static UndefValue *get(const Type *T);
+
+ /// isNullValue - Return true if this is the value that would be returned by
+ /// getNullValue.
+ virtual bool isNullValue() const { return false; }
+
+ virtual void destroyConstant();
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UndefValue *) { return true; }
+ static bool classof(const Value *V) {
+ return V->getValueID() == UndefValueVal;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Debugger/Debugger.h b/include/llvm/Debugger/Debugger.h
new file mode 100644
index 0000000..e708bc0
--- /dev/null
+++ b/include/llvm/Debugger/Debugger.h
@@ -0,0 +1,173 @@
+//===- Debugger.h - LLVM debugger library interface -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LLVM source-level debugger library interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_DEBUGGER_H
+#define LLVM_DEBUGGER_DEBUGGER_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+ class Module;
+ class InferiorProcess;
+
+ /// Debugger class - This class implements the LLVM source-level debugger.
+ /// This allows clients to handle the user IO processing without having to
+ /// worry about how the debugger itself works.
+ ///
+ class Debugger {
+ // State the debugger needs when starting and stopping the program.
+ std::vector<std::string> ProgramArguments;
+
+ // The environment to run the program with. This should eventually be
+ // changed to vector of strings when we allow the user to edit the
+ // environment.
+ const char * const *Environment;
+
+ // Program - The currently loaded program, or null if none is loaded.
+ Module *Program;
+
+ // Process - The currently executing inferior process.
+ InferiorProcess *Process;
+
+ Debugger(const Debugger &); // DO NOT IMPLEMENT
+ void operator=(const Debugger &); // DO NOT IMPLEMENT
+ public:
+ Debugger();
+ ~Debugger();
+
+ //===------------------------------------------------------------------===//
+ // Methods for manipulating and inspecting the execution environment.
+ //
+
+ /// initializeEnvironment - Specify the environment the program should run
+ /// with. This is used to initialize the environment of the program to the
+ /// environment of the debugger.
+ void initializeEnvironment(const char *const *envp) {
+ Environment = envp;
+ }
+
+ /// setWorkingDirectory - Specify the working directory for the program to
+ /// be started from.
+ void setWorkingDirectory(const std::string &Dir) {
+ // FIXME: implement
+ }
+
+ template<typename It>
+ void setProgramArguments(It I, It E) {
+ ProgramArguments.assign(I, E);
+ }
+ unsigned getNumProgramArguments() const { return ProgramArguments.size(); }
+ const std::string &getProgramArgument(unsigned i) const {
+ return ProgramArguments[i];
+ }
+
+
+ //===------------------------------------------------------------------===//
+ // Methods for manipulating and inspecting the program currently loaded.
+ //
+
+ /// isProgramLoaded - Return true if there is a program currently loaded.
+ ///
+ bool isProgramLoaded() const { return Program != 0; }
+
+ /// getProgram - Return the LLVM module corresponding to the program.
+ ///
+ Module *getProgram() const { return Program; }
+
+ /// getProgramPath - Get the path of the currently loaded program, or an
+ /// empty string if none is loaded.
+ std::string getProgramPath() const;
+
+ /// loadProgram - If a program is currently loaded, unload it. Then search
+ /// the PATH for the specified program, loading it when found. If the
+ /// specified program cannot be found, an exception is thrown to indicate
+ /// the error.
+ void loadProgram(const std::string &Path);
+
+ /// unloadProgram - If a program is running, kill it, then unload all traces
+ /// of the current program. If no program is loaded, this method silently
+ /// succeeds.
+ void unloadProgram();
+
+ //===------------------------------------------------------------------===//
+ // Methods for manipulating and inspecting the program currently running.
+ //
+ // If the program is running, and the debugger is active, then we know that
+ // the program has stopped. This being the case, we can inspect the
+ // program, ask it for its source location, set breakpoints, etc.
+ //
+
+ /// isProgramRunning - Return true if a program is loaded and has a
+ /// currently active instance.
+ bool isProgramRunning() const { return Process != 0; }
+
+ /// getRunningProcess - If there is no program running, throw an exception.
+ /// Otherwise return the running process so that it can be inspected by the
+ /// debugger.
+ const InferiorProcess &getRunningProcess() const {
+ if (Process == 0) throw "No process running.";
+ return *Process;
+ }
+
+ /// createProgram - Create an instance of the currently loaded program,
+ /// killing off any existing one. This creates the program and stops it at
+ /// the first possible moment. If there is no program loaded or if there is
+ /// a problem starting the program, this method throws an exception.
+ void createProgram();
+
+ /// killProgram - If the program is currently executing, kill off the
+ /// process and free up any state related to the currently running program.
+ /// If there is no program currently running, this just silently succeeds.
+ /// If something horrible happens when killing the program, an exception
+ /// gets thrown.
+ void killProgram();
+
+
+ //===------------------------------------------------------------------===//
+ // Methods for continuing execution. These methods continue the execution
+ // of the program by some amount. If the program is successfully stopped,
+ // execution returns, otherwise an exception is thrown.
+ //
+ // NOTE: These methods should always be used in preference to directly
+ // accessing the Dbg object, because these will delete the Process object if
+ // the process unexpectedly dies.
+ //
+
+ /// stepProgram - Implement the 'step' command, continuing execution until
+ /// the next possible stop point.
+ void stepProgram();
+
+ /// nextProgram - Implement the 'next' command, continuing execution until
+ /// the next possible stop point that is in the current function.
+ void nextProgram();
+
+ /// finishProgram - Implement the 'finish' command, continuing execution
+ /// until the specified frame ID returns.
+ void finishProgram(void *Frame);
+
+ /// contProgram - Implement the 'cont' command, continuing execution until
+ /// the next breakpoint is encountered.
+ void contProgram();
+ };
+
+ class NonErrorException {
+ std::string Message;
+ public:
+ NonErrorException(const std::string &M) : Message(M) {}
+ const std::string &getMessage() const { return Message; }
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Debugger/InferiorProcess.h b/include/llvm/Debugger/InferiorProcess.h
new file mode 100644
index 0000000..980e5cf
--- /dev/null
+++ b/include/llvm/Debugger/InferiorProcess.h
@@ -0,0 +1,138 @@
+//===- InferiorProcess.h - Represent the program being debugged -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the InferiorProcess class, which is used to represent,
+// inspect, and manipulate a process under the control of the LLVM debugger.
+//
+// This is an abstract class which should allow various different types of
+// implementations. Initially we implement a unix specific debugger backend
+// that does not require code generator support, but we could eventually use
+// code generator support with ptrace, support windows based targets, supported
+// remote targets, etc.
+//
+// If the inferior process unexpectedly dies, an attempt to communicate with it
+// will cause an InferiorProcessDead exception to be thrown, indicating the exit
+// code of the process. When this occurs, no methods on the InferiorProcess
+// class should be called except for the destructor.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_INFERIORPROCESS_H
+#define LLVM_DEBUGGER_INFERIORPROCESS_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+ class Module;
+ class GlobalVariable;
+
+ /// InferiorProcessDead exception - This class is thrown by methods that
+ /// communicate with the interior process if the process unexpectedly exits or
+ /// dies. The instance variable indicates what the exit code of the process
+ /// was, or -1 if unknown.
+ class InferiorProcessDead {
+ int ExitCode;
+ public:
+ InferiorProcessDead(int EC) : ExitCode(EC) {}
+ int getExitCode() const { return ExitCode; }
+ };
+
+ /// InferiorProcess class - This class represents the process being debugged
+ /// by the debugger. Objects of this class should not be stack allocated,
+ /// because the destructor can throw exceptions.
+ ///
+ class InferiorProcess {
+ Module *M;
+ protected:
+ InferiorProcess(Module *m) : M(m) {}
+ public:
+ /// create - Create an inferior process of the specified module, and
+ /// stop it at the first opportunity. If there is a problem starting the
+ /// program (for example, it has no main), throw an exception.
+ static InferiorProcess *create(Module *M,
+ const std::vector<std::string> &Arguments,
+ const char * const *envp);
+
+ // InferiorProcess destructor - Kill the current process. If something
+ // terrible happens, we throw an exception from the destructor.
+ virtual ~InferiorProcess() {}
+
+ //===------------------------------------------------------------------===//
+ // Status methods - These methods return information about the currently
+ // stopped process.
+ //
+
+ /// getStatus - Return a status message that is specific to the current type
+ /// of inferior process that is created. This can return things like the
+ /// PID of the inferior or other potentially interesting things.
+ virtual std::string getStatus() const {
+ return "";
+ }
+
+ //===------------------------------------------------------------------===//
+ // Methods for inspecting the call stack.
+ //
+
+ /// getPreviousFrame - Given the descriptor for the current stack frame,
+ /// return the descriptor for the caller frame. This returns null when it
+ /// runs out of frames. If Frame is null, the initial frame should be
+ /// returned.
+ virtual void *getPreviousFrame(void *Frame) const = 0;
+
+ /// getSubprogramDesc - Return the subprogram descriptor for the current
+ /// stack frame.
+ virtual const GlobalVariable *getSubprogramDesc(void *Frame) const = 0;
+
+ /// getFrameLocation - This method returns the source location where each
+ /// stack frame is stopped.
+ virtual void getFrameLocation(void *Frame, unsigned &LineNo,
+ unsigned &ColNo,
+ const GlobalVariable *&SourceDesc) const = 0;
+
+ //===------------------------------------------------------------------===//
+ // Methods for manipulating breakpoints.
+ //
+
+ /// addBreakpoint - This method adds a breakpoint at the specified line,
+ /// column, and source file, and returns a unique identifier for it.
+ ///
+ /// It is up to the debugger to determine whether or not there is actually a
+ /// stop-point that corresponds with the specified location.
+ virtual unsigned addBreakpoint(unsigned LineNo, unsigned ColNo,
+ const GlobalVariable *SourceDesc) = 0;
+
+ /// removeBreakpoint - This deletes the breakpoint with the specified ID
+ /// number.
+ virtual void removeBreakpoint(unsigned ID) = 0;
+
+
+ //===------------------------------------------------------------------===//
+ // Execution methods - These methods cause the program to continue execution
+ // by some amount. If the program successfully stops, this returns.
+ // Otherwise, if the program unexpectedly terminates, an InferiorProcessDead
+ // exception is thrown.
+ //
+
+ /// stepProgram - Implement the 'step' command, continuing execution until
+ /// the next possible stop point.
+ virtual void stepProgram() = 0;
+
+ /// finishProgram - Implement the 'finish' command, continuing execution
+ /// until the current function returns.
+ virtual void finishProgram(void *Frame) = 0;
+
+ /// contProgram - Implement the 'cont' command, continuing execution until
+ /// a breakpoint is encountered.
+ virtual void contProgram() = 0;
+ };
+} // end namespace llvm
+
+#endif
+
diff --git a/include/llvm/Debugger/ProgramInfo.h b/include/llvm/Debugger/ProgramInfo.h
new file mode 100644
index 0000000..b5f9402
--- /dev/null
+++ b/include/llvm/Debugger/ProgramInfo.h
@@ -0,0 +1,246 @@
+//===- ProgramInfo.h - Information about the loaded program -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various pieces of information about the currently loaded
+// program. One instance of this object is created every time a program is
+// loaded, and destroyed every time it is unloaded.
+//
+// The various pieces of information gathered about the source program are all
+// designed to be extended by various SourceLanguage implementations. This
+// allows source languages to keep any extended information that they support in
+// the derived class portions of the class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_PROGRAMINFO_H
+#define LLVM_DEBUGGER_PROGRAMINFO_H
+
+#include "llvm/System/TimeValue.h"
+#include <string>
+#include <map>
+#include <vector>
+
+namespace llvm {
+ class GlobalVariable;
+ class Module;
+ class SourceFile;
+ class SourceLanguage;
+ class ProgramInfo;
+
+ /// SourceLanguageCache - SourceLanguage implementations are allowed to cache
+ /// stuff in the ProgramInfo object. The only requirement we have on these
+ /// instances is that they are destroyable.
+ struct SourceLanguageCache {
+ virtual ~SourceLanguageCache() {}
+ };
+
+ /// SourceFileInfo - One instance of this structure is created for each
+ /// source file in the program.
+ ///
+ class SourceFileInfo {
+ /// BaseName - The filename of the source file.
+ std::string BaseName;
+
+ /// Directory - The working directory of this source file when it was
+ /// compiled.
+ std::string Directory;
+
+ /// Version - The version of the LLVM debug information that this file was
+ /// compiled with.
+ unsigned Version;
+
+ /// Language - The source language that the file was compiled with. This
+ /// pointer is never null.
+ ///
+ const SourceLanguage *Language;
+
+ /// Descriptor - The LLVM Global Variable which describes the source file.
+ ///
+ const GlobalVariable *Descriptor;
+
+ /// SourceText - The body of this source file, or null if it has not yet
+ /// been loaded.
+ mutable SourceFile *SourceText;
+ public:
+ SourceFileInfo(const GlobalVariable *Desc, const SourceLanguage &Lang);
+ ~SourceFileInfo();
+
+ const std::string &getBaseName() const { return BaseName; }
+ const std::string &getDirectory() const { return Directory; }
+ unsigned getDebugVersion() const { return Version; }
+ const GlobalVariable *getDescriptor() const { return Descriptor; }
+ SourceFile &getSourceText() const;
+
+ const SourceLanguage &getLanguage() const { return *Language; }
+ };
+
+
+ /// SourceFunctionInfo - An instance of this class is used to represent each
+ /// source function in the program.
+ ///
+ class SourceFunctionInfo {
+ /// Name - This contains an abstract name that is potentially useful to the
+ /// end-user. If there is no explicit support for the current language,
+ /// then this string is used to identify the function.
+ std::string Name;
+
+ /// Descriptor - The descriptor for this function.
+ ///
+ const GlobalVariable *Descriptor;
+
+ /// SourceFile - The file that this function is defined in.
+ ///
+ const SourceFileInfo *SourceFile;
+
+ /// LineNo, ColNo - The location of the first stop-point in the function.
+ /// These are computed on demand.
+ mutable unsigned LineNo, ColNo;
+
+ public:
+ SourceFunctionInfo(ProgramInfo &PI, const GlobalVariable *Desc);
+ virtual ~SourceFunctionInfo() {}
+
+ /// getSymbolicName - Return a human-readable symbolic name to identify the
+ /// function (for example, in stack traces).
+ virtual std::string getSymbolicName() const { return Name; }
+
+ /// getDescriptor - This returns the descriptor for the function.
+ ///
+ const GlobalVariable *getDescriptor() const { return Descriptor; }
+
+ /// getSourceFile - This returns the source file that defines the function.
+ ///
+ const SourceFileInfo &getSourceFile() const { return *SourceFile; }
+
+ /// getSourceLocation - This method returns the location of the first
+ /// stopping point in the function. If the body of the function cannot be
+ /// found, this returns zeros for both values.
+ void getSourceLocation(unsigned &LineNo, unsigned &ColNo) const;
+ };
+
+
+ /// ProgramInfo - This object contains information about the loaded program.
+ /// When a new program is loaded, an instance of this class is created. When
+ /// the program is unloaded, the instance is destroyed. This object basically
+ /// manages the lazy computation of information useful for the debugger.
+ class ProgramInfo {
+ Module *M;
+
+ /// ProgramTimeStamp - This is the timestamp of the executable file that we
+ /// currently have loaded into the debugger.
+ sys::TimeValue ProgramTimeStamp;
+
+ /// SourceFiles - This map is used to transform source file descriptors into
+ /// their corresponding SourceFileInfo objects. This mapping owns the
+ /// memory for the SourceFileInfo objects.
+ ///
+ bool SourceFilesIsComplete;
+ std::map<const GlobalVariable*, SourceFileInfo*> SourceFiles;
+
+ /// SourceFileIndex - Mapping from source file basenames to the information
+ /// about the file. Note that there can be filename collisions, so this is
+ /// a multimap. This map is populated incrementally as the user interacts
+ /// with the program, through the getSourceFileFromDesc method. If ALL of
+ /// the source files are needed, the getSourceFiles() method scans the
+ /// entire program looking for them.
+ ///
+ std::multimap<std::string, SourceFileInfo*> SourceFileIndex;
+
+ /// SourceFunctions - This map contains entries functions in the source
+ /// program. If SourceFunctionsIsComplete is true, then this is ALL of the
+ /// functions in the program are in this map.
+ bool SourceFunctionsIsComplete;
+ std::map<const GlobalVariable*, SourceFunctionInfo*> SourceFunctions;
+
+ /// LanguageCaches - Each source language is permitted to keep a per-program
+ /// cache of information specific to whatever it needs. This vector is
+ /// effectively a small map from the languages that are active in the
+ /// program to their caches. This can be accessed by the language by the
+ /// "getLanguageCache" method.
+ std::vector<std::pair<const SourceLanguage*,
+ SourceLanguageCache*> > LanguageCaches;
+ public:
+ ProgramInfo(Module *m);
+ ~ProgramInfo();
+
+ /// getProgramTimeStamp - Return the time-stamp of the program when it was
+ /// loaded.
+ sys::TimeValue getProgramTimeStamp() const { return ProgramTimeStamp; }
+
+ //===------------------------------------------------------------------===//
+ // Interfaces to the source code files that make up the program.
+ //
+
+ /// getSourceFile - Return source file information for the specified source
+ /// file descriptor object, adding it to the collection as needed. This
+ /// method always succeeds (is unambiguous), and is always efficient.
+ ///
+ const SourceFileInfo &getSourceFile(const GlobalVariable *Desc);
+
+ /// getSourceFile - Look up the file with the specified name. If there is
+ /// more than one match for the specified filename, prompt the user to pick
+ /// one. If there is no source file that matches the specified name, throw
+ /// an exception indicating that we can't find the file. Otherwise, return
+ /// the file information for that file.
+ ///
+ /// If the source file hasn't been discovered yet in the program, this
+ /// method might have to index the whole program by calling the
+ /// getSourceFiles() method.
+ ///
+ const SourceFileInfo &getSourceFile(const std::string &Filename);
+
+ /// getSourceFiles - Index all of the source files in the program and return
+ /// them. This information is lazily computed the first time that it is
+ /// requested. Since this information can take a long time to compute, the
+ /// user is given a chance to cancel it. If this occurs, an exception is
+ /// thrown.
+ const std::map<const GlobalVariable*, SourceFileInfo*> &
+ getSourceFiles(bool RequiresCompleteMap = true);
+
+ //===------------------------------------------------------------------===//
+ // Interfaces to the functions that make up the program.
+ //
+
+ /// getFunction - Return source function information for the specified
+ /// function descriptor object, adding it to the collection as needed. This
+ /// method always succeeds (is unambiguous), and is always efficient.
+ ///
+ const SourceFunctionInfo &getFunction(const GlobalVariable *Desc);
+
+ /// getSourceFunctions - Index all of the functions in the program and
+ /// return them. This information is lazily computed the first time that it
+ /// is requested. Since this information can take a long time to compute,
+ /// the user is given a chance to cancel it. If this occurs, an exception
+ /// is thrown.
+ const std::map<const GlobalVariable*, SourceFunctionInfo*> &
+ getSourceFunctions(bool RequiresCompleteMap = true);
+
+ /// addSourceFunctionsRead - Return true if the source functions map is
+ /// complete: that is, all functions in the program have been read in.
+ bool allSourceFunctionsRead() const { return SourceFunctionsIsComplete; }
+
+ /// getLanguageCache - This method is used to build per-program caches of
+ /// information, such as the functions or types visible to the program.
+ /// This can be used by SourceLanguage implementations because it requires
+ /// an accessible [sl]::CacheType typedef, where [sl] is the C++ type of the
+ /// source-language subclass.
+ template<typename SL>
+ typename SL::CacheType &getLanguageCache(const SL *L) {
+ for (unsigned i = 0, e = LanguageCaches.size(); i != e; ++i)
+ if (LanguageCaches[i].first == L)
+ return *(typename SL::CacheType*)LanguageCaches[i].second;
+ typename SL::CacheType *NewCache = L->createSourceLanguageCache(*this);
+ LanguageCaches.push_back(std::make_pair(L, NewCache));
+ return *NewCache;
+ }
+ };
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Debugger/RuntimeInfo.h b/include/llvm/Debugger/RuntimeInfo.h
new file mode 100644
index 0000000..2f4d37a
--- /dev/null
+++ b/include/llvm/Debugger/RuntimeInfo.h
@@ -0,0 +1,142 @@
+//===- RuntimeInfo.h - Information about running program --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes that capture various pieces of information about
+// the currently executing, but stopped, program. One instance of this object
+// is created every time a program is stopped, and destroyed every time it
+// starts running again. This object's main goal is to make access to runtime
+// information easy and efficient, by caching information as requested.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_RUNTIMEINFO_H
+#define LLVM_DEBUGGER_RUNTIMEINFO_H
+
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+ class ProgramInfo;
+ class RuntimeInfo;
+ class InferiorProcess;
+ class GlobalVariable;
+ class SourceFileInfo;
+
+ /// StackFrame - One instance of this structure is created for each stack
+ /// frame that is active in the program.
+ ///
+ class StackFrame {
+ RuntimeInfo &RI;
+ void *FrameID;
+ const GlobalVariable *FunctionDesc;
+
+ /// LineNo, ColNo, FileInfo - This information indicates WHERE in the source
+ /// code for the program the stack frame is located.
+ unsigned LineNo, ColNo;
+ const SourceFileInfo *SourceInfo;
+ public:
+ StackFrame(RuntimeInfo &RI, void *ParentFrameID);
+
+ StackFrame &operator=(const StackFrame &RHS) {
+ FrameID = RHS.FrameID;
+ FunctionDesc = RHS.FunctionDesc;
+ return *this;
+ }
+
+ /// getFrameID - return the low-level opaque frame ID of this stack frame.
+ ///
+ void *getFrameID() const { return FrameID; }
+
+ /// getFunctionDesc - Return the descriptor for the function that contains
+ /// this stack frame, or null if it is unknown.
+ ///
+ const GlobalVariable *getFunctionDesc();
+
+ /// getSourceLocation - Return the source location that this stack frame is
+ /// sitting at.
+ void getSourceLocation(unsigned &LineNo, unsigned &ColNo,
+ const SourceFileInfo *&SourceInfo);
+ };
+
+
+ /// RuntimeInfo - This class collects information about the currently running
+ /// process. It is created whenever the program stops execution for the
+ /// debugger, and destroyed whenver execution continues.
+ class RuntimeInfo {
+ /// ProgInfo - This object contains static information about the program.
+ ///
+ ProgramInfo *ProgInfo;
+
+ /// IP - This object contains information about the actual inferior process
+ /// that we are communicating with and aggregating information from.
+ const InferiorProcess &IP;
+
+ /// CallStack - This caches information about the current stack trace of the
+ /// program. This is lazily computed as needed.
+ std::vector<StackFrame> CallStack;
+
+ /// CurrentFrame - The user can traverse the stack frame with the
+ /// up/down/frame family of commands. This index indicates the current
+ /// stack frame.
+ unsigned CurrentFrame;
+
+ public:
+ RuntimeInfo(ProgramInfo *PI, const InferiorProcess &ip)
+ : ProgInfo(PI), IP(ip), CurrentFrame(0) {
+ // Make sure that the top of stack has been materialized. If this throws
+ // an exception, something is seriously wrong and the RuntimeInfo object
+ // would be unusable anyway.
+ getStackFrame(0);
+ }
+
+ ProgramInfo &getProgramInfo() { return *ProgInfo; }
+ const InferiorProcess &getInferiorProcess() const { return IP; }
+
+ //===------------------------------------------------------------------===//
+ // Methods for inspecting the call stack of the program.
+ //
+
+ /// getStackFrame - Materialize the specified stack frame and return it. If
+ /// the specified ID is off of the bottom of the stack, throw an exception
+ /// indicating the problem.
+ StackFrame &getStackFrame(unsigned ID) {
+ if (ID >= CallStack.size())
+ materializeFrame(ID);
+ return CallStack[ID];
+ }
+
+ /// getCurrentFrame - Return the current stack frame object that the user is
+ /// inspecting.
+ StackFrame &getCurrentFrame() {
+ assert(CallStack.size() > CurrentFrame &&
+ "Must have materialized frame before making it current!");
+ return CallStack[CurrentFrame];
+ }
+
+ /// getCurrentFrameIdx - Return the current frame the user is inspecting.
+ ///
+ unsigned getCurrentFrameIdx() const { return CurrentFrame; }
+
+ /// setCurrentFrameIdx - Set the current frame index to the specified value.
+ /// Note that the specified frame must have been materialized with
+ /// getStackFrame before it can be made current.
+ void setCurrentFrameIdx(unsigned Idx) {
+ assert(Idx < CallStack.size() &&
+ "Must materialize frame before making it current!");
+ CurrentFrame = Idx;
+ }
+ private:
+ /// materializeFrame - Create and process all frames up to and including the
+ /// specified frame number. This throws an exception if the specified frame
+ /// ID is nonexistant.
+ void materializeFrame(unsigned ID);
+ };
+}
+
+#endif
diff --git a/include/llvm/Debugger/SourceFile.h b/include/llvm/Debugger/SourceFile.h
new file mode 100644
index 0000000..e54660c
--- /dev/null
+++ b/include/llvm/Debugger/SourceFile.h
@@ -0,0 +1,97 @@
+//===- SourceFile.h - Class to represent a source code file -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the SourceFile class which is used to represent a single
+// file of source code in the program, caching data from the file to make access
+// efficient.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_SOURCEFILE_H
+#define LLVM_DEBUGGER_SOURCEFILE_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/MappedFile.h"
+#include <vector>
+
+namespace llvm {
+ class GlobalVariable;
+
+ class SourceFile {
+ /// Filename - This is the full path of the file that is loaded.
+ ///
+ sys::Path Filename;
+
+ /// Descriptor - The debugging descriptor for this source file. If there
+ /// are multiple descriptors for the same file, this is just the first one
+ /// encountered.
+ ///
+ const GlobalVariable *Descriptor;
+
+ /// This is the memory mapping for the file so we can gain access to it.
+ sys::MappedFile File;
+
+ /// LineOffset - This vector contains a mapping from source line numbers to
+ /// their offsets in the file. This data is computed lazily, the first time
+ /// it is asked for. If there are zero elements allocated in this vector,
+ /// then it has not yet been computed.
+ mutable std::vector<unsigned> LineOffset;
+
+ public:
+ /// SourceFile constructor - Read in the specified source file if it exists,
+ /// but do not build the LineOffsets table until it is requested. This will
+ /// NOT throw an exception if the file is not found, if there is an error
+ /// reading it, or if the user cancels the operation. Instead, it will just
+ /// be an empty source file.
+ SourceFile(const std::string &fn, const GlobalVariable *Desc)
+ : Filename(fn), Descriptor(Desc), File() {
+ std::string ErrMsg;
+ if (File.open(Filename, sys::MappedFile::READ_ACCESS, &ErrMsg))
+ throw ErrMsg;
+ readFile();
+ }
+ ~SourceFile() {
+ File.unmap();
+ }
+
+ /// getDescriptor - Return the debugging decriptor for this source file.
+ ///
+ const GlobalVariable *getDescriptor() const { return Descriptor; }
+
+ /// getFilename - Return the fully resolved path that this file was loaded
+ /// from.
+ const std::string &getFilename() const { return Filename.toString(); }
+
+ /// getSourceLine - Given a line number, return the start and end of the
+ /// line in the file. If the line number is invalid, or if the file could
+ /// not be loaded, null pointers are returned for the start and end of the
+ /// file. Note that line numbers start with 0, not 1. This also strips off
+ /// any newlines from the end of the line, to ease formatting of the text.
+ void getSourceLine(unsigned LineNo, const char *&LineStart,
+ const char *&LineEnd) const;
+
+ /// getNumLines - Return the number of lines the source file contains.
+ ///
+ unsigned getNumLines() const {
+ if (LineOffset.empty()) calculateLineOffsets();
+ return LineOffset.size();
+ }
+
+ private:
+ /// readFile - Load Filename into memory
+ ///
+ void readFile();
+
+ /// calculateLineOffsets - Compute the LineOffset vector for the current
+ /// file.
+ void calculateLineOffsets() const;
+ };
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Debugger/SourceLanguage.h b/include/llvm/Debugger/SourceLanguage.h
new file mode 100644
index 0000000..06f4381
--- /dev/null
+++ b/include/llvm/Debugger/SourceLanguage.h
@@ -0,0 +1,99 @@
+//===- SourceLanguage.h - Interact with source languages --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the abstract SourceLanguage interface, which is used by the
+// LLVM debugger to parse source-language expressions and render program objects
+// into a human readable string. In general, these classes perform all of the
+// analysis and interpretation of the language-specific debugger information.
+//
+// This interface is designed to be completely stateless, so all methods are
+// const.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGGER_SOURCELANGUAGE_H
+#define LLVM_DEBUGGER_SOURCELANGUAGE_H
+
+#include <string>
+
+namespace llvm {
+ class GlobalVariable;
+ class SourceFileInfo;
+ class SourceFunctionInfo;
+ class ProgramInfo;
+ class RuntimeInfo;
+
+ struct SourceLanguage {
+ virtual ~SourceLanguage() {}
+
+ /// getSourceLanguageName - This method is used to implement the 'show
+ /// language' command in the debugger.
+ virtual const char *getSourceLanguageName() const = 0;
+
+ //===------------------------------------------------------------------===//
+ // Methods used to implement debugger hooks.
+ //
+
+ /// printInfo - Implementing this method allows the debugger to use
+ /// language-specific 'info' extensions, e.g., 'info selectors' for objc.
+ /// This method should return true if the specified string is recognized.
+ ///
+ virtual bool printInfo(const std::string &What) const {
+ return false;
+ }
+
+ /// lookupFunction - Given a textual function name, return the
+ /// SourceFunctionInfo descriptor for that function, or null if it cannot be
+ /// found. If the program is currently running, the RuntimeInfo object
+ /// provides information about the current evaluation context, otherwise it
+ /// will be null.
+ ///
+ virtual SourceFunctionInfo *lookupFunction(const std::string &FunctionName,
+ ProgramInfo &PI,
+ RuntimeInfo *RI = 0) const {
+ return 0;
+ }
+
+
+ //===------------------------------------------------------------------===//
+ // Methods used to parse various pieces of program information.
+ //
+
+ /// createSourceFileInfo - This method can be implemented by the front-end
+ /// if it needs to keep track of information beyond what the debugger
+ /// requires.
+ virtual SourceFileInfo *
+ createSourceFileInfo(const GlobalVariable *Desc, ProgramInfo &PI) const;
+
+ /// createSourceFunctionInfo - This method can be implemented by the derived
+ /// SourceLanguage if it needs to keep track of more information than the
+ /// SourceFunctionInfo has.
+ virtual SourceFunctionInfo *
+ createSourceFunctionInfo(const GlobalVariable *Desc, ProgramInfo &PI) const;
+
+
+ //===------------------------------------------------------------------===//
+ // Static methods used to get instances of various source languages.
+ //
+
+ /// get - This method returns a source-language instance for the specified
+ /// Dwarf 3 language identifier. If the language is unknown, an object is
+ /// returned that can support some minimal operations, but is not terribly
+ /// bright.
+ static const SourceLanguage &get(unsigned ID);
+
+ /// get*Instance() - These methods return specific instances of languages.
+ ///
+ static const SourceLanguage &getCFamilyInstance();
+ static const SourceLanguage &getCPlusPlusInstance();
+ static const SourceLanguage &getUnknownLanguageInstance();
+ };
+}
+
+#endif
diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h
new file mode 100644
index 0000000..ba35d78
--- /dev/null
+++ b/include/llvm/DerivedTypes.h
@@ -0,0 +1,419 @@
+//===-- llvm/DerivedTypes.h - Classes for handling data types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations of classes that represent "derived
+// types". These are things like "arrays of x" or "structure of x, y, z" or
+// "method returning x taking (y,z) as parameters", etc...
+//
+// The implementations of these classes live in the Type.cpp file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DERIVED_TYPES_H
+#define LLVM_DERIVED_TYPES_H
+
+#include "llvm/Type.h"
+
+namespace llvm {
+
+class Value;
+template<class ValType, class TypeClass> class TypeMap;
+class FunctionValType;
+class ArrayValType;
+class StructValType;
+class PointerValType;
+class VectorValType;
+class IntegerValType;
+class APInt;
+class ParamAttrsList;
+
+class DerivedType : public Type {
+ friend class Type;
+
+protected:
+ explicit DerivedType(TypeID id) : Type(id) {}
+
+ /// notifyUsesThatTypeBecameConcrete - Notify AbstractTypeUsers of this type
+ /// that the current type has transitioned from being abstract to being
+ /// concrete.
+ ///
+ void notifyUsesThatTypeBecameConcrete();
+
+ /// dropAllTypeUses - When this (abstract) type is resolved to be equal to
+ /// another (more concrete) type, we must eliminate all references to other
+ /// types, to avoid some circular reference problems.
+ ///
+ void dropAllTypeUses();
+
+public:
+
+ //===--------------------------------------------------------------------===//
+ // Abstract Type handling methods - These types have special lifetimes, which
+ // are managed by (add|remove)AbstractTypeUser. See comments in
+ // AbstractTypeUser.h for more information.
+
+ /// refineAbstractTypeTo - This function is used to when it is discovered that
+ /// the 'this' abstract type is actually equivalent to the NewType specified.
+ /// This causes all users of 'this' to switch to reference the more concrete
+ /// type NewType and for 'this' to be deleted.
+ ///
+ void refineAbstractTypeTo(const Type *NewType);
+
+ void dump() const { Type::dump(); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DerivedType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->isDerivedType();
+ }
+};
+
+/// Class to represent integer types. Note that this class is also used to
+/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
+/// Int64Ty.
+/// @brief Integer representation type
+class IntegerType : public DerivedType {
+protected:
+ explicit IntegerType(unsigned NumBits) : DerivedType(IntegerTyID) {
+ setSubclassData(NumBits);
+ }
+ friend class TypeMap<IntegerValType, IntegerType>;
+public:
+ /// This enum is just used to hold constants we need for IntegerType.
+ enum {
+ MIN_INT_BITS = 1, ///< Minimum number of bits that can be specified
+ MAX_INT_BITS = (1<<23)-1 ///< Maximum number of bits that can be specified
+ ///< Note that bit width is stored in the Type classes SubclassData field
+ ///< which has 23 bits. This yields a maximum bit width of 8,388,607 bits.
+ };
+
+ /// This static method is the primary way of constructing an IntegerType.
+ /// If an IntegerType with the same NumBits value was previously instantiated,
+ /// that instance will be returned. Otherwise a new one will be created. Only
+ /// one instance with a given NumBits value is ever created.
+ /// @brief Get or create an IntegerType instance.
+ static const IntegerType* get(unsigned NumBits);
+
+ /// @brief Get the number of bits in this IntegerType
+ unsigned getBitWidth() const { return getSubclassData(); }
+
+ /// getBitMask - Return a bitmask with ones set for all of the bits
+ /// that can be set by an unsigned version of this type. This is 0xFF for
+ /// sbyte/ubyte, 0xFFFF for shorts, etc.
+ uint64_t getBitMask() const {
+ return ~uint64_t(0UL) >> (64-getBitWidth());
+ }
+
+ /// getSignBit - Return a uint64_t with just the most significant bit set (the
+ /// sign bit, if the value is treated as a signed number).
+ uint64_t getSignBit() const {
+ return 1ULL << (getBitWidth()-1);
+ }
+
+ /// For example, this is 0xFF for an 8 bit integer, 0xFFFF for i16, etc.
+ /// @returns a bit mask with ones set for all the bits of this type.
+ /// @brief Get a bit mask for this type.
+ APInt getMask() const;
+
+ /// This method determines if the width of this IntegerType is a power-of-2
+ /// in terms of 8 bit bytes.
+ /// @returns true if this is a power-of-2 byte width.
+ /// @brief Is this a power-of-2 byte-width IntegerType ?
+ bool isPowerOf2ByteWidth() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const IntegerType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == IntegerTyID;
+ }
+};
+
+
+/// FunctionType - Class to represent function types
+///
+class FunctionType : public DerivedType {
+ friend class TypeMap<FunctionValType, FunctionType>;
+ bool isVarArgs;
+ const ParamAttrsList *ParamAttrs;
+
+ FunctionType(const FunctionType &); // Do not implement
+ const FunctionType &operator=(const FunctionType &); // Do not implement
+ FunctionType(const Type *Result, const std::vector<const Type*> &Params,
+ bool IsVarArgs, const ParamAttrsList *Attrs = 0);
+
+public:
+ /// FunctionType::get - This static method is the primary way of constructing
+ /// a FunctionType.
+ ///
+ static FunctionType *get(
+ const Type *Result, ///< The result type
+ const std::vector<const Type*> &Params, ///< The types of the parameters
+ bool isVarArg, ///< Whether this is a variable argument length function
+ const ParamAttrsList *Attrs = 0
+ ///< Indicates the parameter attributes to use, if any. The 0th entry
+ ///< in the list refers to the return type. Parameters are numbered
+ ///< starting at 1. This argument must be on the heap and FunctionType
+ ///< owns it after its passed here.
+ );
+
+ inline bool isVarArg() const { return isVarArgs; }
+ inline const Type *getReturnType() const { return ContainedTys[0]; }
+
+ typedef Type::subtype_iterator param_iterator;
+ param_iterator param_begin() const { return ContainedTys + 1; }
+ param_iterator param_end() const { return &ContainedTys[NumContainedTys]; }
+
+ // Parameter type accessors...
+ const Type *getParamType(unsigned i) const { return ContainedTys[i+1]; }
+
+ /// getNumParams - Return the number of fixed parameters this function type
+ /// requires. This does not consider varargs.
+ ///
+ unsigned getNumParams() const { return NumContainedTys - 1; }
+
+ bool isStructReturn() const;
+
+ /// The parameter attributes for the \p ith parameter are returned. The 0th
+ /// parameter refers to the return type of the function.
+ /// @returns The ParameterAttributes for the \p ith parameter.
+ /// @brief Get the attributes for a parameter
+ const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FunctionType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == FunctionTyID;
+ }
+};
+
+
+/// CompositeType - Common super class of ArrayType, StructType, PointerType
+/// and VectorType
+class CompositeType : public DerivedType {
+protected:
+ inline explicit CompositeType(TypeID id) : DerivedType(id) { }
+public:
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element.
+ ///
+ virtual const Type *getTypeAtIndex(const Value *V) const = 0;
+ virtual bool indexValid(const Value *V) const = 0;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CompositeType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == ArrayTyID ||
+ T->getTypeID() == StructTyID ||
+ T->getTypeID() == PointerTyID ||
+ T->getTypeID() == VectorTyID;
+ }
+};
+
+
+/// StructType - Class to represent struct types
+///
+class StructType : public CompositeType {
+ friend class TypeMap<StructValType, StructType>;
+ StructType(const StructType &); // Do not implement
+ const StructType &operator=(const StructType &); // Do not implement
+ StructType(const std::vector<const Type*> &Types, bool isPacked);
+public:
+ /// StructType::get - This static method is the primary way to create a
+ /// StructType.
+ ///
+ static StructType *get(const std::vector<const Type*> &Params,
+ bool isPacked=false);
+
+ // Iterator access to the elements
+ typedef Type::subtype_iterator element_iterator;
+ element_iterator element_begin() const { return ContainedTys; }
+ element_iterator element_end() const { return &ContainedTys[NumContainedTys];}
+
+ // Random access to the elements
+ unsigned getNumElements() const { return NumContainedTys; }
+ const Type *getElementType(unsigned N) const {
+ assert(N < NumContainedTys && "Element number out of range!");
+ return ContainedTys[N];
+ }
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element. For a structure type, this must be a constant value...
+ ///
+ virtual const Type *getTypeAtIndex(const Value *V) const ;
+ virtual bool indexValid(const Value *V) const;
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const StructType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == StructTyID;
+ }
+
+ bool isPacked() const { return getSubclassData(); }
+};
+
+
+/// SequentialType - This is the superclass of the array, pointer and vector
+/// type classes. All of these represent "arrays" in memory. The array type
+/// represents a specifically sized array, pointer types are unsized/unknown
+/// size arrays, vector types represent specifically sized arrays that
+/// allow for use of SIMD instructions. SequentialType holds the common
+/// features of all, which stem from the fact that all three lay their
+/// components out in memory identically.
+///
+class SequentialType : public CompositeType {
+ PATypeHandle ContainedType; ///< Storage for the single contained type
+ SequentialType(const SequentialType &); // Do not implement!
+ const SequentialType &operator=(const SequentialType &); // Do not implement!
+protected:
+ SequentialType(TypeID TID, const Type *ElType)
+ : CompositeType(TID), ContainedType(ElType, this) {
+ ContainedTys = &ContainedType;
+ NumContainedTys = 1;
+ }
+
+public:
+ inline const Type *getElementType() const { return ContainedTys[0]; }
+
+ virtual bool indexValid(const Value *V) const;
+
+ /// getTypeAtIndex - Given an index value into the type, return the type of
+ /// the element. For sequential types, there is only one subtype...
+ ///
+ virtual const Type *getTypeAtIndex(const Value *V) const {
+ return ContainedTys[0];
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SequentialType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == ArrayTyID ||
+ T->getTypeID() == PointerTyID ||
+ T->getTypeID() == VectorTyID;
+ }
+};
+
+
+/// ArrayType - Class to represent array types
+///
+class ArrayType : public SequentialType {
+ friend class TypeMap<ArrayValType, ArrayType>;
+ uint64_t NumElements;
+
+ ArrayType(const ArrayType &); // Do not implement
+ const ArrayType &operator=(const ArrayType &); // Do not implement
+ ArrayType(const Type *ElType, uint64_t NumEl);
+public:
+ /// ArrayType::get - This static method is the primary way to construct an
+ /// ArrayType
+ ///
+ static ArrayType *get(const Type *ElementType, uint64_t NumElements);
+
+ inline uint64_t getNumElements() const { return NumElements; }
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ArrayType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == ArrayTyID;
+ }
+};
+
+/// VectorType - Class to represent vector types
+///
+class VectorType : public SequentialType {
+ friend class TypeMap<VectorValType, VectorType>;
+ unsigned NumElements;
+
+ VectorType(const VectorType &); // Do not implement
+ const VectorType &operator=(const VectorType &); // Do not implement
+ VectorType(const Type *ElType, unsigned NumEl);
+public:
+ /// VectorType::get - This static method is the primary way to construct an
+ /// VectorType
+ ///
+ static VectorType *get(const Type *ElementType, unsigned NumElements);
+
+ /// @brief Return the number of elements in the Vector type.
+ inline unsigned getNumElements() const { return NumElements; }
+
+ /// @brief Return the number of bits in the Vector type.
+ inline unsigned getBitWidth() const {
+ return NumElements *getElementType()->getPrimitiveSizeInBits();
+ }
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const VectorType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == VectorTyID;
+ }
+};
+
+
+/// PointerType - Class to represent pointers
+///
+class PointerType : public SequentialType {
+ friend class TypeMap<PointerValType, PointerType>;
+ PointerType(const PointerType &); // Do not implement
+ const PointerType &operator=(const PointerType &); // Do not implement
+ explicit PointerType(const Type *ElType);
+public:
+ /// PointerType::get - This is the only way to construct a new pointer type.
+ static PointerType *get(const Type *ElementType);
+
+ // Implement the AbstractTypeUser interface.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+ // Implement support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const PointerType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == PointerTyID;
+ }
+};
+
+
+/// OpaqueType - Class to represent abstract types
+///
+class OpaqueType : public DerivedType {
+ OpaqueType(const OpaqueType &); // DO NOT IMPLEMENT
+ const OpaqueType &operator=(const OpaqueType &); // DO NOT IMPLEMENT
+ OpaqueType();
+public:
+ /// OpaqueType::get - Static factory method for the OpaqueType class...
+ ///
+ static OpaqueType *get() {
+ return new OpaqueType(); // All opaque types are distinct
+ }
+
+ // Implement support for type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const OpaqueType *T) { return true; }
+ static inline bool classof(const Type *T) {
+ return T->getTypeID() == OpaqueTyID;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
new file mode 100644
index 0000000..7100a5f
--- /dev/null
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -0,0 +1,227 @@
+//===- ExecutionEngine.h - Abstract Execution Engine Interface --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the abstract interface that implements execution support
+// for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EXECUTION_ENGINE_H
+#define EXECUTION_ENGINE_H
+
+#include <vector>
+#include <map>
+#include <cassert>
+#include <string>
+#include "llvm/System/Mutex.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+struct GenericValue;
+class Constant;
+class Function;
+class GlobalVariable;
+class GlobalValue;
+class Module;
+class ModuleProvider;
+class TargetData;
+class Type;
+class MutexGuard;
+
+class ExecutionEngineState {
+private:
+ /// GlobalAddressMap - A mapping between LLVM global values and their
+ /// actualized version...
+ std::map<const GlobalValue*, void *> GlobalAddressMap;
+
+ /// GlobalAddressReverseMap - This is the reverse mapping of GlobalAddressMap,
+ /// used to convert raw addresses into the LLVM global value that is emitted
+ /// at the address. This map is not computed unless getGlobalValueAtAddress
+ /// is called at some point.
+ std::map<void *, const GlobalValue*> GlobalAddressReverseMap;
+
+public:
+ std::map<const GlobalValue*, void *> &
+ getGlobalAddressMap(const MutexGuard &locked) {
+ return GlobalAddressMap;
+ }
+
+ std::map<void*, const GlobalValue*> &
+ getGlobalAddressReverseMap(const MutexGuard& locked) {
+ return GlobalAddressReverseMap;
+ }
+};
+
+
+class ExecutionEngine {
+ const TargetData *TD;
+ ExecutionEngineState state;
+ bool LazyCompilationDisabled;
+protected:
+ /// Modules - This is a list of ModuleProvider's that we are JIT'ing from. We
+ /// use a smallvector to optimize for the case where there is only one module.
+ SmallVector<ModuleProvider*, 1> Modules;
+
+ void setTargetData(const TargetData *td) {
+ TD = td;
+ }
+
+ // To avoid having libexecutionengine depend on the JIT and interpreter
+ // libraries, the JIT and Interpreter set these functions to ctor pointers
+ // at startup time if they are linked in.
+ typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*);
+ static EECtorFn JITCtor, InterpCtor;
+
+public:
+ /// lock - This lock is protects the ExecutionEngine, JIT, JITResolver and
+ /// JITEmitter classes. It must be held while changing the internal state of
+ /// any of those classes.
+ sys::Mutex lock; // Used to make this class and subclasses thread-safe
+
+ ExecutionEngine(ModuleProvider *P);
+ ExecutionEngine(Module *M);
+ virtual ~ExecutionEngine();
+
+ const TargetData *getTargetData() const { return TD; }
+
+ /// addModuleProvider - Add a ModuleProvider to the list of modules that we
+ /// can JIT from. Note that this takes ownership of the ModuleProvider: when
+ /// the ExecutionEngine is destroyed, it destroys the MP as well.
+ void addModuleProvider(ModuleProvider *P) {
+ Modules.push_back(P);
+ }
+
+ /// FindFunctionNamed - Search all of the active modules to find the one that
+ /// defines FnName. This is very slow operation and shouldn't be used for
+ /// general code.
+ Function *FindFunctionNamed(const char *FnName);
+
+ /// create - This is the factory method for creating an execution engine which
+ /// is appropriate for the current machine.
+ static ExecutionEngine *create(ModuleProvider *MP,
+ bool ForceInterpreter = false,
+ std::string *ErrorStr = 0);
+
+ /// runFunction - Execute the specified function with the specified arguments,
+ /// and return the result.
+ ///
+ virtual GenericValue runFunction(Function *F,
+ const std::vector<GenericValue> &ArgValues) = 0;
+
+ /// runStaticConstructorsDestructors - This method is used to execute all of
+ /// the static constructors or destructors for a module, depending on the
+ /// value of isDtors.
+ void runStaticConstructorsDestructors(bool isDtors);
+
+
+ /// runFunctionAsMain - This is a helper function which wraps runFunction to
+ /// handle the common task of starting up main with the specified argc, argv,
+ /// and envp parameters.
+ int runFunctionAsMain(Function *Fn, const std::vector<std::string> &argv,
+ const char * const * envp);
+
+
+ /// addGlobalMapping - Tell the execution engine that the specified global is
+ /// at the specified location. This is used internally as functions are JIT'd
+ /// and as global variables are laid out in memory. It can and should also be
+ /// used by clients of the EE that want to have an LLVM global overlay
+ /// existing data in memory.
+ void addGlobalMapping(const GlobalValue *GV, void *Addr);
+
+ /// clearAllGlobalMappings - Clear all global mappings and start over again
+ /// use in dynamic compilation scenarios when you want to move globals
+ void clearAllGlobalMappings();
+
+ /// updateGlobalMapping - Replace an existing mapping for GV with a new
+ /// address. This updates both maps as required. If "Addr" is null, the
+ /// entry for the global is removed from the mappings.
+ void updateGlobalMapping(const GlobalValue *GV, void *Addr);
+
+ /// getPointerToGlobalIfAvailable - This returns the address of the specified
+ /// global value if it is has already been codegen'd, otherwise it returns
+ /// null.
+ ///
+ void *getPointerToGlobalIfAvailable(const GlobalValue *GV);
+
+ /// getPointerToGlobal - This returns the address of the specified global
+ /// value. This may involve code generation if it's a function.
+ ///
+ void *getPointerToGlobal(const GlobalValue *GV);
+
+ /// getPointerToFunction - The different EE's represent function bodies in
+ /// different ways. They should each implement this to say what a function
+ /// pointer should look like.
+ ///
+ virtual void *getPointerToFunction(Function *F) = 0;
+
+ /// getPointerToFunctionOrStub - If the specified function has been
+ /// code-gen'd, return a pointer to the function. If not, compile it, or use
+ /// a stub to implement lazy compilation if available.
+ ///
+ virtual void *getPointerToFunctionOrStub(Function *F) {
+ // Default implementation, just codegen the function.
+ return getPointerToFunction(F);
+ }
+
+ /// getGlobalValueAtAddress - Return the LLVM global value object that starts
+ /// at the specified address.
+ ///
+ const GlobalValue *getGlobalValueAtAddress(void *Addr);
+
+
+ void StoreValueToMemory(const GenericValue &Val, GenericValue *Ptr, const Type *Ty);
+ void InitializeMemory(const Constant *Init, void *Addr);
+
+ /// recompileAndRelinkFunction - This method is used to force a function
+ /// which has already been compiled to be compiled again, possibly
+ /// after it has been modified. Then the entry to the old copy is overwritten
+ /// with a branch to the new copy. If there was no old copy, this acts
+ /// just like VM::getPointerToFunction().
+ ///
+ virtual void *recompileAndRelinkFunction(Function *F) = 0;
+
+ /// freeMachineCodeForFunction - Release memory in the ExecutionEngine
+ /// corresponding to the machine code emitted to execute this function, useful
+ /// for garbage-collecting generated code.
+ ///
+ virtual void freeMachineCodeForFunction(Function *F) = 0;
+
+ /// getOrEmitGlobalVariable - Return the address of the specified global
+ /// variable, possibly emitting it to memory if needed. This is used by the
+ /// Emitter.
+ virtual void *getOrEmitGlobalVariable(const GlobalVariable *GV) {
+ return getPointerToGlobal((GlobalValue*)GV);
+ }
+
+ /// DisableLazyCompilation - If called, the JIT will abort if lazy compilation
+ // is ever attempted.
+ void DisableLazyCompilation() {
+ LazyCompilationDisabled = true;
+ }
+ bool isLazyCompilationDisabled() const {
+ return LazyCompilationDisabled;
+ }
+
+protected:
+ void emitGlobals();
+
+ // EmitGlobalVariable - This method emits the specified global variable to the
+ // address specified in GlobalAddresses, or allocates new memory if it's not
+ // already in the map.
+ void EmitGlobalVariable(const GlobalVariable *GV);
+
+ GenericValue getConstantValue(const Constant *C);
+ void LoadValueFromMemory(GenericValue &Result, GenericValue *Ptr,
+ const Type *Ty);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ExecutionEngine/GenericValue.h b/include/llvm/ExecutionEngine/GenericValue.h
new file mode 100644
index 0000000..d0cd2cd
--- /dev/null
+++ b/include/llvm/ExecutionEngine/GenericValue.h
@@ -0,0 +1,44 @@
+//===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The GenericValue class is used to represent an LLVM value of arbitrary type.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef GENERIC_VALUE_H
+#define GENERIC_VALUE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+typedef void* PointerTy;
+class APInt;
+
+struct GenericValue {
+ union {
+ double DoubleVal;
+ float FloatVal;
+ PointerTy PointerVal;
+ struct { unsigned int first; unsigned int second; } UIntPairVal;
+ unsigned char Untyped[8];
+ };
+ APInt IntVal;
+
+ GenericValue() : DoubleVal(0.0), IntVal(1,0) {}
+ GenericValue(void *V) : PointerVal(V), IntVal(1,0) { }
+};
+
+inline GenericValue PTOGV(void *P) { return GenericValue(P); }
+inline void* GVTOP(const GenericValue &GV) { return GV.PointerVal; }
+
+} // End llvm namespace
+#endif
diff --git a/include/llvm/ExecutionEngine/Interpreter.h b/include/llvm/ExecutionEngine/Interpreter.h
new file mode 100644
index 0000000..b46574d
--- /dev/null
+++ b/include/llvm/ExecutionEngine/Interpreter.h
@@ -0,0 +1,40 @@
+//===-- Interpreter.h - Abstract Execution Engine Interface -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Jeff Cohen and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the interpreter to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EXECUTION_ENGINE_INTERPRETER_H
+#define EXECUTION_ENGINE_INTERPRETER_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+namespace llvm {
+ extern void LinkInInterpreter();
+}
+
+namespace {
+ struct ForceInterpreterLinking {
+ ForceInterpreterLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ llvm::LinkInInterpreter();
+ }
+ } ForceInterpreterLinking;
+}
+
+#endif
diff --git a/include/llvm/ExecutionEngine/JIT.h b/include/llvm/ExecutionEngine/JIT.h
new file mode 100644
index 0000000..b801f1d
--- /dev/null
+++ b/include/llvm/ExecutionEngine/JIT.h
@@ -0,0 +1,40 @@
+//===-- JIT.h - Abstract Execution Engine Interface -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Jeff Cohen and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file forces the JIT to link in on certain operating systems.
+// (Windows).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef EXECUTION_ENGINE_JIT_H
+#define EXECUTION_ENGINE_JIT_H
+
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include <cstdlib>
+
+namespace llvm {
+ extern void LinkInJIT();
+}
+
+namespace {
+ struct ForceJITLinking {
+ ForceJITLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ llvm::LinkInJIT();
+ }
+ } ForceJITLinking;
+}
+
+#endif
diff --git a/include/llvm/Function.h b/include/llvm/Function.h
new file mode 100644
index 0000000..b3b9716
--- /dev/null
+++ b/include/llvm/Function.h
@@ -0,0 +1,280 @@
+//===-- llvm/Function.h - Class to represent a single function --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Function class, which represents a
+// single function/procedure in LLVM.
+//
+// A function basically consists of a list of basic blocks, a list of arguments,
+// and a symbol table.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUNCTION_H
+#define LLVM_FUNCTION_H
+
+#include "llvm/GlobalValue.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Argument.h"
+#include "llvm/Support/Annotation.h"
+
+namespace llvm {
+
+class FunctionType;
+class ParamAttrsList;
+
+// Traits for intrusive list of instructions...
+template<> struct ilist_traits<BasicBlock>
+ : public SymbolTableListTraits<BasicBlock, Function> {
+
+ // createSentinel is used to create a node that marks the end of the list...
+ static BasicBlock *createSentinel();
+ static void destroySentinel(BasicBlock *BB) { delete BB; }
+ static iplist<BasicBlock> &getList(Function *F);
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
+ static int getListOffset();
+};
+
+template<> struct ilist_traits<Argument>
+ : public SymbolTableListTraits<Argument, Function> {
+
+ // createSentinel is used to create a node that marks the end of the list...
+ static Argument *createSentinel();
+ static void destroySentinel(Argument *A) { delete A; }
+ static iplist<Argument> &getList(Function *F);
+ static ValueSymbolTable *getSymTab(Function *ItemParent);
+ static int getListOffset();
+};
+
+class Function : public GlobalValue, public Annotable {
+public:
+ typedef iplist<Argument> ArgumentListType;
+ typedef iplist<BasicBlock> BasicBlockListType;
+
+ // BasicBlock iterators...
+ typedef BasicBlockListType::iterator iterator;
+ typedef BasicBlockListType::const_iterator const_iterator;
+
+ typedef ArgumentListType::iterator arg_iterator;
+ typedef ArgumentListType::const_iterator const_arg_iterator;
+
+private:
+ // Important things that make up a function!
+ BasicBlockListType BasicBlocks; ///< The basic blocks
+ ArgumentListType ArgumentList; ///< The formal arguments
+ ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
+ ParamAttrsList *ParamAttrs; ///< Parameter attributes
+
+
+ // The Calling Convention is stored in Value::SubclassData.
+ /*unsigned CallingConvention;*/
+
+ friend class SymbolTableListTraits<Function, Module>;
+
+ void setParent(Module *parent);
+ Function *Prev, *Next;
+ void setNext(Function *N) { Next = N; }
+ void setPrev(Function *N) { Prev = N; }
+
+ // getNext/Prev - Return the next or previous function in the list. These
+ // methods should never be used directly, and are only used to implement the
+ // function list as part of the module.
+ //
+ Function *getNext() { return Next; }
+ const Function *getNext() const { return Next; }
+ Function *getPrev() { return Prev; }
+ const Function *getPrev() const { return Prev; }
+
+public:
+ /// Function ctor - If the (optional) Module argument is specified, the
+ /// function is automatically inserted into the end of the function list for
+ /// the module.
+ ///
+ Function(const FunctionType *Ty, LinkageTypes Linkage,
+ const std::string &N = "", Module *M = 0);
+ ~Function();
+
+ const Type *getReturnType() const; // Return the type of the ret val
+ const FunctionType *getFunctionType() const; // Return the FunctionType for me
+
+ /// isVarArg - Return true if this function takes a variable number of
+ /// arguments.
+ bool isVarArg() const;
+
+ /// isDeclaration - Is the body of this function unknown? (The basic block
+ /// list is empty if so.) This is true for function declarations, but not
+ /// true for function definitions.
+ ///
+ virtual bool isDeclaration() const { return BasicBlocks.empty(); }
+
+ /// getIntrinsicID - This method returns the ID number of the specified
+ /// function, or Intrinsic::not_intrinsic if the function is not an
+ /// instrinsic, or if the pointer is null. This value is always defined to be
+ /// zero to allow easy checking for whether a function is intrinsic or not.
+ /// The particular intrinsic functions which correspond to this value are
+ /// defined in llvm/Intrinsics.h.
+ ///
+ unsigned getIntrinsicID(bool noAssert = false) const;
+ bool isIntrinsic() const { return getIntrinsicID() != 0; }
+
+ /// getCallingConv()/setCallingConv(uint) - These method get and set the
+ /// calling convention of this function. The enum values for the known
+ /// calling conventions are defined in CallingConv.h.
+ unsigned getCallingConv() const { return SubclassData; }
+ void setCallingConv(unsigned CC) { SubclassData = CC; }
+
+ /// Obtains a constant pointer to the ParamAttrsList object which holds the
+ /// parameter attributes information, if any.
+ /// @returns 0 if no parameter attributes have been set.
+ /// @brief Get the parameter attributes.
+ const ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ /// Sets the parameter attributes for this Function. To construct a
+ /// ParamAttrsList, see ParameterAttributes.h
+ /// @brief Set the parameter attributes.
+ void setParamAttrs(ParamAttrsList *attrs);
+
+ /// deleteBody - This method deletes the body of the function, and converts
+ /// the linkage to external.
+ ///
+ void deleteBody() {
+ dropAllReferences();
+ setLinkage(ExternalLinkage);
+ }
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ void eraseFromParent();
+
+
+ /// Get the underlying elements of the Function... the basic block list is
+ /// empty for external functions.
+ ///
+ const ArgumentListType &getArgumentList() const { return ArgumentList; }
+ ArgumentListType &getArgumentList() { return ArgumentList; }
+
+ const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
+ BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
+
+ const BasicBlock &getEntryBlock() const { return front(); }
+ BasicBlock &getEntryBlock() { return front(); }
+
+ //===--------------------------------------------------------------------===//
+ // Symbol Table Accessing functions...
+
+ /// getSymbolTable() - Return the symbol table...
+ ///
+ inline ValueSymbolTable &getValueSymbolTable() { return *SymTab; }
+ inline const ValueSymbolTable &getValueSymbolTable() const { return *SymTab; }
+
+
+ //===--------------------------------------------------------------------===//
+ // BasicBlock iterator forwarding functions
+ //
+ iterator begin() { return BasicBlocks.begin(); }
+ const_iterator begin() const { return BasicBlocks.begin(); }
+ iterator end () { return BasicBlocks.end(); }
+ const_iterator end () const { return BasicBlocks.end(); }
+
+ size_t size() const { return BasicBlocks.size(); }
+ bool empty() const { return BasicBlocks.empty(); }
+ const BasicBlock &front() const { return BasicBlocks.front(); }
+ BasicBlock &front() { return BasicBlocks.front(); }
+ const BasicBlock &back() const { return BasicBlocks.back(); }
+ BasicBlock &back() { return BasicBlocks.back(); }
+
+ //===--------------------------------------------------------------------===//
+ // Argument iterator forwarding functions
+ //
+ arg_iterator arg_begin() { return ArgumentList.begin(); }
+ const_arg_iterator arg_begin() const { return ArgumentList.begin(); }
+ arg_iterator arg_end () { return ArgumentList.end(); }
+ const_arg_iterator arg_end () const { return ArgumentList.end(); }
+
+ size_t arg_size () const { return ArgumentList.size(); }
+ bool arg_empty() const { return ArgumentList.empty(); }
+
+ virtual void print(std::ostream &OS) const { print(OS, 0); }
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+ /// viewCFG - This function is meant for use from the debugger. You can just
+ /// say 'call F->viewCFG()' and a ghostview window should pop up from the
+ /// program, displaying the CFG of the current function with the code for each
+ /// basic block inside. This depends on there being a 'dot' and 'gv' program
+ /// in your path.
+ ///
+ void viewCFG() const;
+
+ /// viewCFGOnly - This function is meant for use from the debugger. It works
+ /// just like viewCFG, but it does not include the contents of basic blocks
+ /// into the nodes, just the label. If you are only interested in the CFG
+ /// this can make the graph smaller.
+ ///
+ void viewCFGOnly() const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Function *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::FunctionVal;
+ }
+
+ /// dropAllReferences() - This method causes all the subinstructions to "let
+ /// go" of all references that they are maintaining. This allows one to
+ /// 'delete' a whole module at a time, even though there may be circular
+ /// references... first all references are dropped, and all use counts go to
+ /// zero. Then everything is deleted for real. Note that no operations are
+ /// valid on an object that has "dropped all references", except operator
+ /// delete.
+ ///
+ /// Since no other object in the module can have references into the body of a
+ /// function, dropping all references deletes the entire body of the function,
+ /// including any contained basic blocks.
+ ///
+ void dropAllReferences();
+
+ static unsigned getBasicBlockListOffset() {
+ Function *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->BasicBlocks));
+ }
+ static unsigned getArgumentListOffset() {
+ Function *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList));
+ }
+};
+
+inline ValueSymbolTable *
+ilist_traits<BasicBlock>::getSymTab(Function *F) {
+ return F ? &F->getValueSymbolTable() : 0;
+}
+
+inline ValueSymbolTable *
+ilist_traits<Argument>::getSymTab(Function *F) {
+ return F ? &F->getValueSymbolTable() : 0;
+}
+
+inline int
+ilist_traits<BasicBlock>::getListOffset() {
+ return Function::getBasicBlockListOffset();
+}
+
+inline int
+ilist_traits<Argument>::getListOffset() {
+ return Function::getArgumentListOffset();
+}
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h
new file mode 100644
index 0000000..bbd19ba
--- /dev/null
+++ b/include/llvm/GlobalAlias.h
@@ -0,0 +1,91 @@
+//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Anton Korobeynikov and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalAlias class, which
+// represents a single function or variable alias in the IR.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GLOBAL_ALIAS_H
+#define LLVM_GLOBAL_ALIAS_H
+
+#include "llvm/GlobalValue.h"
+
+namespace llvm {
+
+class Module;
+class Constant;
+class PointerType;
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+class GlobalAlias : public GlobalValue {
+ friend class SymbolTableListTraits<GlobalAlias, Module>;
+ void operator=(const GlobalAlias &); // Do not implement
+ GlobalAlias(const GlobalAlias &); // Do not implement
+
+ void setParent(Module *parent);
+
+ GlobalAlias *Prev, *Next;
+ void setNext(GlobalAlias *N) { Next = N; }
+ void setPrev(GlobalAlias *N) { Prev = N; }
+
+ // getNext/Prev - Return the next or previous alias in the list.
+ GlobalAlias *getNext() { return Next; }
+ const GlobalAlias *getNext() const { return Next; }
+ GlobalAlias *getPrev() { return Prev; }
+ const GlobalAlias *getPrev() const { return Prev; }
+
+ Use Aliasee;
+public:
+ /// GlobalAlias ctor - If a parent module is specified, the alias is
+ /// automatically inserted into the end of the specified module's alias list.
+ GlobalAlias(const Type *Ty, LinkageTypes Linkage, const std::string &Name = "",
+ Constant* Aliasee = 0, Module *Parent = 0);
+
+ /// isDeclaration - Is this global variable lacking an initializer? If so,
+ /// the global variable is defined in some other translation unit, and is thus
+ /// only a declaration here.
+ virtual bool isDeclaration() const;
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ void eraseFromParent();
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// set/getAliasee - These methods retrive and set alias target.
+ void setAliasee(Constant* GV);
+ const Constant* getAliasee() const {
+ return cast_or_null<Constant>(getOperand(0));
+ }
+ Constant* getAliasee() {
+ return cast_or_null<Constant>(getOperand(0));
+ }
+ /// getAliasedGlobal() - Aliasee can be either global or bitcast of
+ /// global. This method retrives the global for both aliasee flavours.
+ const GlobalValue* getAliasedGlobal() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const GlobalAlias *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::GlobalAliasVal;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h
new file mode 100644
index 0000000..6735cb5
--- /dev/null
+++ b/include/llvm/GlobalValue.h
@@ -0,0 +1,151 @@
+//===-- llvm/GlobalValue.h - Class to represent a global value --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a common base class of all globally definable objects. As such,
+// it is subclassed by GlobalVariable, GlobalAlias and by Function. This is
+// used because you can do certain things with these global objects that you
+// can't do to anything else. For example, use the address of one as a
+// constant.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GLOBALVALUE_H
+#define LLVM_GLOBALVALUE_H
+
+#include "llvm/Constant.h"
+
+namespace llvm {
+
+class PointerType;
+class Module;
+
+class GlobalValue : public Constant {
+ GlobalValue(const GlobalValue &); // do not implement
+public:
+ /// @brief An enumeration for the kinds of linkage for global values.
+ enum LinkageTypes {
+ ExternalLinkage = 0,///< Externally visible function
+ LinkOnceLinkage, ///< Keep one copy of function when linking (inline)
+ WeakLinkage, ///< Keep one copy of named function when linking (weak)
+ AppendingLinkage, ///< Special purpose, only applies to global arrays
+ InternalLinkage, ///< Rename collisions when linking (static functions)
+ DLLImportLinkage, ///< Function to be imported from DLL
+ DLLExportLinkage, ///< Function to be accessible from DLL
+ ExternalWeakLinkage,///< ExternalWeak linkage description
+ GhostLinkage ///< Stand-in functions for streaming fns from BC files
+ };
+
+ /// @brief An enumeration for the kinds of visibility of global values.
+ enum VisibilityTypes {
+ DefaultVisibility = 0, ///< The GV is visible
+ HiddenVisibility, ///< The GV is hidden
+ ProtectedVisibility ///< The GV is protected
+ };
+
+protected:
+ GlobalValue(const Type *Ty, ValueTy vty, Use *Ops, unsigned NumOps,
+ LinkageTypes linkage, const std::string &name = "")
+ : Constant(Ty, vty, Ops, NumOps), Parent(0),
+ Linkage(linkage), Visibility(DefaultVisibility), Alignment(0) {
+ if (!name.empty()) setName(name);
+ }
+
+ Module *Parent;
+ // Note: VC++ treats enums as signed, so an extra bit is required to prevent
+ // Linkage and Visibility from turning into negative values.
+ LinkageTypes Linkage : 5; // The linkage of this global
+ unsigned Visibility : 2; // The visibility style of this global
+ unsigned Alignment : 16; // Alignment of this symbol, must be power of two
+ std::string Section; // Section to emit this into, empty mean default
+public:
+ ~GlobalValue() {
+ removeDeadConstantUsers(); // remove any dead constants using this.
+ }
+
+ unsigned getAlignment() const { return Alignment; }
+ void setAlignment(unsigned Align) {
+ assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ Alignment = Align;
+ }
+
+ VisibilityTypes getVisibility() const { return (VisibilityTypes)Visibility; }
+ bool hasHiddenVisibility() const { return Visibility == HiddenVisibility; }
+ bool hasProtectedVisibility() const {
+ return Visibility == ProtectedVisibility;
+ }
+ void setVisibility(VisibilityTypes V) { Visibility = V; }
+
+ bool hasSection() const { return !Section.empty(); }
+ const std::string &getSection() const { return Section; }
+ void setSection(const std::string &S) { Section = S; }
+
+ /// If the usage is empty (except transitively dead constants), then this
+ /// global value can can be safely deleted since the destructor will
+ /// delete the dead constants as well.
+ /// @brief Determine if the usage of this global value is empty except
+ /// for transitively dead constants.
+ bool use_empty_except_constants();
+
+ /// getType - Global values are always pointers.
+ inline const PointerType *getType() const {
+ return reinterpret_cast<const PointerType*>(User::getType());
+ }
+
+ bool hasExternalLinkage() const { return Linkage == ExternalLinkage; }
+ bool hasLinkOnceLinkage() const { return Linkage == LinkOnceLinkage; }
+ bool hasWeakLinkage() const { return Linkage == WeakLinkage; }
+ bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; }
+ bool hasInternalLinkage() const { return Linkage == InternalLinkage; }
+ bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; }
+ bool hasDLLExportLinkage() const { return Linkage == DLLExportLinkage; }
+ bool hasExternalWeakLinkage() const { return Linkage == ExternalWeakLinkage; }
+ void setLinkage(LinkageTypes LT) { Linkage = LT; }
+ LinkageTypes getLinkage() const { return Linkage; }
+
+ /// hasNotBeenReadFromBitcode - If a module provider is being used to lazily
+ /// stream in functions from disk, this method can be used to check to see if
+ /// the function has been read in yet or not. Unless you are working on the
+ /// JIT or something else that streams stuff in lazily, you don't need to
+ /// worry about this.
+ bool hasNotBeenReadFromBitcode() const { return Linkage == GhostLinkage; }
+
+ /// Override from Constant class. No GlobalValue's are null values so this
+ /// always returns false.
+ virtual bool isNullValue() const { return false; }
+
+ /// Override from Constant class.
+ virtual void destroyConstant();
+
+ /// isDeclaration - Return true if the primary definition of this global
+ /// value is outside of the current translation unit...
+ virtual bool isDeclaration() const = 0;
+
+ /// getParent - Get the module that this global value is contained inside
+ /// of...
+ inline Module *getParent() { return Parent; }
+ inline const Module *getParent() const { return Parent; }
+
+ /// removeDeadConstantUsers - If there are any dead constant users dangling
+ /// off of this global value, remove them. This method is useful for clients
+ /// that want to check to see if a global is unused, but don't want to deal
+ /// with potentially dead constants hanging off of the globals.
+ void removeDeadConstantUsers();
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const GlobalValue *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::FunctionVal ||
+ V->getValueID() == Value::GlobalVariableVal ||
+ V->getValueID() == Value::GlobalAliasVal;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h
new file mode 100644
index 0000000..00d4acb
--- /dev/null
+++ b/include/llvm/GlobalVariable.h
@@ -0,0 +1,139 @@
+//===-- llvm/GlobalVariable.h - GlobalVariable class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the GlobalVariable class, which
+// represents a single global variable (or constant) in the VM.
+//
+// Global variables are constant pointers that refer to hunks of space that are
+// allocated by either the VM, or by the linker in a static compiler. A global
+// variable may have an intial value, which is copied into the executables .data
+// area. Global Constants are required to have initializers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_GLOBAL_VARIABLE_H
+#define LLVM_GLOBAL_VARIABLE_H
+
+#include "llvm/GlobalValue.h"
+
+namespace llvm {
+
+class Module;
+class Constant;
+class PointerType;
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+class GlobalVariable : public GlobalValue {
+ friend class SymbolTableListTraits<GlobalVariable, Module>;
+ void operator=(const GlobalVariable &); // Do not implement
+ GlobalVariable(const GlobalVariable &); // Do not implement
+
+ void setParent(Module *parent);
+
+ GlobalVariable *Prev, *Next;
+ void setNext(GlobalVariable *N) { Next = N; }
+ void setPrev(GlobalVariable *N) { Prev = N; }
+
+ bool isConstantGlobal : 1; // Is this a global constant?
+ bool isThreadLocalSymbol : 1; // Is this symbol "Thread Local"?
+ Use Initializer;
+
+public:
+ /// GlobalVariable ctor - If a parent module is specified, the global is
+ /// automatically inserted into the end of the specified modules global list.
+ GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
+ Constant *Initializer = 0, const std::string &Name = "",
+ Module *Parent = 0, bool ThreadLocal = false);
+ /// GlobalVariable ctor - This creates a global and inserts it before the
+ /// specified other global.
+ GlobalVariable(const Type *Ty, bool isConstant, LinkageTypes Linkage,
+ Constant *Initializer, const std::string &Name,
+ GlobalVariable *InsertBefore, bool ThreadLocal = false);
+
+ /// isDeclaration - Is this global variable lacking an initializer? If so,
+ /// the global variable is defined in some other translation unit, and is thus
+ /// only a declaration here.
+ virtual bool isDeclaration() const { return getNumOperands() == 0; }
+
+ /// hasInitializer - Unless a global variable isExternal(), it has an
+ /// initializer. The initializer for the global variable/constant is held by
+ /// Initializer if an initializer is specified.
+ ///
+ inline bool hasInitializer() const { return !isDeclaration(); }
+
+ /// getInitializer - Return the initializer for this global variable. It is
+ /// illegal to call this method if the global is external, because we cannot
+ /// tell what the value is initialized to!
+ ///
+ inline Constant *getInitializer() const {
+ assert(hasInitializer() && "GV doesn't have initializer!");
+ return reinterpret_cast<Constant*>(Initializer.get());
+ }
+ inline Constant *getInitializer() {
+ assert(hasInitializer() && "GV doesn't have initializer!");
+ return reinterpret_cast<Constant*>(Initializer.get());
+ }
+ inline void setInitializer(Constant *CPV) {
+ if (CPV == 0) {
+ if (hasInitializer()) {
+ Initializer.set(0);
+ NumOperands = 0;
+ }
+ } else {
+ if (!hasInitializer())
+ NumOperands = 1;
+ Initializer.set(CPV);
+ }
+ }
+
+ /// If the value is a global constant, its value is immutable throughout the
+ /// runtime execution of the program. Assigning a value into the constant
+ /// leads to undefined behavior.
+ ///
+ bool isConstant() const { return isConstantGlobal; }
+ void setConstant(bool Value) { isConstantGlobal = Value; }
+
+ /// If the value is "Thread Local", its value isn't shared by the threads.
+ bool isThreadLocal() const { return isThreadLocalSymbol; }
+ void setThreadLocal(bool Value) { isThreadLocalSymbol = Value; }
+
+ /// removeFromParent - This method unlinks 'this' from the containing module,
+ /// but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing module
+ /// and deletes it.
+ ///
+ void eraseFromParent();
+
+ /// Override Constant's implementation of this method so we can
+ /// replace constant initializers.
+ virtual void replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U);
+
+ virtual void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const GlobalVariable *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::GlobalVariableVal;
+ }
+private:
+ // getNext/Prev - Return the next or previous global variable in the list.
+ GlobalVariable *getNext() { return Next; }
+ const GlobalVariable *getNext() const { return Next; }
+ GlobalVariable *getPrev() { return Prev; }
+ const GlobalVariable *getPrev() const { return Prev; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/InlineAsm.h b/include/llvm/InlineAsm.h
new file mode 100644
index 0000000..20c184ac
--- /dev/null
+++ b/include/llvm/InlineAsm.h
@@ -0,0 +1,138 @@
+//===-- llvm/InlineAsm.h - Class to represent inline asm strings-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents the inline asm strings, which are Value*'s that are
+// used as the callee operand of call instructions. InlineAsm's are uniqued
+// like constants, and created via InlineAsm::get(...).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INLINEASM_H
+#define LLVM_INLINEASM_H
+
+#include "llvm/Value.h"
+#include "llvm/System/IncludeFile.h"
+#include <vector>
+
+namespace llvm {
+
+struct AssemblyAnnotationWriter;
+class PointerType;
+class FunctionType;
+class Module;
+
+class InlineAsm : public Value {
+ InlineAsm(const InlineAsm &); // do not implement
+ void operator=(const InlineAsm&); // do not implement
+
+ std::string AsmString, Constraints;
+ bool HasSideEffects;
+
+ InlineAsm(const FunctionType *Ty, const std::string &AsmString,
+ const std::string &Constraints, bool hasSideEffects);
+ virtual ~InlineAsm();
+public:
+
+ /// InlineAsm::get - Return the the specified uniqued inline asm string.
+ ///
+ static InlineAsm *get(const FunctionType *Ty, const std::string &AsmString,
+ const std::string &Constraints, bool hasSideEffects);
+
+ bool hasSideEffects() const { return HasSideEffects; }
+
+ /// getType - InlineAsm's are always pointers.
+ ///
+ const PointerType *getType() const {
+ return reinterpret_cast<const PointerType*>(Value::getType());
+ }
+
+ /// getFunctionType - InlineAsm's are always pointers to functions.
+ ///
+ const FunctionType *getFunctionType() const;
+
+ const std::string &getAsmString() const { return AsmString; }
+ const std::string &getConstraintString() const { return Constraints; }
+
+ virtual void print(std::ostream &O) const { print(O, 0); }
+ void print(std::ostream *O) const { if (O) print(*O); }
+ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+ /// Verify - This static method can be used by the parser to check to see if
+ /// the specified constraint string is legal for the type. This returns true
+ /// if legal, false if not.
+ ///
+ static bool Verify(const FunctionType *Ty, const std::string &Constraints);
+
+ // Constraint String Parsing
+ enum ConstraintPrefix {
+ isInput, // 'x'
+ isOutput, // '=x'
+ isClobber // '~x'
+ };
+
+ struct ConstraintInfo {
+ /// Type - The basic type of the constraint: input/output/clobber
+ ///
+ ConstraintPrefix Type;
+
+ /// isEarlyClobber - "&": output operand writes result before inputs are all
+ /// read. This is only ever set for an output operand.
+ bool isEarlyClobber;
+
+ /// hasMatchingInput - This is set to true for an output constraint iff
+ /// there is an input constraint that is required to match it (e.g. "0").
+ bool hasMatchingInput;
+
+ /// isCommutative - This is set to true for a constraint that is commutative
+ /// with the next operand.
+ bool isCommutative;
+
+ /// isIndirect - True if this operand is an indirect operand. This means
+ /// that the address of the source or destination is present in the call
+ /// instruction, instead of it being returned or passed in explicitly. This
+ /// is represented with a '*' in the asm string.
+ bool isIndirect;
+
+ /// Code - The constraint code, either the register name (in braces) or the
+ /// constraint letter/number.
+ std::vector<std::string> Codes;
+
+ /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
+ /// fields in this structure. If the constraint string is not understood,
+ /// return true, otherwise return false.
+ bool Parse(const std::string &Str,
+ std::vector<InlineAsm::ConstraintInfo> &ConstraintsSoFar);
+ };
+
+ /// ParseConstraints - Split up the constraint string into the specific
+ /// constraints and their prefixes. If this returns an empty vector, and if
+ /// the constraint string itself isn't empty, there was an error parsing.
+ static std::vector<ConstraintInfo>
+ ParseConstraints(const std::string &ConstraintString);
+
+ /// ParseConstraints - Parse the constraints of this inlineasm object,
+ /// returning them the same way that ParseConstraints(str) does.
+ std::vector<ConstraintInfo>
+ ParseConstraints() const {
+ return ParseConstraints(Constraints);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const InlineAsm *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() == Value::InlineAsmVal;
+ }
+};
+
+} // End llvm namespace
+
+// Make sure the InlineAsm.cpp file is linked when this one is #included.
+FORCE_DEFINING_FILE_TO_BE_LINKED(InlineAsm)
+
+#endif
diff --git a/include/llvm/InstrTypes.h b/include/llvm/InstrTypes.h
new file mode 100644
index 0000000..d96b20f
--- /dev/null
+++ b/include/llvm/InstrTypes.h
@@ -0,0 +1,569 @@
+//===-- llvm/InstrTypes.h - Important Instruction subclasses ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various meta classes of instructions that exist in the VM
+// representation. Specific concrete subclasses of these may be found in the
+// i*.h files...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INSTRUCTION_TYPES_H
+#define LLVM_INSTRUCTION_TYPES_H
+
+#include "llvm/Instruction.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// TerminatorInst Class
+//===----------------------------------------------------------------------===//
+
+/// TerminatorInst - Subclasses of this class are all able to terminate a basic
+/// block. Thus, these are all the flow control type of operations.
+///
+class TerminatorInst : public Instruction {
+protected:
+ TerminatorInst(const Type *Ty, Instruction::TermOps iType,
+ Use *Ops, unsigned NumOps,
+ Instruction *InsertBefore = 0)
+ : Instruction(Ty, iType, Ops, NumOps, InsertBefore) {}
+
+ TerminatorInst(const Type *Ty, Instruction::TermOps iType,
+ Use *Ops, unsigned NumOps, BasicBlock *InsertAtEnd)
+ : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {}
+
+ // Out of line virtual method, so the vtable, etc has a home.
+ ~TerminatorInst();
+
+ /// Virtual methods - Terminators should overload these and provide inline
+ /// overrides of non-V methods.
+ virtual BasicBlock *getSuccessorV(unsigned idx) const = 0;
+ virtual unsigned getNumSuccessorsV() const = 0;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0;
+public:
+
+ virtual Instruction *clone() const = 0;
+
+ /// getNumSuccessors - Return the number of successors that this terminator
+ /// has.
+ unsigned getNumSuccessors() const {
+ return getNumSuccessorsV();
+ }
+
+ /// getSuccessor - Return the specified successor.
+ ///
+ BasicBlock *getSuccessor(unsigned idx) const {
+ return getSuccessorV(idx);
+ }
+
+ /// setSuccessor - Update the specified successor to point at the provided
+ /// block.
+ void setSuccessor(unsigned idx, BasicBlock *B) {
+ setSuccessorV(idx, B);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const TerminatorInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() >= TermOpsBegin && I->getOpcode() < TermOpsEnd;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// UnaryInstruction Class
+//===----------------------------------------------------------------------===//
+
+class UnaryInstruction : public Instruction {
+ Use Op;
+protected:
+ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB =0)
+ : Instruction(Ty, iType, &Op, 1, IB), Op(V, this) {
+ }
+ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
+ : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this) {
+ }
+public:
+ // Out of line virtual method, so the vtable, etc has a home.
+ ~UnaryInstruction();
+
+ // Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i == 0 && "getOperand() out of range!");
+ return Op;
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i == 0 && "setOperand() out of range!");
+ Op = Val;
+ }
+ unsigned getNumOperands() const { return 1; }
+};
+
+//===----------------------------------------------------------------------===//
+// BinaryOperator Class
+//===----------------------------------------------------------------------===//
+
+class BinaryOperator : public Instruction {
+ Use Ops[2];
+protected:
+ void init(BinaryOps iType);
+ BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
+ const std::string &Name, Instruction *InsertBefore);
+ BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+public:
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 2 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 2 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 2; }
+
+ /// create() - Construct a binary instruction, given the opcode and the two
+ /// operands. Optionally (if InstBefore is specified) insert the instruction
+ /// into a BasicBlock right before the specified instruction. The specified
+ /// Instruction is allowed to be a dereferenced end iterator.
+ ///
+ static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2,
+ const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+
+ /// create() - Construct a binary instruction, given the opcode and the two
+ /// operands. Also automatically insert this instruction to the end of the
+ /// BasicBlock specified.
+ ///
+ static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2,
+ const std::string &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// create* - These methods just forward to create, and are useful when you
+ /// statically know what type of instruction you're going to create. These
+ /// helpers just save some typing.
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+ static BinaryOperator *create##OPC(Value *V1, Value *V2, \
+ const std::string &Name = "") {\
+ return create(Instruction::OPC, V1, V2, Name);\
+ }
+#include "llvm/Instruction.def"
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+ static BinaryOperator *create##OPC(Value *V1, Value *V2, \
+ const std::string &Name, BasicBlock *BB) {\
+ return create(Instruction::OPC, V1, V2, Name, BB);\
+ }
+#include "llvm/Instruction.def"
+#define HANDLE_BINARY_INST(N, OPC, CLASS) \
+ static BinaryOperator *create##OPC(Value *V1, Value *V2, \
+ const std::string &Name, Instruction *I) {\
+ return create(Instruction::OPC, V1, V2, Name, I);\
+ }
+#include "llvm/Instruction.def"
+
+
+ /// Helper functions to construct and inspect unary operations (NEG and NOT)
+ /// via binary operators SUB and XOR:
+ ///
+ /// createNeg, createNot - Create the NEG and NOT
+ /// instructions out of SUB and XOR instructions.
+ ///
+ static BinaryOperator *createNeg(Value *Op, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *createNeg(Value *Op, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+ static BinaryOperator *createNot(Value *Op, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ static BinaryOperator *createNot(Value *Op, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// isNeg, isNot - Check if the given Value is a NEG or NOT instruction.
+ ///
+ static bool isNeg(const Value *V);
+ static bool isNot(const Value *V);
+
+ /// getNegArgument, getNotArgument - Helper functions to extract the
+ /// unary argument of a NEG or NOT operation implemented via Sub or Xor.
+ ///
+ static const Value *getNegArgument(const Value *BinOp);
+ static Value *getNegArgument( Value *BinOp);
+ static const Value *getNotArgument(const Value *BinOp);
+ static Value *getNotArgument( Value *BinOp);
+
+ BinaryOps getOpcode() const {
+ return static_cast<BinaryOps>(Instruction::getOpcode());
+ }
+
+ virtual BinaryOperator *clone() const;
+
+ /// swapOperands - Exchange the two operands to this instruction.
+ /// This instruction is safe to use on any binary instruction and
+ /// does not modify the semantics of the instruction. If the
+ /// instruction is order dependent (SetLT f.e.) the opcode is
+ /// changed. If the instruction cannot be reversed (ie, it's a Div),
+ /// then return true.
+ ///
+ bool swapOperands();
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BinaryOperator *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() >= BinaryOpsBegin && I->getOpcode() < BinaryOpsEnd;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// CastInst Class
+//===----------------------------------------------------------------------===//
+
+/// CastInst - This is the base class for all instructions that perform data
+/// casts. It is simply provided so that instruction category testing
+/// can be performed with code like:
+///
+/// if (isa<CastInst>(Instr)) { ... }
+/// @brief Base class of casting instructions.
+class CastInst : public UnaryInstruction {
+ /// @brief Copy constructor
+ CastInst(const CastInst &CI)
+ : UnaryInstruction(CI.getType(), CI.getOpcode(), CI.getOperand(0)) {
+ }
+ /// @brief Do not allow default construction
+ CastInst();
+protected:
+ /// @brief Constructor with insert-before-instruction semantics for subclasses
+ CastInst(const Type *Ty, unsigned iType, Value *S,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, iType, S, InsertBefore) {
+ setName(Name);
+ }
+ /// @brief Constructor with insert-at-end-of-block semantics for subclasses
+ CastInst(const Type *Ty, unsigned iType, Value *S,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, iType, S, InsertAtEnd) {
+ setName(Name);
+ }
+public:
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category (Instruction::isCast(opcode) returns true). This
+ /// constructor has insert-before-instruction semantics to automatically
+ /// insert the new CastInst before InsertBefore (if it is non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *create(
+ Instruction::CastOps, ///< The opcode of the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+ /// Provides a way to construct any of the CastInst subclasses using an
+ /// opcode instead of the subclass's constructor. The opcode must be in the
+ /// CastOps category. This constructor has insert-at-end-of-block semantics
+ /// to automatically insert the new CastInst at the end of InsertAtEnd (if
+ /// its non-null).
+ /// @brief Construct any of the CastInst subclasses
+ static CastInst *create(
+ Instruction::CastOps, ///< The opcode for the cast instruction
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *createZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt or BitCast cast instruction
+ static CastInst *createZExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *createSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast instruction
+ static CastInst *createPointerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a BitCast or a PtrToInt cast instruction
+ static CastInst *createPointerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+ static CastInst *createIntegerCast(
+ Value *S, ///< The pointer value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ bool isSigned, ///< Whether to regard S as signed or not
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts.
+ static CastInst *createIntegerCast(
+ Value *S, ///< The integer value to be casted (operand 0)
+ const Type *Ty, ///< The integer type to which operand is casted
+ bool isSigned, ///< Whether to regard S as signed or not
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+ static CastInst *createFPCast(
+ Value *S, ///< The floating point value to be casted
+ const Type *Ty, ///< The floating point type to cast to
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create an FPExt, BitCast, or FPTrunc for fp -> fp casts
+ static CastInst *createFPCast(
+ Value *S, ///< The floating point value to be casted
+ const Type *Ty, ///< The floating point type to cast to
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a SExt or BitCast cast instruction
+ static CastInst *createSExtOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *createTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which cast should be made
+ const std::string &Name = "", ///< Name for the instruction
+ Instruction *InsertBefore = 0 ///< Place to insert the instruction
+ );
+
+ /// @brief Create a Trunc or BitCast cast instruction
+ static CastInst *createTruncOrBitCast(
+ Value *S, ///< The value to be casted (operand 0)
+ const Type *Ty, ///< The type to which operand is casted
+ const std::string &Name, ///< The name for the instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// Returns the opcode necessary to cast Val into Ty using usual casting
+ /// rules.
+ /// @brief Infer the opcode for cast operand and type
+ static Instruction::CastOps getCastOpcode(
+ const Value *Val, ///< The value to cast
+ bool SrcIsSigned, ///< Whether to treat the source as signed
+ const Type *Ty, ///< The Type to which the value should be casted
+ bool DstIsSigned ///< Whether to treate the dest. as signed
+ );
+
+ /// There are several places where we need to know if a cast instruction
+ /// only deals with integer source and destination types. To simplify that
+ /// logic, this method is provided.
+ /// @returns true iff the cast has only integral typed operand and dest type.
+ /// @brief Determine if this is an integer-only cast.
+ bool isIntegerCast() const;
+
+ /// A lossless cast is one that does not alter the basic value. It implies
+ /// a no-op cast but is more stringent, preventing things like int->float,
+ /// long->double, int->ptr, or vector->anything.
+ /// @returns true iff the cast is lossless.
+ /// @brief Determine if this is a lossless cast.
+ bool isLosslessCast() const;
+
+ /// A no-op cast is one that can be effected without changing any bits.
+ /// It implies that the source and destination types are the same size. The
+ /// IntPtrTy argument is used to make accurate determinations for casts
+ /// involving Integer and Pointer types. They are no-op casts if the integer
+ /// is the same size as the pointer. However, pointer size varies with
+ /// platform. Generally, the result of TargetData::getIntPtrType() should be
+ /// passed in. If that's not available, use Type::Int64Ty, which will make
+ /// the isNoopCast call conservative.
+ /// @brief Determine if this cast is a no-op cast.
+ bool isNoopCast(
+ const Type *IntPtrTy ///< Integer type corresponding to pointer
+ ) 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.
+ /// @returns 0 if the CastInst pair can't be eliminated
+ /// @returns Instruction::CastOps value for a cast that can replace
+ /// the pair, casting SrcTy to DstTy.
+ /// @brief Determine if a cast pair is eliminable
+ static unsigned isEliminableCastPair(
+ Instruction::CastOps firstOpcode, ///< Opcode of first cast
+ Instruction::CastOps secondOpcode, ///< Opcode of second cast
+ const Type *SrcTy, ///< SrcTy of 1st cast
+ const Type *MidTy, ///< DstTy of 1st cast & SrcTy of 2nd cast
+ const Type *DstTy, ///< DstTy of 2nd cast
+ const Type *IntPtrTy ///< Integer type corresponding to Ptr types
+ );
+
+ /// @brief Return the opcode of this CastInst
+ Instruction::CastOps getOpcode() const {
+ return Instruction::CastOps(Instruction::getOpcode());
+ }
+
+ /// @brief Return the source type, as a convenience
+ const Type* getSrcTy() const { return getOperand(0)->getType(); }
+ /// @brief Return the destination type, as a convenience
+ const Type* getDestTy() const { return getType(); }
+
+ /// This method can be used to determine if a cast from S to DstTy using
+ /// Opcode op is valid or not.
+ /// @returns true iff the proposed cast is valid.
+ /// @brief Determine if a cast is valid without creating one.
+ static bool castIsValid(Instruction::CastOps op, Value *S, const Type *DstTy);
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CastInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class is the base class for the comparison instructions.
+/// @brief Abstract base class of comparison instructions.
+class CmpInst: public Instruction {
+ CmpInst(); // do not implement
+protected:
+ CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+ const std::string &Name = "", Instruction *InsertBefore = 0);
+
+ CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
+
+public:
+ /// Construct a compare instruction, given the opcode, the predicate and
+ /// the two operands. Optionally (if InstBefore is specified) insert the
+ /// instruction into a BasicBlock right before the specified instruction.
+ /// The specified Instruction is allowed to be a dereferenced end iterator.
+ /// @brief Create a CmpInst
+ static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
+ Value *S2, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+
+ /// Construct a compare instruction, given the opcode, the predicate and the
+ /// two operands. Also automatically insert this instruction to the end of
+ /// the BasicBlock specified.
+ /// @brief Create a CmpInst
+ static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
+ Value *S2, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// @brief Implement superclass method.
+ virtual CmpInst *clone() const;
+
+ /// @brief Get the opcode casted to the right type
+ OtherOps getOpcode() const {
+ return static_cast<OtherOps>(Instruction::getOpcode());
+ }
+
+ /// The predicate for CmpInst is defined by the subclasses but stored in
+ /// the SubclassData field (see Value.h). We allow it to be fetched here
+ /// as the predicate but there is no enum type for it, just the raw unsigned
+ /// short. This facilitates comparison of CmpInst instances without delving
+ /// into the subclasses since predicate values are distinct between the
+ /// CmpInst subclasses.
+ /// @brief Return the predicate for this instruction.
+ unsigned short getPredicate() const {
+ return SubclassData;
+ }
+
+ /// @brief Provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 2 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 2 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+
+ /// @brief CmpInst instructions always have 2 operands.
+ unsigned getNumOperands() const { return 2; }
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Swap the operands and adjust predicate accordingly to retain
+ /// the same comparison.
+ void swapOperands();
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this CmpInst is commutative.
+ bool isCommutative();
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this is an equals/not equals predicate.
+ bool isEquality();
+
+ /// @returns true if the predicate is unsigned, false otherwise.
+ /// @brief Determine if the predicate is an unsigned operation.
+ static bool isUnsigned(unsigned short predicate);
+
+ /// @returns true if the predicate is signed, false otherwise.
+ /// @brief Determine if the predicate is an signed operation.
+ static bool isSigned(unsigned short predicate);
+
+ /// @brief Determine if the predicate is an ordered operation.
+ static bool isOrdered(unsigned short predicate);
+
+ /// @brief Determine if the predicate is an unordered operation.
+ static bool isUnordered(unsigned short predicate);
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ICmp ||
+ I->getOpcode() == Instruction::FCmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def
new file mode 100644
index 0000000..41540c2
--- /dev/null
+++ b/include/llvm/Instruction.def
@@ -0,0 +1,191 @@
+//===-- llvm/Instruction.def - File that describes Instructions -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains descriptions of the various LLVM instructions. This is
+// used as a central place for enumerating the different instructions and
+// should eventually be the place to put comments about the instructions.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+// Provide definitions of macros so that users of this file do not have to
+// define everything to use it...
+//
+#ifndef FIRST_TERM_INST
+#define FIRST_TERM_INST(num)
+#endif
+#ifndef HANDLE_TERM_INST
+#ifndef HANDLE_INST
+#define HANDLE_TERM_INST(num, opcode, Class)
+#else
+#define HANDLE_TERM_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_TERM_INST
+#define LAST_TERM_INST(num)
+#endif
+
+#ifndef FIRST_BINARY_INST
+#define FIRST_BINARY_INST(num)
+#endif
+#ifndef HANDLE_BINARY_INST
+#ifndef HANDLE_INST
+#define HANDLE_BINARY_INST(num, opcode, instclass)
+#else
+#define HANDLE_BINARY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_BINARY_INST
+#define LAST_BINARY_INST(num)
+#endif
+
+#ifndef FIRST_MEMORY_INST
+#define FIRST_MEMORY_INST(num)
+#endif
+#ifndef HANDLE_MEMORY_INST
+#ifndef HANDLE_INST
+#define HANDLE_MEMORY_INST(num, opcode, Class)
+#else
+#define HANDLE_MEMORY_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_MEMORY_INST
+#define LAST_MEMORY_INST(num)
+#endif
+
+#ifndef FIRST_CAST_INST
+#define FIRST_CAST_INST(num)
+#endif
+#ifndef HANDLE_CAST_INST
+#ifndef HANDLE_INST
+#define HANDLE_CAST_INST(num, opcode, Class)
+#else
+#define HANDLE_CAST_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_CAST_INST
+#define LAST_CAST_INST(num)
+#endif
+
+#ifndef FIRST_OTHER_INST
+#define FIRST_OTHER_INST(num)
+#endif
+#ifndef HANDLE_OTHER_INST
+#ifndef HANDLE_INST
+#define HANDLE_OTHER_INST(num, opcode, Class)
+#else
+#define HANDLE_OTHER_INST(num, opcode, Class) HANDLE_INST(num, opcode, Class)
+#endif
+#endif
+#ifndef LAST_OTHER_INST
+#define LAST_OTHER_INST(num)
+#endif
+
+
+// Terminator Instructions - These instructions are used to terminate a basic
+// block of the program. Every basic block must end with one of these
+// instructions for it to be a well formed basic block.
+//
+ FIRST_TERM_INST ( 1)
+HANDLE_TERM_INST ( 1, Ret , ReturnInst)
+HANDLE_TERM_INST ( 2, Br , BranchInst)
+HANDLE_TERM_INST ( 3, Switch , SwitchInst)
+HANDLE_TERM_INST ( 4, Invoke , InvokeInst)
+HANDLE_TERM_INST ( 5, Unwind , UnwindInst)
+HANDLE_TERM_INST ( 6, Unreachable, UnreachableInst)
+ LAST_TERM_INST ( 6)
+
+// Standard binary operators...
+ FIRST_BINARY_INST( 7)
+HANDLE_BINARY_INST( 7, Add , BinaryOperator)
+HANDLE_BINARY_INST( 8, Sub , BinaryOperator)
+HANDLE_BINARY_INST( 9, Mul , BinaryOperator)
+HANDLE_BINARY_INST(10, UDiv , BinaryOperator)
+HANDLE_BINARY_INST(11, SDiv , BinaryOperator)
+HANDLE_BINARY_INST(12, FDiv , BinaryOperator)
+HANDLE_BINARY_INST(13, URem , BinaryOperator)
+HANDLE_BINARY_INST(14, SRem , BinaryOperator)
+HANDLE_BINARY_INST(15, FRem , BinaryOperator)
+
+// Logical operators (integer operands)
+HANDLE_BINARY_INST(16, Shl , BinaryOperator) // Shift left (logical)
+HANDLE_BINARY_INST(17, LShr , BinaryOperator) // Shift right (logical)
+HANDLE_BINARY_INST(18, AShr , BinaryOperator) // shift right (arithmetic)
+HANDLE_BINARY_INST(19, And , BinaryOperator)
+HANDLE_BINARY_INST(20, Or , BinaryOperator)
+HANDLE_BINARY_INST(21, Xor , BinaryOperator)
+ LAST_BINARY_INST(21)
+
+// Memory operators...
+ FIRST_MEMORY_INST(22)
+HANDLE_MEMORY_INST(22, Malloc, MallocInst) // Heap management instructions
+HANDLE_MEMORY_INST(23, Free , FreeInst )
+HANDLE_MEMORY_INST(24, Alloca, AllocaInst) // Stack management
+HANDLE_MEMORY_INST(25, Load , LoadInst ) // Memory manipulation instrs
+HANDLE_MEMORY_INST(26, Store , StoreInst )
+HANDLE_MEMORY_INST(27, GetElementPtr, GetElementPtrInst)
+ LAST_MEMORY_INST(27)
+
+// Cast operators ...
+// NOTE: The order matters here because CastInst::isEliminableCastPair
+// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
+ FIRST_CAST_INST(28)
+HANDLE_CAST_INST(28, Trunc , TruncInst ) // Truncate integers
+HANDLE_CAST_INST(29, ZExt , ZExtInst ) // Zero extend integers
+HANDLE_CAST_INST(30, SExt , SExtInst ) // Sign extend integers
+HANDLE_CAST_INST(31, FPToUI , FPToUIInst ) // floating point -> UInt
+HANDLE_CAST_INST(32, FPToSI , FPToSIInst ) // floating point -> SInt
+HANDLE_CAST_INST(33, UIToFP , UIToFPInst ) // UInt -> floating point
+HANDLE_CAST_INST(34, SIToFP , SIToFPInst ) // SInt -> floating point
+HANDLE_CAST_INST(35, FPTrunc , FPTruncInst ) // Truncate floating point
+HANDLE_CAST_INST(36, FPExt , FPExtInst ) // Extend floating point
+HANDLE_CAST_INST(37, PtrToInt, PtrToIntInst) // Pointer -> Integer
+HANDLE_CAST_INST(38, IntToPtr, IntToPtrInst) // Integer -> Pointer
+HANDLE_CAST_INST(39, BitCast , BitCastInst ) // Type cast
+ LAST_CAST_INST(39)
+
+// Other operators...
+ FIRST_OTHER_INST(40)
+HANDLE_OTHER_INST(40, ICmp , ICmpInst ) // Integer comparison instruction
+HANDLE_OTHER_INST(41, FCmp , FCmpInst ) // Floating point comparison instr.
+HANDLE_OTHER_INST(42, PHI , PHINode ) // PHI node instruction
+HANDLE_OTHER_INST(43, Call , CallInst ) // Call a function
+HANDLE_OTHER_INST(44, Select , SelectInst ) // select instruction
+HANDLE_OTHER_INST(45, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_OTHER_INST(46, UserOp2, Instruction) // Internal to passes only
+HANDLE_OTHER_INST(47, VAArg , VAArgInst ) // vaarg instruction
+HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector.
+HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector
+HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
+ LAST_OTHER_INST(50)
+
+#undef FIRST_TERM_INST
+#undef HANDLE_TERM_INST
+#undef LAST_TERM_INST
+
+#undef FIRST_BINARY_INST
+#undef HANDLE_BINARY_INST
+#undef LAST_BINARY_INST
+
+#undef FIRST_MEMORY_INST
+#undef HANDLE_MEMORY_INST
+#undef LAST_MEMORY_INST
+
+#undef FIRST_CAST_INST
+#undef HANDLE_CAST_INST
+#undef LAST_CAST_INST
+
+#undef FIRST_OTHER_INST
+#undef HANDLE_OTHER_INST
+#undef LAST_OTHER_INST
+
+#ifdef HANDLE_INST
+#undef HANDLE_INST
+#endif
diff --git a/include/llvm/Instruction.h b/include/llvm/Instruction.h
new file mode 100644
index 0000000..8da89e2
--- /dev/null
+++ b/include/llvm/Instruction.h
@@ -0,0 +1,239 @@
+//===-- llvm/Instruction.h - Instruction class definition -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declaration of the Instruction class, which is the
+// base class for all of the LLVM instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INSTRUCTION_H
+#define LLVM_INSTRUCTION_H
+
+#include "llvm/User.h"
+
+namespace llvm {
+
+struct AssemblyAnnotationWriter;
+class BinaryOperator;
+
+template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+
+class Instruction : public User {
+ void operator=(const Instruction &); // Do not implement
+ Instruction(const Instruction &); // Do not implement
+
+ BasicBlock *Parent;
+ Instruction *Prev, *Next; // Next and Prev links for our intrusive linked list
+
+ void setNext(Instruction *N) { Next = N; }
+ void setPrev(Instruction *N) { Prev = N; }
+
+ friend class SymbolTableListTraits<Instruction, BasicBlock>;
+ void setParent(BasicBlock *P);
+protected:
+ Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+ Instruction *InsertBefore = 0);
+ Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
+ BasicBlock *InsertAtEnd);
+public:
+ // Out of line virtual method, so the vtable, etc has a home.
+ ~Instruction();
+
+ /// mayWriteToMemory - Return true if this instruction may modify memory.
+ ///
+ bool mayWriteToMemory() const;
+
+ /// clone() - Create a copy of 'this' instruction that is identical in all
+ /// ways except the following:
+ /// * The instruction has no parent
+ /// * The instruction has no name
+ ///
+ virtual Instruction *clone() const = 0;
+
+ /// isIdenticalTo - Return true if the specified instruction is exactly
+ /// identical to the current one. This means that all operands match and any
+ /// extra information (e.g. load is volatile) agree.
+ bool isIdenticalTo(Instruction *I) const;
+
+ /// This function determines if the specified instruction executes the same
+ /// operation as the current one. This means that the opcodes, type, operand
+ /// types and any other factors affecting the operation must be the same. This
+ /// is similar to isIdenticalTo except the operands themselves don't have to
+ /// be identical.
+ /// @returns true if the specified instruction is the same operation as
+ /// the current one.
+ /// @brief Determine if one instruction is the same operation as another.
+ bool isSameOperationAs(Instruction *I) const;
+
+ /// use_back - Specialize the methods defined in Value, as we know that an
+ /// instruction can only be used by other instructions.
+ Instruction *use_back() { return cast<Instruction>(*use_begin());}
+ const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
+
+ // Accessor methods...
+ //
+ inline const BasicBlock *getParent() const { return Parent; }
+ inline BasicBlock *getParent() { return Parent; }
+
+ /// removeFromParent - This method unlinks 'this' from the containing basic
+ /// block, but does not delete it.
+ ///
+ void removeFromParent();
+
+ /// eraseFromParent - This method unlinks 'this' from the containing basic
+ /// block and deletes it.
+ ///
+ void eraseFromParent();
+
+ /// moveBefore - Unlink this instruction from its current basic block and
+ /// insert it into the basic block that MovePos lives in, right before
+ /// MovePos.
+ void moveBefore(Instruction *MovePos);
+
+ // ---------------------------------------------------------------------------
+ /// Subclass classification... getOpcode() returns a member of
+ /// one of the enums that is coming soon (down below)...
+ ///
+ unsigned getOpcode() const { return getValueID() - InstructionVal; }
+ const char *getOpcodeName() const {
+ return getOpcodeName(getOpcode());
+ }
+ static const char* getOpcodeName(unsigned OpCode);
+
+ static inline bool isTerminator(unsigned OpCode) {
+ return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
+ }
+
+ inline bool isTerminator() const { // Instance of TerminatorInst?
+ return isTerminator(getOpcode());
+ }
+
+ inline bool isBinaryOp() const {
+ return getOpcode() >= BinaryOpsBegin && getOpcode() < BinaryOpsEnd;
+ }
+
+ /// @brief Determine if the Opcode is one of the shift instructions.
+ static inline bool isShift(unsigned Opcode) {
+ return Opcode >= Shl && Opcode <= AShr;
+ }
+
+ /// @brief Determine if the instruction's opcode is one of the shift
+ /// instructions.
+ inline bool isShift() { return isShift(getOpcode()); }
+
+ /// isLogicalShift - Return true if this is a logical shift left or a logical
+ /// shift right.
+ inline bool isLogicalShift() {
+ return getOpcode() == Shl || getOpcode() == LShr;
+ }
+
+ /// isLogicalShift - Return true if this is a logical shift left or a logical
+ /// shift right.
+ inline bool isArithmeticShift() {
+ return getOpcode() == AShr;
+ }
+
+ /// @brief Determine if the OpCode is one of the CastInst instructions.
+ static inline bool isCast(unsigned OpCode) {
+ return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
+ }
+
+ /// @brief Determine if this is one of the CastInst instructions.
+ inline bool isCast() const {
+ return isCast(getOpcode());
+ }
+
+ /// isAssociative - Return true if the instruction is associative:
+ ///
+ /// Associative operators satisfy: x op (y op z) === (x op y) op z
+ ///
+ /// In LLVM, the Add, Mul, And, Or, and Xor operators are associative, when
+ /// not applied to floating point types.
+ ///
+ bool isAssociative() const { return isAssociative(getOpcode(), getType()); }
+ static bool isAssociative(unsigned op, const Type *Ty);
+
+ /// isCommutative - Return true if the instruction is commutative:
+ ///
+ /// Commutative operators satisfy: (x op y) === (y op x)
+ ///
+ /// In LLVM, these are the associative operators, plus SetEQ and SetNE, when
+ /// applied to any type.
+ ///
+ bool isCommutative() const { return isCommutative(getOpcode()); }
+ static bool isCommutative(unsigned op);
+
+ /// isTrappingInstruction - Return true if the instruction may trap.
+ ///
+ bool isTrapping() const {
+ return isTrapping(getOpcode());
+ }
+ static bool isTrapping(unsigned op);
+
+ virtual void print(std::ostream &OS) const { print(OS, 0); }
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *) { return true; }
+ static inline bool classof(const Value *V) {
+ return V->getValueID() >= Value::InstructionVal;
+ }
+
+ //----------------------------------------------------------------------
+ // Exported enumerations...
+ //
+ enum TermOps { // These terminate basic blocks
+#define FIRST_TERM_INST(N) TermOpsBegin = N,
+#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N,
+#define LAST_TERM_INST(N) TermOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
+ enum BinaryOps {
+#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
+#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
+#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
+ enum MemoryOps {
+#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N,
+#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N,
+#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
+ enum CastOps {
+#define FIRST_CAST_INST(N) CastOpsBegin = N,
+#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
+#define LAST_CAST_INST(N) CastOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
+ enum OtherOps {
+#define FIRST_OTHER_INST(N) OtherOpsBegin = N,
+#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
+#define LAST_OTHER_INST(N) OtherOpsEnd = N+1
+#include "llvm/Instruction.def"
+ };
+
+private:
+ // getNext/Prev - Return the next or previous instruction in the list. The
+ // last node in the list is a terminator instruction.
+ Instruction *getNext() { return Next; }
+ const Instruction *getNext() const { return Next; }
+ Instruction *getPrev() { return Prev; }
+ const Instruction *getPrev() const { return Prev; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
new file mode 100644
index 0000000..b501b8e
--- /dev/null
+++ b/include/llvm/Instructions.h
@@ -0,0 +1,2112 @@
+//===-- llvm/Instructions.h - Instruction subclass definitions --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes the class definitions of all of the subclasses of the
+// Instruction class. This is meant to be an easy way to get access to all
+// instruction subclasses.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INSTRUCTIONS_H
+#define LLVM_INSTRUCTIONS_H
+
+#include "llvm/InstrTypes.h"
+
+namespace llvm {
+
+class BasicBlock;
+class ConstantInt;
+class PointerType;
+class VectorType;
+class ConstantRange;
+class APInt;
+class ParamAttrsList;
+
+//===----------------------------------------------------------------------===//
+// AllocationInst Class
+//===----------------------------------------------------------------------===//
+
+/// AllocationInst - This class is the common base class of MallocInst and
+/// AllocaInst.
+///
+class AllocationInst : public UnaryInstruction {
+ unsigned Alignment;
+protected:
+ AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align,
+ const std::string &Name = "", Instruction *InsertBefore = 0);
+ AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, unsigned Align,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+public:
+ // Out of line virtual method, so the vtable, etc has a home.
+ virtual ~AllocationInst();
+
+ /// isArrayAllocation - Return true if there is an allocation size parameter
+ /// to the allocation instruction that is not 1.
+ ///
+ bool isArrayAllocation() const;
+
+ /// getArraySize - Get the number of element allocated, for a simple
+ /// allocation of a single element, this will return a constant 1 value.
+ ///
+ inline const Value *getArraySize() const { return getOperand(0); }
+ inline Value *getArraySize() { return getOperand(0); }
+
+ /// getType - Overload to return most specific pointer type
+ ///
+ inline const PointerType *getType() const {
+ return reinterpret_cast<const PointerType*>(Instruction::getType());
+ }
+
+ /// getAllocatedType - Return the type that is being allocated by the
+ /// instruction.
+ ///
+ const Type *getAllocatedType() const;
+
+ /// getAlignment - Return the alignment of the memory that is being allocated
+ /// by the instruction.
+ ///
+ unsigned getAlignment() const { return Alignment; }
+ void setAlignment(unsigned Align) {
+ assert((Align & (Align-1)) == 0 && "Alignment is not a power of 2!");
+ Alignment = Align;
+ }
+
+ virtual Instruction *clone() const = 0;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const AllocationInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Alloca ||
+ I->getOpcode() == Instruction::Malloc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// MallocInst Class
+//===----------------------------------------------------------------------===//
+
+/// MallocInst - an instruction to allocated memory on the heap
+///
+class MallocInst : public AllocationInst {
+ MallocInst(const MallocInst &MI);
+public:
+ explicit MallocInst(const Type *Ty, Value *ArraySize = 0,
+ const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertBefore) {}
+ MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name,
+ BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, ArraySize, Malloc, 0, Name, InsertAtEnd) {}
+
+ MallocInst(const Type *Ty, const std::string &Name,
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, 0, Malloc, 0, Name, InsertBefore) {}
+ MallocInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, 0, Malloc, 0, Name, InsertAtEnd) {}
+
+ MallocInst(const Type *Ty, Value *ArraySize, unsigned Align,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertAtEnd) {}
+ MallocInst(const Type *Ty, Value *ArraySize, unsigned Align,
+ const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Malloc, Align, Name, InsertBefore) {}
+
+ virtual MallocInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MallocInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Malloc);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// AllocaInst Class
+//===----------------------------------------------------------------------===//
+
+/// AllocaInst - an instruction to allocate memory on the stack
+///
+class AllocaInst : public AllocationInst {
+ AllocaInst(const AllocaInst &);
+public:
+ explicit AllocaInst(const Type *Ty, Value *ArraySize = 0,
+ const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertBefore) {}
+ AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name,
+ BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, ArraySize, Alloca, 0, Name, InsertAtEnd) {}
+
+ AllocaInst(const Type *Ty, const std::string &Name,
+ Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, 0, Alloca, 0, Name, InsertBefore) {}
+ AllocaInst(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, 0, Alloca, 0, Name, InsertAtEnd) {}
+
+ AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align,
+ const std::string &Name = "", Instruction *InsertBefore = 0)
+ : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertBefore) {}
+ AllocaInst(const Type *Ty, Value *ArraySize, unsigned Align,
+ const std::string &Name, BasicBlock *InsertAtEnd)
+ : AllocationInst(Ty, ArraySize, Alloca, Align, Name, InsertAtEnd) {}
+
+ virtual AllocaInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const AllocaInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Alloca);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// FreeInst Class
+//===----------------------------------------------------------------------===//
+
+/// FreeInst - an instruction to deallocate memory
+///
+class FreeInst : public UnaryInstruction {
+ void AssertOK();
+public:
+ explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
+ FreeInst(Value *Ptr, BasicBlock *InsertAfter);
+
+ virtual FreeInst *clone() const;
+
+ // Accessor methods for consistency with other memory operations
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FreeInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Free);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// LoadInst Class
+//===----------------------------------------------------------------------===//
+
+/// LoadInst - an instruction for reading from memory. This uses the
+/// SubclassData field in Value to store whether or not the load is volatile.
+///
+class LoadInst : public UnaryInstruction {
+
+ LoadInst(const LoadInst &LI)
+ : UnaryInstruction(LI.getType(), Load, LI.getOperand(0)) {
+ setVolatile(LI.isVolatile());
+ setAlignment(LI.getAlignment());
+
+#ifndef NDEBUG
+ AssertOK();
+#endif
+ }
+ void AssertOK();
+public:
+ LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore);
+ LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile, unsigned Align,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
+ BasicBlock *InsertAtEnd);
+
+ LoadInst(Value *Ptr, const char *Name, Instruction *InsertBefore);
+ LoadInst(Value *Ptr, const char *Name, BasicBlock *InsertAtEnd);
+ explicit LoadInst(Value *Ptr, const char *Name = 0, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ LoadInst(Value *Ptr, const char *Name, bool isVolatile,
+ BasicBlock *InsertAtEnd);
+
+ /// isVolatile - Return true if this is a load from a volatile memory
+ /// location.
+ ///
+ bool isVolatile() const { return SubclassData & 1; }
+
+ /// setVolatile - Specify whether this is a volatile load or not.
+ ///
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ }
+
+ virtual LoadInst *clone() const;
+
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
+ Value *getPointerOperand() { return getOperand(0); }
+ const Value *getPointerOperand() const { return getOperand(0); }
+ static unsigned getPointerOperandIndex() { return 0U; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const LoadInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Load;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// StoreInst Class
+//===----------------------------------------------------------------------===//
+
+/// StoreInst - an instruction for storing to memory
+///
+class StoreInst : public Instruction {
+ Use Ops[2];
+
+ StoreInst(const StoreInst &SI) : Instruction(SI.getType(), Store, Ops, 2) {
+ Ops[0].init(SI.Ops[0], this);
+ Ops[1].init(SI.Ops[1], this);
+ setVolatile(SI.isVolatile());
+ setAlignment(SI.getAlignment());
+
+#ifndef NDEBUG
+ AssertOK();
+#endif
+ }
+ void AssertOK();
+public:
+ StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
+ StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
+ Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile,
+ unsigned Align, Instruction *InsertBefore = 0);
+ StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
+
+
+ /// isVolatile - Return true if this is a load from a volatile memory
+ /// location.
+ ///
+ bool isVolatile() const { return SubclassData & 1; }
+
+ /// setVolatile - Specify whether this is a volatile load or not.
+ ///
+ void setVolatile(bool V) {
+ SubclassData = (SubclassData & ~1) | ((V) ? 1 : 0);
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 2 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 2 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 2; }
+
+ /// getAlignment - Return the alignment of the access that is being performed
+ ///
+ unsigned getAlignment() const {
+ return (1 << (SubclassData>>1)) >> 1;
+ }
+
+ void setAlignment(unsigned Align);
+
+ virtual StoreInst *clone() const;
+
+ Value *getPointerOperand() { return getOperand(1); }
+ const Value *getPointerOperand() const { return getOperand(1); }
+ static unsigned getPointerOperandIndex() { return 1U; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const StoreInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Store;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// GetElementPtrInst Class
+//===----------------------------------------------------------------------===//
+
+/// GetElementPtrInst - an instruction for type-safe pointer arithmetic to
+/// access elements of arrays and structs
+///
+class GetElementPtrInst : public Instruction {
+ GetElementPtrInst(const GetElementPtrInst &GEPI)
+ : Instruction(reinterpret_cast<const Type*>(GEPI.getType()), GetElementPtr,
+ 0, GEPI.getNumOperands()) {
+ Use *OL = OperandList = new Use[NumOperands];
+ Use *GEPIOL = GEPI.OperandList;
+ for (unsigned i = 0, E = NumOperands; i != E; ++i)
+ OL[i].init(GEPIOL[i], this);
+ }
+ void init(Value *Ptr, Value* const *Idx, unsigned NumIdx);
+ void init(Value *Ptr, Value *Idx0, Value *Idx1);
+ void init(Value *Ptr, Value *Idx);
+public:
+ /// Constructors - Create a getelementptr instruction with a base pointer an
+ /// list of indices. The first ctor can optionally insert before an existing
+ /// instruction, the second appends the new instruction to the specified
+ /// BasicBlock.
+ GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
+ const std::string &Name = "", Instruction *InsertBefore =0);
+ GetElementPtrInst(Value *Ptr, Value* const *Idx, unsigned NumIdx,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ /// Constructors - These two constructors are convenience methods because one
+ /// and two index getelementptr instructions are so common.
+ GetElementPtrInst(Value *Ptr, Value *Idx,
+ const std::string &Name = "", Instruction *InsertBefore =0);
+ GetElementPtrInst(Value *Ptr, Value *Idx,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+ GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
+ const std::string &Name = "", Instruction *InsertBefore =0);
+ GetElementPtrInst(Value *Ptr, Value *Idx0, Value *Idx1,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+ ~GetElementPtrInst();
+
+ virtual GetElementPtrInst *clone() const;
+
+ // getType - Overload to return most specific pointer type...
+ inline const PointerType *getType() const {
+ return reinterpret_cast<const PointerType*>(Instruction::getType());
+ }
+
+ /// getIndexedType - Returns the type of the element that would be loaded with
+ /// a load instruction with the specified parameters.
+ ///
+ /// A null type is returned if the indices are invalid for the specified
+ /// pointer type.
+ ///
+ static const Type *getIndexedType(const Type *Ptr,
+ Value* const *Idx, unsigned NumIdx,
+ bool AllowStructLeaf = false);
+
+ static const Type *getIndexedType(const Type *Ptr, Value *Idx0, Value *Idx1,
+ bool AllowStructLeaf = false);
+ static const Type *getIndexedType(const Type *Ptr, Value *Idx);
+
+ inline op_iterator idx_begin() { return op_begin()+1; }
+ inline const_op_iterator idx_begin() const { return op_begin()+1; }
+ inline op_iterator idx_end() { return op_end(); }
+ inline const_op_iterator idx_end() const { return op_end(); }
+
+ Value *getPointerOperand() {
+ return getOperand(0);
+ }
+ const Value *getPointerOperand() const {
+ return getOperand(0);
+ }
+ static unsigned getPointerOperandIndex() {
+ return 0U; // get index for modifying correct operand
+ }
+
+ inline unsigned getNumIndices() const { // Note: always non-negative
+ return getNumOperands() - 1;
+ }
+
+ inline bool hasIndices() const {
+ return getNumOperands() > 1;
+ }
+
+ /// hasAllZeroIndices - Return true if all of the indices of this GEP are
+ /// zeros. If so, the result pointer and the first operand have the same
+ /// value, just potentially different types.
+ bool hasAllZeroIndices() const;
+
+ /// hasAllConstantIndices - Return true if all of the indices of this GEP are
+ /// constant integers. If so, the result pointer and the first operand have
+ /// a constant offset between them.
+ bool hasAllConstantIndices() const;
+
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const GetElementPtrInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::GetElementPtr);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on integers, pointers, or packed
+/// vectors of integrals. The two operands must be the same type.
+/// @brief Represent an integer comparison operator.
+class ICmpInst: public CmpInst {
+public:
+ /// This enumeration lists the possible predicates for the ICmpInst. The
+ /// values in the range 0-31 are reserved for FCmpInst while values in the
+ /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+ /// predicate values are not overlapping between the classes.
+ enum Predicate {
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
+ FIRST_ICMP_PREDICATE = ICMP_EQ,
+ LAST_ICMP_PREDICATE = ICMP_SLE,
+ BAD_ICMP_PREDICATE = ICMP_SLE + 1
+ };
+
+ /// @brief Constructor with insert-before-instruction semantics.
+ ICmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name = "", ///< Name of the instruction
+ Instruction *InsertBefore = 0 ///< Where to insert
+ ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertBefore) {
+ }
+
+ /// @brief Constructor with insert-at-block-end semantics.
+ ICmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name, ///< Name of the instruction
+ BasicBlock *InsertAtEnd ///< Block to insert into.
+ ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertAtEnd) {
+ }
+
+ /// @brief Return the predicate for this instruction.
+ Predicate getPredicate() const { return Predicate(SubclassData); }
+
+ /// @brief Set the predicate for this instruction to the specified value.
+ void setPredicate(Predicate P) { SubclassData = P; }
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+ /// @returns the inverse predicate for the instruction's current predicate.
+ /// @brief Return the inverse of the instruction's predicate.
+ Predicate getInversePredicate() const {
+ return getInversePredicate(getPredicate());
+ }
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+ /// @returns the inverse predicate for predicate provided in \p pred.
+ /// @brief Return the inverse of a given predicate
+ static Predicate getInversePredicate(Predicate pred);
+
+ /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
+ /// @returns the predicate that would be the result of exchanging the two
+ /// operands of the ICmpInst instruction without changing the result
+ /// produced.
+ /// @brief Return the predicate as if the operands were swapped
+ Predicate getSwappedPredicate() const {
+ return getSwappedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @brief Return the predicate as if the operands were swapped.
+ static Predicate getSwappedPredicate(Predicate pred);
+
+ /// For example, EQ->EQ, SLE->SLE, UGT->SGT, etc.
+ /// @returns the predicate that would be the result if the operand were
+ /// regarded as signed.
+ /// @brief Return the signed version of the predicate
+ Predicate getSignedPredicate() const {
+ return getSignedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction.
+ /// @brief Return the signed version of the predicate.
+ static Predicate getSignedPredicate(Predicate pred);
+
+ /// This also tests for commutativity. If isEquality() returns true then
+ /// the predicate is also commutative.
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// @brief Determine if this is an equality predicate.
+ bool isEquality() const {
+ return SubclassData == ICMP_EQ || SubclassData == ICMP_NE;
+ }
+
+ /// @returns true if the predicate of this ICmpInst is commutative
+ /// @brief Determine if this relation is commutative.
+ bool isCommutative() const { return isEquality(); }
+
+ /// @returns true if the predicate is relational (not EQ or NE).
+ /// @brief Determine if this a relational predicate.
+ bool isRelational() const {
+ return !isEquality();
+ }
+
+ /// @returns true if the predicate of this ICmpInst is signed, false otherwise
+ /// @brief Determine if this instruction's predicate is signed.
+ bool isSignedPredicate() { return isSignedPredicate(getPredicate()); }
+
+ /// @returns true if the predicate provided is signed, false otherwise
+ /// @brief Determine if the predicate is signed.
+ static bool isSignedPredicate(Predicate pred);
+
+ /// Initialize a set of values that all satisfy the predicate with C.
+ /// @brief Make a ConstantRange for a relation with a constant value.
+ static ConstantRange makeConstantRange(Predicate pred, const APInt &C);
+
+ /// Exchange the two operands to this instruction in such a way that it does
+ /// not modify the semantics of the instruction. The predicate value may be
+ /// changed to retain the same result if the predicate is order dependent
+ /// (e.g. ult).
+ /// @brief Swap operands and adjust predicate.
+ void swapOperands() {
+ SubclassData = getSwappedPredicate();
+ std::swap(Ops[0], Ops[1]);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ICmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ICmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on floating point values or packed
+/// vectors of floating point values. The operands must be identical types.
+/// @brief Represents a floating point comparison operator.
+class FCmpInst: public CmpInst {
+public:
+ /// This enumeration lists the possible predicates for the FCmpInst. Values
+ /// in the range 0-31 are reserved for FCmpInst.
+ enum Predicate {
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT =10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE =11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT =12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE =13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded)
+ FIRST_FCMP_PREDICATE = FCMP_FALSE,
+ LAST_FCMP_PREDICATE = FCMP_TRUE,
+ BAD_FCMP_PREDICATE = FCMP_TRUE + 1
+ };
+
+ /// @brief Constructor with insert-before-instruction semantics.
+ FCmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name = "", ///< Name of the instruction
+ Instruction *InsertBefore = 0 ///< Where to insert
+ ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertBefore) {
+ }
+
+ /// @brief Constructor with insert-at-block-end semantics.
+ FCmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name, ///< Name of the instruction
+ BasicBlock *InsertAtEnd ///< Block to insert into.
+ ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertAtEnd) {
+ }
+
+ /// @brief Return the predicate for this instruction.
+ Predicate getPredicate() const { return Predicate(SubclassData); }
+
+ /// @brief Set the predicate for this instruction to the specified value.
+ void setPredicate(Predicate P) { SubclassData = P; }
+
+ /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for the instructions current predicate.
+ /// @brief Return the inverse of the predicate
+ Predicate getInversePredicate() const {
+ return getInversePredicate(getPredicate());
+ }
+
+ /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for \p pred.
+ /// @brief Return the inverse of a given predicate
+ static Predicate getInversePredicate(Predicate pred);
+
+ /// For example, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
+ /// @returns the predicate that would be the result of exchanging the two
+ /// operands of the ICmpInst instruction without changing the result
+ /// produced.
+ /// @brief Return the predicate as if the operands were swapped
+ Predicate getSwappedPredicate() const {
+ return getSwappedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @brief Return the predicate as if the operands were swapped.
+ static Predicate getSwappedPredicate(Predicate Opcode);
+
+ /// This also tests for commutativity. If isEquality() returns true then
+ /// the predicate is also commutative. Only the equality predicates are
+ /// commutative.
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// @brief Determine if this is an equality predicate.
+ bool isEquality() const {
+ return SubclassData == FCMP_OEQ || SubclassData == FCMP_ONE ||
+ SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE;
+ }
+ bool isCommutative() const { return isEquality(); }
+
+ /// @returns true if the predicate is relational (not EQ or NE).
+ /// @brief Determine if this a relational predicate.
+ bool isRelational() const { return !isEquality(); }
+
+ /// Exchange the two operands to this instruction in such a way that it does
+ /// not modify the semantics of the instruction. The predicate value may be
+ /// changed to retain the same result if the predicate is order dependent
+ /// (e.g. ult).
+ /// @brief Swap operands and adjust predicate.
+ void swapOperands() {
+ SubclassData = getSwappedPredicate();
+ std::swap(Ops[0], Ops[1]);
+ }
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FCmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::FCmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// CallInst Class
+//===----------------------------------------------------------------------===//
+
+/// CallInst - This class represents a function call, abstracting a target
+/// machine's calling convention. This class uses low bit of the SubClassData
+/// field to indicate whether or not this is a tail call. The rest of the bits
+/// hold the calling convention of the call.
+///
+class CallInst : public Instruction {
+ ParamAttrsList *ParamAttrs; ///< parameter attributes for call
+ CallInst(const CallInst &CI);
+ void init(Value *Func, Value* const *Params, unsigned NumParams);
+ void init(Value *Func, Value *Actual1, Value *Actual2);
+ void init(Value *Func, Value *Actual);
+ void init(Value *Func);
+
+public:
+ CallInst(Value *F, Value* const *Args, unsigned NumArgs,
+ const std::string &Name = "", Instruction *InsertBefore = 0);
+ CallInst(Value *F, Value *const *Args, unsigned NumArgs,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ // Alternate CallInst ctors w/ two actuals, w/ one actual and no
+ // actuals, respectively.
+ CallInst(Value *F, Value *Actual1, Value *Actual2,
+ const std::string& Name = "", Instruction *InsertBefore = 0);
+ CallInst(Value *F, Value *Actual1, Value *Actual2,
+ const std::string& Name, BasicBlock *InsertAtEnd);
+ CallInst(Value *F, Value *Actual, const std::string& Name = "",
+ Instruction *InsertBefore = 0);
+ CallInst(Value *F, Value *Actual, const std::string& Name,
+ BasicBlock *InsertAtEnd);
+ explicit CallInst(Value *F, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ CallInst(Value *F, const std::string &Name, BasicBlock *InsertAtEnd);
+ ~CallInst();
+
+ virtual CallInst *clone() const;
+
+ bool isTailCall() const { return SubclassData & 1; }
+ void setTailCall(bool isTailCall = true) {
+ SubclassData = (SubclassData & ~1) | unsigned(isTailCall);
+ }
+
+ /// getCallingConv/setCallingConv - Get or set the calling convention of this
+ /// function call.
+ unsigned getCallingConv() const { return SubclassData >> 1; }
+ void setCallingConv(unsigned CC) {
+ SubclassData = (SubclassData & 1) | (CC << 1);
+ }
+
+ /// Obtains a pointer to the ParamAttrsList object which holds the
+ /// parameter attributes information, if any.
+ /// @returns 0 if no attributes have been set.
+ /// @brief Get the parameter attributes.
+ ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ /// Sets the parameter attributes for this CallInst. To construct a
+ /// ParamAttrsList, see ParameterAttributes.h
+ /// @brief Set the parameter attributes.
+ void setParamAttrs(ParamAttrsList *attrs);
+
+ /// getCalledFunction - Return the function being called by this instruction
+ /// if it is a direct call. If it is a call through a function pointer,
+ /// return null.
+ Function *getCalledFunction() const {
+ return static_cast<Function*>(dyn_cast<Function>(getOperand(0)));
+ }
+
+ /// getCalledValue - Get a pointer to the function that is invoked by this
+ /// instruction
+ inline const Value *getCalledValue() const { return getOperand(0); }
+ inline Value *getCalledValue() { return getOperand(0); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CallInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Call;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SelectInst Class
+//===----------------------------------------------------------------------===//
+
+/// SelectInst - This class represents the LLVM 'select' instruction.
+///
+class SelectInst : public Instruction {
+ Use Ops[3];
+
+ void init(Value *C, Value *S1, Value *S2) {
+ Ops[0].init(C, this);
+ Ops[1].init(S1, this);
+ Ops[2].init(S2, this);
+ }
+
+ SelectInst(const SelectInst &SI)
+ : Instruction(SI.getType(), SI.getOpcode(), Ops, 3) {
+ init(SI.Ops[0], SI.Ops[1], SI.Ops[2]);
+ }
+public:
+ SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertBefore) {
+ init(C, S1, S2);
+ setName(Name);
+ }
+ SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name,
+ BasicBlock *InsertAtEnd)
+ : Instruction(S1->getType(), Instruction::Select, Ops, 3, InsertAtEnd) {
+ init(C, S1, S2);
+ setName(Name);
+ }
+
+ Value *getCondition() const { return Ops[0]; }
+ Value *getTrueValue() const { return Ops[1]; }
+ Value *getFalseValue() const { return Ops[2]; }
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 3 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 3 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 3; }
+
+ OtherOps getOpcode() const {
+ return static_cast<OtherOps>(Instruction::getOpcode());
+ }
+
+ virtual SelectInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SelectInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Select;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// VAArgInst Class
+//===----------------------------------------------------------------------===//
+
+/// VAArgInst - This class represents the va_arg llvm instruction, which returns
+/// an argument of the specified type given a va_list and increments that list
+///
+class VAArgInst : public UnaryInstruction {
+ VAArgInst(const VAArgInst &VAA)
+ : UnaryInstruction(VAA.getType(), VAArg, VAA.getOperand(0)) {}
+public:
+ VAArgInst(Value *List, const Type *Ty, const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : UnaryInstruction(Ty, VAArg, List, InsertBefore) {
+ setName(Name);
+ }
+ VAArgInst(Value *List, const Type *Ty, const std::string &Name,
+ BasicBlock *InsertAtEnd)
+ : UnaryInstruction(Ty, VAArg, List, InsertAtEnd) {
+ setName(Name);
+ }
+
+ virtual VAArgInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const VAArgInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == VAArg;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ExtractElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// ExtractElementInst - This instruction extracts a single (scalar)
+/// element from a VectorType value
+///
+class ExtractElementInst : public Instruction {
+ Use Ops[2];
+ ExtractElementInst(const ExtractElementInst &EE) :
+ Instruction(EE.getType(), ExtractElement, Ops, 2) {
+ Ops[0].init(EE.Ops[0], this);
+ Ops[1].init(EE.Ops[1], this);
+ }
+
+public:
+ ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ ExtractElementInst(Value *Vec, Value *Idx, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+ ExtractElementInst(Value *Vec, unsigned Idx, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// isValidOperands - Return true if an extractelement instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *Vec, const Value *Idx);
+
+ virtual ExtractElementInst *clone() const;
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 2 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 2 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 2; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ExtractElementInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ExtractElement;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// InsertElementInst Class
+//===----------------------------------------------------------------------===//
+
+/// InsertElementInst - This instruction inserts a single (scalar)
+/// element into a VectorType value
+///
+class InsertElementInst : public Instruction {
+ Use Ops[3];
+ InsertElementInst(const InsertElementInst &IE);
+public:
+ InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+ const std::string &Name = "",Instruction *InsertBefore = 0);
+ InsertElementInst(Value *Vec, Value *NewElt, unsigned Idx,
+ const std::string &Name = "",Instruction *InsertBefore = 0);
+ InsertElementInst(Value *Vec, Value *NewElt, Value *Idx,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+ InsertElementInst(Value *Vec, Value *NewElt, unsigned Idx,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ /// isValidOperands - Return true if an insertelement instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *Vec, const Value *NewElt,
+ const Value *Idx);
+
+ virtual InsertElementInst *clone() const;
+
+ /// getType - Overload to return most specific vector type.
+ ///
+ inline const VectorType *getType() const {
+ return reinterpret_cast<const VectorType*>(Instruction::getType());
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 3 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 3 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 3; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const InsertElementInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::InsertElement;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ShuffleVectorInst Class
+//===----------------------------------------------------------------------===//
+
+/// ShuffleVectorInst - This instruction constructs a fixed permutation of two
+/// input vectors.
+///
+class ShuffleVectorInst : public Instruction {
+ Use Ops[3];
+ ShuffleVectorInst(const ShuffleVectorInst &IE);
+public:
+ ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const std::string &Name = "", Instruction *InsertBefor = 0);
+ ShuffleVectorInst(Value *V1, Value *V2, Value *Mask,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ /// isValidOperands - Return true if a shufflevector instruction can be
+ /// formed with the specified operands.
+ static bool isValidOperands(const Value *V1, const Value *V2,
+ const Value *Mask);
+
+ virtual ShuffleVectorInst *clone() const;
+
+ /// getType - Overload to return most specific vector type.
+ ///
+ inline const VectorType *getType() const {
+ return reinterpret_cast<const VectorType*>(Instruction::getType());
+ }
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 3 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 3 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+ unsigned getNumOperands() const { return 3; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ShuffleVectorInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ShuffleVector;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// PHINode Class
+//===----------------------------------------------------------------------===//
+
+// PHINode - The PHINode class is used to represent the magical mystical PHI
+// node, that can not exist in nature, but can be synthesized in a computer
+// scientist's overactive imagination.
+//
+class PHINode : public Instruction {
+ /// ReservedSpace - The number of operands actually allocated. NumOperands is
+ /// the number actually in use.
+ unsigned ReservedSpace;
+ PHINode(const PHINode &PN);
+public:
+ explicit PHINode(const Type *Ty, const std::string &Name = "",
+ Instruction *InsertBefore = 0)
+ : Instruction(Ty, Instruction::PHI, 0, 0, InsertBefore),
+ ReservedSpace(0) {
+ setName(Name);
+ }
+
+ PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
+ : Instruction(Ty, Instruction::PHI, 0, 0, InsertAtEnd),
+ ReservedSpace(0) {
+ setName(Name);
+ }
+
+ ~PHINode();
+
+ /// reserveOperandSpace - This method can be used to avoid repeated
+ /// reallocation of PHI operand lists by reserving space for the correct
+ /// number of operands before adding them. Unlike normal vector reserves,
+ /// this method can also be used to trim the operand space.
+ void reserveOperandSpace(unsigned NumValues) {
+ resizeOperands(NumValues*2);
+ }
+
+ virtual PHINode *clone() const;
+
+ /// getNumIncomingValues - Return the number of incoming edges
+ ///
+ unsigned getNumIncomingValues() const { return getNumOperands()/2; }
+
+ /// getIncomingValue - Return incoming value number x
+ ///
+ Value *getIncomingValue(unsigned i) const {
+ assert(i*2 < getNumOperands() && "Invalid value number!");
+ return getOperand(i*2);
+ }
+ void setIncomingValue(unsigned i, Value *V) {
+ assert(i*2 < getNumOperands() && "Invalid value number!");
+ setOperand(i*2, V);
+ }
+ unsigned getOperandNumForIncomingValue(unsigned i) {
+ return i*2;
+ }
+
+ /// getIncomingBlock - Return incoming basic block number x
+ ///
+ BasicBlock *getIncomingBlock(unsigned i) const {
+ return reinterpret_cast<BasicBlock*>(getOperand(i*2+1));
+ }
+ void setIncomingBlock(unsigned i, BasicBlock *BB) {
+ setOperand(i*2+1, reinterpret_cast<Value*>(BB));
+ }
+ unsigned getOperandNumForIncomingBlock(unsigned i) {
+ return i*2+1;
+ }
+
+ /// addIncoming - Add an incoming value to the end of the PHI list
+ ///
+ void addIncoming(Value *V, BasicBlock *BB) {
+ assert(getType() == V->getType() &&
+ "All operands to PHI node must be the same type as the PHI node!");
+ unsigned OpNo = NumOperands;
+ if (OpNo+2 > ReservedSpace)
+ resizeOperands(0); // Get more space!
+ // Initialize some new operands.
+ NumOperands = OpNo+2;
+ OperandList[OpNo].init(V, this);
+ OperandList[OpNo+1].init(reinterpret_cast<Value*>(BB), this);
+ }
+
+ /// removeIncomingValue - Remove an incoming value. This is useful if a
+ /// predecessor basic block is deleted. The value removed is returned.
+ ///
+ /// If the last incoming value for a PHI node is removed (and DeletePHIIfEmpty
+ /// is true), the PHI node is destroyed and any uses of it are replaced with
+ /// dummy values. The only time there should be zero incoming values to a PHI
+ /// node is when the block is dead, so this strategy is sound.
+ ///
+ Value *removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty = true);
+
+ Value *removeIncomingValue(const BasicBlock *BB, bool DeletePHIIfEmpty =true){
+ int Idx = getBasicBlockIndex(BB);
+ assert(Idx >= 0 && "Invalid basic block argument to remove!");
+ return removeIncomingValue(Idx, DeletePHIIfEmpty);
+ }
+
+ /// getBasicBlockIndex - Return the first index of the specified basic
+ /// block in the value list for this PHI. Returns -1 if no instance.
+ ///
+ int getBasicBlockIndex(const BasicBlock *BB) const {
+ Use *OL = OperandList;
+ for (unsigned i = 0, e = getNumOperands(); i != e; i += 2)
+ if (OL[i+1] == reinterpret_cast<const Value*>(BB)) return i/2;
+ return -1;
+ }
+
+ Value *getIncomingValueForBlock(const BasicBlock *BB) const {
+ return getIncomingValue(getBasicBlockIndex(BB));
+ }
+
+ /// hasConstantValue - If the specified PHI node always merges together the
+ /// same value, return the value, otherwise return null.
+ ///
+ Value *hasConstantValue(bool AllowNonDominatingInstruction = false) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const PHINode *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::PHI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+ private:
+ void resizeOperands(unsigned NumOperands);
+};
+
+//===----------------------------------------------------------------------===//
+// ReturnInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// ReturnInst - Return a value (possibly void), from a function. Execution
+/// does not continue in this function any longer.
+///
+class ReturnInst : public TerminatorInst {
+ Use RetVal; // Return Value: null if 'void'.
+ ReturnInst(const ReturnInst &RI);
+ void init(Value *RetVal);
+
+public:
+ // ReturnInst constructors:
+ // ReturnInst() - 'ret void' instruction
+ // ReturnInst( null) - 'ret void' instruction
+ // ReturnInst(Value* X) - 'ret X' instruction
+ // ReturnInst( null, Inst *) - 'ret void' instruction, insert before I
+ // ReturnInst(Value* X, Inst *I) - 'ret X' instruction, insert before I
+ // ReturnInst( null, BB *B) - 'ret void' instruction, insert @ end of BB
+ // ReturnInst(Value* X, BB *B) - 'ret X' instruction, insert @ end of BB
+ //
+ // NOTE: If the Value* passed is of type void then the constructor behaves as
+ // if it was passed NULL.
+ explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0);
+ ReturnInst(Value *retVal, BasicBlock *InsertAtEnd);
+ explicit ReturnInst(BasicBlock *InsertAtEnd);
+
+ virtual ReturnInst *clone() const;
+
+ // Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return RetVal;
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < getNumOperands() && "setOperand() out of range!");
+ RetVal = Val;
+ }
+
+ Value *getReturnValue() const { return RetVal; }
+
+ unsigned getNumSuccessors() const { return 0; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ReturnInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Ret);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+ private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// BranchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// BranchInst - Conditional or Unconditional Branch instruction.
+///
+class BranchInst : public TerminatorInst {
+ /// Ops list - Branches are strange. The operands are ordered:
+ /// TrueDest, FalseDest, Cond. This makes some accessors faster because
+ /// they don't have to check for cond/uncond branchness.
+ Use Ops[3];
+ BranchInst(const BranchInst &BI);
+ void AssertOK();
+public:
+ // BranchInst constructors (where {B, T, F} are blocks, and C is a condition):
+ // BranchInst(BB *B) - 'br B'
+ // BranchInst(BB* T, BB *F, Value *C) - 'br C, T, F'
+ // BranchInst(BB* B, Inst *I) - 'br B' insert before I
+ // BranchInst(BB* T, BB *F, Value *C, Inst *I) - 'br C, T, F', insert before I
+ // BranchInst(BB* B, BB *I) - 'br B' insert at end
+ // BranchInst(BB* T, BB *F, Value *C, BB *I) - 'br C, T, F', insert at end
+ explicit BranchInst(BasicBlock *IfTrue, Instruction *InsertBefore = 0);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+ Instruction *InsertBefore = 0);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *InsertAtEnd);
+ BranchInst(BasicBlock *IfTrue, BasicBlock *IfFalse, Value *Cond,
+ BasicBlock *InsertAtEnd);
+
+ /// Transparently provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < getNumOperands() && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < getNumOperands() && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+
+ virtual BranchInst *clone() const;
+
+ inline bool isUnconditional() const { return getNumOperands() == 1; }
+ inline bool isConditional() const { return getNumOperands() == 3; }
+
+ inline Value *getCondition() const {
+ assert(isConditional() && "Cannot get condition of an uncond branch!");
+ return getOperand(2);
+ }
+
+ void setCondition(Value *V) {
+ assert(isConditional() && "Cannot set condition of unconditional branch!");
+ setOperand(2, V);
+ }
+
+ // setUnconditionalDest - Change the current branch to an unconditional branch
+ // targeting the specified block.
+ // FIXME: Eliminate this ugly method.
+ void setUnconditionalDest(BasicBlock *Dest) {
+ if (isConditional()) { // Convert this to an uncond branch.
+ NumOperands = 1;
+ Ops[1].set(0);
+ Ops[2].set(0);
+ }
+ setOperand(0, reinterpret_cast<Value*>(Dest));
+ }
+
+ unsigned getNumSuccessors() const { return 1+isConditional(); }
+
+ BasicBlock *getSuccessor(unsigned i) const {
+ assert(i < getNumSuccessors() && "Successor # out of range for Branch!");
+ return cast<BasicBlock>(getOperand(i));
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
+ setOperand(idx, reinterpret_cast<Value*>(NewSucc));
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BranchInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Br);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// SwitchInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// SwitchInst - Multiway switch
+///
+class SwitchInst : public TerminatorInst {
+ unsigned ReservedSpace;
+ // Operand[0] = Value to switch on
+ // Operand[1] = Default basic block destination
+ // Operand[2n ] = Value to match
+ // Operand[2n+1] = BasicBlock to go to on match
+ SwitchInst(const SwitchInst &RI);
+ void init(Value *Value, BasicBlock *Default, unsigned NumCases);
+ void resizeOperands(unsigned No);
+public:
+ /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+ /// switch on and a default destination. The number of additional cases can
+ /// be specified here to make memory allocation more efficient. This
+ /// constructor can also autoinsert before another instruction.
+ SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+ Instruction *InsertBefore = 0);
+
+ /// SwitchInst ctor - Create a new switch instruction, specifying a value to
+ /// switch on and a default destination. The number of additional cases can
+ /// be specified here to make memory allocation more efficient. This
+ /// constructor also autoinserts at the end of the specified BasicBlock.
+ SwitchInst(Value *Value, BasicBlock *Default, unsigned NumCases,
+ BasicBlock *InsertAtEnd);
+ ~SwitchInst();
+
+
+ // Accessor Methods for Switch stmt
+ inline Value *getCondition() const { return getOperand(0); }
+ void setCondition(Value *V) { setOperand(0, V); }
+
+ inline BasicBlock *getDefaultDest() const {
+ return cast<BasicBlock>(getOperand(1));
+ }
+
+ /// getNumCases - return the number of 'cases' in this switch instruction.
+ /// Note that case #0 is always the default case.
+ unsigned getNumCases() const {
+ return getNumOperands()/2;
+ }
+
+ /// getCaseValue - Return the specified case value. Note that case #0, the
+ /// default destination, does not have a case value.
+ ConstantInt *getCaseValue(unsigned i) {
+ assert(i && i < getNumCases() && "Illegal case value to get!");
+ return getSuccessorValue(i);
+ }
+
+ /// getCaseValue - Return the specified case value. Note that case #0, the
+ /// default destination, does not have a case value.
+ const ConstantInt *getCaseValue(unsigned i) const {
+ assert(i && i < getNumCases() && "Illegal case value to get!");
+ return getSuccessorValue(i);
+ }
+
+ /// findCaseValue - Search all of the case values for the specified constant.
+ /// If it is explicitly handled, return the case number of it, otherwise
+ /// return 0 to indicate that it is handled by the default handler.
+ unsigned findCaseValue(const ConstantInt *C) const {
+ for (unsigned i = 1, e = getNumCases(); i != e; ++i)
+ if (getCaseValue(i) == C)
+ return i;
+ return 0;
+ }
+
+ /// findCaseDest - Finds the unique case value for a given successor. Returns
+ /// null if the successor is not found, not unique, or is the default case.
+ ConstantInt *findCaseDest(BasicBlock *BB) {
+ if (BB == getDefaultDest()) return NULL;
+
+ ConstantInt *CI = NULL;
+ for (unsigned i = 1, e = getNumCases(); i != e; ++i) {
+ if (getSuccessor(i) == BB) {
+ if (CI) return NULL; // Multiple cases lead to BB.
+ else CI = getCaseValue(i);
+ }
+ }
+ return CI;
+ }
+
+ /// addCase - Add an entry to the switch instruction...
+ ///
+ void addCase(ConstantInt *OnVal, BasicBlock *Dest);
+
+ /// removeCase - This method removes the specified successor from the switch
+ /// instruction. Note that this cannot be used to remove the default
+ /// destination (successor #0).
+ ///
+ void removeCase(unsigned idx);
+
+ virtual SwitchInst *clone() const;
+
+ unsigned getNumSuccessors() const { return getNumOperands()/2; }
+ BasicBlock *getSuccessor(unsigned idx) const {
+ assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
+ return cast<BasicBlock>(getOperand(idx*2+1));
+ }
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
+ setOperand(idx*2+1, reinterpret_cast<Value*>(NewSucc));
+ }
+
+ // getSuccessorValue - Return the value associated with the specified
+ // successor.
+ inline ConstantInt *getSuccessorValue(unsigned idx) const {
+ assert(idx < getNumSuccessors() && "Successor # out of range!");
+ return reinterpret_cast<ConstantInt*>(getOperand(idx*2));
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SwitchInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Switch;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// InvokeInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+
+/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the
+/// calling convention of the call.
+///
+class InvokeInst : public TerminatorInst {
+ ParamAttrsList *ParamAttrs;
+ InvokeInst(const InvokeInst &BI);
+ void init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
+ Value* const *Args, unsigned NumArgs);
+public:
+ InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
+ Value* const* Args, unsigned NumArgs, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+ InvokeInst(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
+ Value* const* Args, unsigned NumArgs, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+ ~InvokeInst();
+
+ virtual InvokeInst *clone() const;
+
+ /// getCallingConv/setCallingConv - Get or set the calling convention of this
+ /// function call.
+ unsigned getCallingConv() const { return SubclassData; }
+ void setCallingConv(unsigned CC) {
+ SubclassData = CC;
+ }
+
+ /// Obtains a pointer to the ParamAttrsList object which holds the
+ /// parameter attributes information, if any.
+ /// @returns 0 if no attributes have been set.
+ /// @brief Get the parameter attributes.
+ ParamAttrsList *getParamAttrs() const { return ParamAttrs; }
+
+ /// Sets the parameter attributes for this InvokeInst. To construct a
+ /// ParamAttrsList, see ParameterAttributes.h
+ /// @brief Set the parameter attributes.
+ void setParamAttrs(ParamAttrsList *attrs);
+
+ /// getCalledFunction - Return the function called, or null if this is an
+ /// indirect function invocation.
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(getOperand(0));
+ }
+
+ // getCalledValue - Get a pointer to a function that is invoked by this inst.
+ inline Value *getCalledValue() const { return getOperand(0); }
+
+ // get*Dest - Return the destination basic blocks...
+ BasicBlock *getNormalDest() const {
+ return cast<BasicBlock>(getOperand(1));
+ }
+ BasicBlock *getUnwindDest() const {
+ return cast<BasicBlock>(getOperand(2));
+ }
+ void setNormalDest(BasicBlock *B) {
+ setOperand(1, reinterpret_cast<Value*>(B));
+ }
+
+ void setUnwindDest(BasicBlock *B) {
+ setOperand(2, reinterpret_cast<Value*>(B));
+ }
+
+ inline BasicBlock *getSuccessor(unsigned i) const {
+ assert(i < 2 && "Successor # out of range for invoke!");
+ return i == 0 ? getNormalDest() : getUnwindDest();
+ }
+
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ assert(idx < 2 && "Successor # out of range for invoke!");
+ setOperand(idx+1, reinterpret_cast<Value*>(NewSucc));
+ }
+
+ unsigned getNumSuccessors() const { return 2; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const InvokeInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return (I->getOpcode() == Instruction::Invoke);
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+
+//===----------------------------------------------------------------------===//
+// UnwindInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// UnwindInst - Immediately exit the current function, unwinding the stack
+/// until an invoke instruction is found.
+///
+class UnwindInst : public TerminatorInst {
+public:
+ explicit UnwindInst(Instruction *InsertBefore = 0);
+ explicit UnwindInst(BasicBlock *InsertAtEnd);
+
+ virtual UnwindInst *clone() const;
+
+ unsigned getNumSuccessors() const { return 0; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UnwindInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Unwind;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// UnreachableInst Class
+//===----------------------------------------------------------------------===//
+
+//===---------------------------------------------------------------------------
+/// UnreachableInst - This function has undefined behavior. In particular, the
+/// presence of this instruction indicates some higher level knowledge that the
+/// end of the block cannot be reached.
+///
+class UnreachableInst : public TerminatorInst {
+public:
+ explicit UnreachableInst(Instruction *InsertBefore = 0);
+ explicit UnreachableInst(BasicBlock *InsertAtEnd);
+
+ virtual UnreachableInst *clone() const;
+
+ unsigned getNumSuccessors() const { return 0; }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UnreachableInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::Unreachable;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+private:
+ virtual BasicBlock *getSuccessorV(unsigned idx) const;
+ virtual unsigned getNumSuccessorsV() const;
+ virtual void setSuccessorV(unsigned idx, BasicBlock *B);
+};
+
+//===----------------------------------------------------------------------===//
+// TruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of integer types.
+class TruncInst : public CastInst {
+ /// Private copy constructor
+ TruncInst(const TruncInst &CI)
+ : CastInst(CI.getType(), Trunc, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ TruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The (smaller) type to truncate to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ TruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The (smaller) type to truncate to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical TruncInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const TruncInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Trunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// ZExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents zero extension of integer types.
+class ZExtInst : public CastInst {
+ /// @brief Private copy constructor
+ ZExtInst(const ZExtInst &CI)
+ : CastInst(CI.getType(), ZExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ const Type *Ty, ///< The type to zero extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end semantics.
+ ZExtInst(
+ Value *S, ///< The value to be zero extended
+ const Type *Ty, ///< The type to zero extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical ZExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ZExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == ZExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a sign extension of integer types.
+class SExtInst : public CastInst {
+ /// @brief Private copy constructor
+ SExtInst(const SExtInst &CI)
+ : CastInst(CI.getType(), SExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SExtInst(
+ Value *S, ///< The value to be sign extended
+ const Type *Ty, ///< The type to sign extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ SExtInst(
+ Value *S, ///< The value to be sign extended
+ const Type *Ty, ///< The type to sign extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical SExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPTruncInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a truncation of floating point types.
+class FPTruncInst : public CastInst {
+ FPTruncInst(const FPTruncInst &CI)
+ : CastInst(CI.getType(), FPTrunc, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The type to truncate to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-before-instruction semantics
+ FPTruncInst(
+ Value *S, ///< The value to be truncated
+ const Type *Ty, ///< The type to truncate to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPTruncInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPTruncInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPTrunc;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPExtInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents an extension of floating point types.
+class FPExtInst : public CastInst {
+ FPExtInst(const FPExtInst &CI)
+ : CastInst(CI.getType(), FPExt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ const Type *Ty, ///< The type to extend to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPExtInst(
+ Value *S, ///< The value to be extended
+ const Type *Ty, ///< The type to extend to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPExtInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPExtInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPExt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// UIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast unsigned integer to floating point.
+class UIToFPInst : public CastInst {
+ UIToFPInst(const UIToFPInst &CI)
+ : CastInst(CI.getType(), UIToFP, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ UIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical UIToFPInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const UIToFPInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == UIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// SIToFPInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from signed integer to floating point.
+class SIToFPInst : public CastInst {
+ SIToFPInst(const SIToFPInst &CI)
+ : CastInst(CI.getType(), SIToFP, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ SIToFPInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical SIToFPInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const SIToFPInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == SIToFP;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToUIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to unsigned integer
+class FPToUIInst : public CastInst {
+ FPToUIInst(const FPToUIInst &CI)
+ : CastInst(CI.getType(), FPToUI, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToUIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< Where to insert the new instruction
+ );
+
+ /// @brief Clone an identical FPToUIInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPToUIInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToUI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FPToSIInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from floating point to signed integer.
+class FPToSIInst : public CastInst {
+ FPToSIInst(const FPToSIInst &CI)
+ : CastInst(CI.getType(), FPToSI, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ FPToSIInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical FPToSIInst
+ virtual CastInst *clone() const;
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FPToSIInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == FPToSI;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// IntToPtrInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from an integer to a pointer.
+class IntToPtrInst : public CastInst {
+ IntToPtrInst(const IntToPtrInst &CI)
+ : CastInst(CI.getType(), IntToPtr, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ IntToPtrInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical IntToPtrInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const IntToPtrInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == IntToPtr;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// PtrToIntInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a cast from a pointer to an integer
+class PtrToIntInst : public CastInst {
+ PtrToIntInst(const PtrToIntInst &CI)
+ : CastInst(CI.getType(), PtrToInt, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ PtrToIntInst(
+ Value *S, ///< The value to be converted
+ const Type *Ty, ///< The type to convert to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical PtrToIntInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const PtrToIntInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == PtrToInt;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// BitCastInst Class
+//===----------------------------------------------------------------------===//
+
+/// @brief This class represents a no-op cast from one type to another.
+class BitCastInst : public CastInst {
+ BitCastInst(const BitCastInst &CI)
+ : CastInst(CI.getType(), BitCast, CI.getOperand(0)) {
+ }
+public:
+ /// @brief Constructor with insert-before-instruction semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ const Type *Ty, ///< The type to casted to
+ const std::string &Name = "", ///< A name for the new instruction
+ Instruction *InsertBefore = 0 ///< Where to insert the new instruction
+ );
+
+ /// @brief Constructor with insert-at-end-of-block semantics
+ BitCastInst(
+ Value *S, ///< The value to be casted
+ const Type *Ty, ///< The type to casted to
+ const std::string &Name, ///< A name for the new instruction
+ BasicBlock *InsertAtEnd ///< The block to insert the instruction into
+ );
+
+ /// @brief Clone an identical BitCastInst
+ virtual CastInst *clone() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BitCastInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == BitCast;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/IntrinsicInst.h b/include/llvm/IntrinsicInst.h
new file mode 100644
index 0000000..4e4d475
--- /dev/null
+++ b/include/llvm/IntrinsicInst.h
@@ -0,0 +1,323 @@
+//===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines classes that make it really easy to deal with intrinsic
+// functions with the isa/dyncast family of functions. In particular, this
+// allows you to do things like:
+//
+// if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst))
+// ... MCI->getDest() ... MCI->getSource() ...
+//
+// All intrinsic function calls are instances of the call instruction, so these
+// are all subclasses of the CallInst class. Note that none of these classes
+// has state or virtual methods, which is an important part of this gross/neat
+// hack working.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTRINSICINST_H
+#define LLVM_INTRINSICINST_H
+
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+ /// IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic
+ /// functions. This allows the standard isa/dyncast/cast functionality to
+ /// work with calls to intrinsic functions.
+ class IntrinsicInst : public CallInst {
+ IntrinsicInst(); // DO NOT IMPLEMENT
+ IntrinsicInst(const IntrinsicInst&); // DO NOT IMPLEMENT
+ void operator=(const IntrinsicInst&); // DO NOT IMPLEMENT
+ public:
+
+ /// StripPointerCasts - This static method strips off any unneeded pointer
+ /// casts from the specified value, returning the original uncasted value.
+ /// Note that the returned value is guaranteed to have pointer type.
+ static Value *StripPointerCasts(Value *Ptr);
+
+ /// getIntrinsicID - Return the intrinsic ID of this intrinsic.
+ ///
+ Intrinsic::ID getIntrinsicID() const {
+ return (Intrinsic::ID)getCalledFunction()->getIntrinsicID();
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const IntrinsicInst *) { return true; }
+ static inline bool classof(const CallInst *I) {
+ if (const Function *CF = I->getCalledFunction())
+ return CF->getIntrinsicID() != 0;
+ return false;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<CallInst>(V) && classof(cast<CallInst>(V));
+ }
+ };
+
+ /// DbgInfoIntrinsic - This is the common base class for debug info intrinsics
+ ///
+ struct DbgInfoIntrinsic : public IntrinsicInst {
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgInfoIntrinsic *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::dbg_stoppoint:
+ case Intrinsic::dbg_func_start:
+ case Intrinsic::dbg_region_start:
+ case Intrinsic::dbg_region_end:
+ case Intrinsic::dbg_declare:
+ return true;
+ default: return false;
+ }
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+
+ static Value *StripCast(Value *C);
+ };
+
+ /// DbgStopPointInst - This represents the llvm.dbg.stoppoint instruction.
+ ///
+ struct DbgStopPointInst : public DbgInfoIntrinsic {
+ Value *getLineValue() const { return const_cast<Value*>(getOperand(1)); }
+ Value *getColumnValue() const { return const_cast<Value*>(getOperand(2)); }
+ Value *getContext() const {
+ return StripCast(getOperand(3));
+ }
+
+ unsigned getLine() const {
+ return unsigned(cast<ConstantInt>(getOperand(1))->getZExtValue());
+ }
+ unsigned getColumn() const {
+ return unsigned(cast<ConstantInt>(getOperand(2))->getZExtValue());
+ }
+
+ std::string getFileName() const;
+ std::string getDirectory() const;
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgStopPointInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_stoppoint;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// DbgFuncStartInst - This represents the llvm.dbg.func.start instruction.
+ ///
+ struct DbgFuncStartInst : public DbgInfoIntrinsic {
+ Value *getSubprogram() const { return StripCast(getOperand(1)); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgFuncStartInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_func_start;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// DbgRegionStartInst - This represents the llvm.dbg.region.start
+ /// instruction.
+ struct DbgRegionStartInst : public DbgInfoIntrinsic {
+ Value *getContext() const { return StripCast(getOperand(1)); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgRegionStartInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_region_start;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// DbgRegionEndInst - This represents the llvm.dbg.region.end instruction.
+ ///
+ struct DbgRegionEndInst : public DbgInfoIntrinsic {
+ Value *getContext() const { return StripCast(getOperand(1)); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgRegionEndInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_region_end;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// DbgDeclareInst - This represents the llvm.dbg.declare instruction.
+ ///
+ struct DbgDeclareInst : public DbgInfoIntrinsic {
+ Value *getAddress() const { return getOperand(1); }
+ Value *getVariable() const { return StripCast(getOperand(2)); }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const DbgDeclareInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::dbg_declare;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemIntrinsic - This is the common base class for memset/memcpy/memmove.
+ ///
+ struct MemIntrinsic : public IntrinsicInst {
+ Value *getRawDest() const { return const_cast<Value*>(getOperand(1)); }
+
+ Value *getLength() const { return const_cast<Value*>(getOperand(3)); }
+ ConstantInt *getAlignment() const {
+ return cast<ConstantInt>(const_cast<Value*>(getOperand(4)));
+ }
+
+ /// getDest - This is just like getRawDest, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getDest() const { return StripPointerCasts(getRawDest()); }
+
+ /// set* - Set the specified arguments of the instruction.
+ ///
+ void setDest(Value *Ptr) {
+ assert(getRawDest()->getType() == Ptr->getType() &&
+ "setDest called with pointer of wrong type!");
+ setOperand(1, Ptr);
+ }
+
+ void setLength(Value *L) {
+ assert(getLength()->getType() == L->getType() &&
+ "setLength called with value of wrong type!");
+ setOperand(3, L);
+ }
+ void setAlignment(ConstantInt *A) {
+ assert(getAlignment()->getType() == A->getType() &&
+ "setAlignment called with value of wrong type!");
+ setOperand(4, A);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MemIntrinsic *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ switch (I->getIntrinsicID()) {
+ case Intrinsic::memcpy_i32:
+ case Intrinsic::memcpy_i64:
+ case Intrinsic::memmove_i32:
+ case Intrinsic::memmove_i64:
+ case Intrinsic::memset_i32:
+ case Intrinsic::memset_i64:
+ return true;
+ default: return false;
+ }
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+
+ /// MemCpyInst - This class wraps the llvm.memcpy intrinsic.
+ ///
+ struct MemCpyInst : public MemIntrinsic {
+ /// get* - Return the arguments to the instruction.
+ ///
+ Value *getRawSource() const { return const_cast<Value*>(getOperand(2)); }
+
+ /// getSource - This is just like getRawSource, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getSource() const { return StripPointerCasts(getRawSource()); }
+
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setOperand(2, Ptr);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MemCpyInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memcpy_i32 ||
+ I->getIntrinsicID() == Intrinsic::memcpy_i64;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemMoveInst - This class wraps the llvm.memmove intrinsic.
+ ///
+ struct MemMoveInst : public MemIntrinsic {
+ /// get* - Return the arguments to the instruction.
+ ///
+ Value *getRawSource() const { return const_cast<Value*>(getOperand(2)); }
+
+ /// getSource - This is just like getRawSource, but it strips off any cast
+ /// instructions that feed it, giving the original input. The returned
+ /// value is guaranteed to be a pointer.
+ Value *getSource() const { return StripPointerCasts(getRawSource()); }
+
+ void setSource(Value *Ptr) {
+ assert(getRawSource()->getType() == Ptr->getType() &&
+ "setSource called with pointer of wrong type!");
+ setOperand(2, Ptr);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MemMoveInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memmove_i32 ||
+ I->getIntrinsicID() == Intrinsic::memmove_i64;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+ /// MemSetInst - This class wraps the llvm.memset intrinsic.
+ ///
+ struct MemSetInst : public MemIntrinsic {
+ /// get* - Return the arguments to the instruction.
+ ///
+ Value *getValue() const { return const_cast<Value*>(getOperand(2)); }
+
+ void setValue(Value *Val) {
+ assert(getValue()->getType() == Val->getType() &&
+ "setSource called with pointer of wrong type!");
+ setOperand(2, Val);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const MemSetInst *) { return true; }
+ static inline bool classof(const IntrinsicInst *I) {
+ return I->getIntrinsicID() == Intrinsic::memset_i32 ||
+ I->getIntrinsicID() == Intrinsic::memset_i64;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V));
+ }
+ };
+
+}
+
+// Ensure that the IntrinsicInst.cpp file gets added as a dependency of any
+// file that includes this header
+FORCE_DEFINING_FILE_TO_BE_LINKED(IntrinsicInst)
+
+#endif
diff --git a/include/llvm/Intrinsics.h b/include/llvm/Intrinsics.h
new file mode 100644
index 0000000..3a97b33
--- /dev/null
+++ b/include/llvm/Intrinsics.h
@@ -0,0 +1,58 @@
+//===-- llvm/Instrinsics.h - LLVM Intrinsic Function Handling ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a set of enums which allow processing of intrinsic
+// functions. Values of these enum types are returned by
+// Function::getIntrinsicID.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_INTRINSICS_H
+#define LLVM_INTRINSICS_H
+
+namespace llvm {
+
+class Type;
+class FunctionType;
+class Function;
+class Module;
+
+/// Intrinsic Namespace - This namespace contains an enum with a value for
+/// every intrinsic/builtin function known by LLVM. These enum values are
+/// returned by Function::getIntrinsicID().
+///
+namespace Intrinsic {
+ enum ID {
+ not_intrinsic = 0, // Must be zero
+
+ // Get the intrinsic enums generated from Intrinsics.td
+#define GET_INTRINSIC_ENUM_VALUES
+#include "llvm/Intrinsics.gen"
+#undef GET_INTRINSIC_ENUM_VALUES
+ , num_intrinsics
+ };
+
+ /// Intrinsic::getName(ID) - Return the LLVM name for an intrinsic, such as
+ /// "llvm.ppc.altivec.lvx".
+ std::string getName(ID id, const Type **Tys = 0, unsigned numTys = 0);
+
+ /// Intrinsic::getType(ID) - Return the function type for an intrinsic.
+ ///
+ const FunctionType *getType(ID id, const Type **Tys = 0, unsigned numTys = 0);
+
+ /// Intrinsic::getDeclaration(M, ID) - Create or insert an LLVM Function
+ /// declaration for an intrinsic, and return it.
+ Function *getDeclaration(Module *M, ID id, const Type **Tys = 0,
+ unsigned numTys = 0);
+
+} // End Intrinsic namespace
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td
new file mode 100644
index 0000000..e5bb2f6
--- /dev/null
+++ b/include/llvm/Intrinsics.td
@@ -0,0 +1,255 @@
+//===- Intrinsics.td - Defines all LLVM intrinsics ---------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines properties of all LLVM intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/CodeGen/ValueTypes.td"
+
+//===----------------------------------------------------------------------===//
+// Properties we keep track of for intrinsics.
+//===----------------------------------------------------------------------===//
+
+class IntrinsicProperty;
+
+// Intr*Mem - Memory properties. An intrinsic is allowed to have exactly one of
+// these properties set. They are listed from the most aggressive (best to use
+// if correct) to the least aggressive. If no property is set, the worst case
+// is assumed (IntrWriteMem).
+
+// IntrNoMem - The intrinsic does not access memory or have any other side
+// effects. It may be CSE'd deleted if dead, etc.
+def IntrNoMem : IntrinsicProperty;
+
+// IntrReadArgMem - This intrinsic reads only from memory that one of its
+// arguments points to, but may read an unspecified amount.
+def IntrReadArgMem : IntrinsicProperty;
+
+// IntrReadMem - This intrinsic reads from unspecified memory, so it cannot be
+// moved across stores. However, it can be reordered otherwise and can be
+// deleted if dead.
+def IntrReadMem : IntrinsicProperty;
+
+// IntrWriteArgMem - This intrinsic reads and writes only from memory that one
+// of its arguments points to, but may access an unspecified amount. It has no
+// other side effects. This may only be used if the intrinsic doesn't "capture"
+// the argument pointer (e.g. storing it someplace).
+def IntrWriteArgMem : IntrinsicProperty;
+
+// IntrWriteMem - This intrinsic may read or modify unspecified memory or has
+// other side effects. It cannot be modified by the optimizer. This is the
+// default if the intrinsic has no other Intr*Mem property.
+def IntrWriteMem : IntrinsicProperty;
+
+//===----------------------------------------------------------------------===//
+// Types used by intrinsics.
+//===----------------------------------------------------------------------===//
+
+class LLVMType<ValueType vt, string typeval> {
+ ValueType VT = vt;
+ string TypeVal = typeval;
+}
+
+class LLVMIntegerType<ValueType VT, int width>
+ : LLVMType<VT, "Type::IntegerTyID"> {
+ int Width = width;
+}
+
+class LLVMVectorType<ValueType VT, int numelts, LLVMType elty>
+ : LLVMType<VT, "Type::VectorTyID">{
+ int NumElts = numelts;
+ LLVMType ElTy = elty;
+}
+
+class LLVMPointerType<LLVMType elty>
+ : LLVMType<iPTR, "Type::PointerTyID">{
+ LLVMType ElTy = elty;
+}
+
+class LLVMEmptyStructType
+ : LLVMType<OtherVT, "Type::StructTyID">{
+}
+
+def llvm_void_ty : LLVMType<isVoid, "Type::VoidTyID">;
+def llvm_int_ty : LLVMIntegerType<iAny, 0>;
+def llvm_i1_ty : LLVMIntegerType<i1 , 1>;
+def llvm_i8_ty : LLVMIntegerType<i8 , 8>;
+def llvm_i16_ty : LLVMIntegerType<i16, 16>;
+def llvm_i32_ty : LLVMIntegerType<i32, 32>;
+def llvm_i64_ty : LLVMIntegerType<i64, 64>;
+def llvm_float_ty : LLVMType<f32, "Type::FloatTyID">;
+def llvm_double_ty : LLVMType<f64, "Type::DoubleTyID">;
+def llvm_ptr_ty : LLVMPointerType<llvm_i8_ty>; // i8*
+def llvm_ptrptr_ty : LLVMPointerType<llvm_ptr_ty>; // i8**
+def llvm_empty_ty : LLVMEmptyStructType; // { }
+def llvm_descriptor_ty : LLVMPointerType<llvm_empty_ty>; // { }*
+
+def llvm_v16i8_ty : LLVMVectorType<v16i8,16, llvm_i8_ty>; // 16 x i8
+def llvm_v8i16_ty : LLVMVectorType<v8i16, 8, llvm_i16_ty>; // 8 x i16
+def llvm_v2i64_ty : LLVMVectorType<v2i64, 2, llvm_i64_ty>; // 2 x i64
+def llvm_v2i32_ty : LLVMVectorType<v2i32, 2, llvm_i32_ty>; // 2 x i32
+def llvm_v1i64_ty : LLVMVectorType<v1i64, 1, llvm_i64_ty>; // 1 x i64
+def llvm_v4i32_ty : LLVMVectorType<v4i32, 4, llvm_i32_ty>; // 4 x i32
+def llvm_v4f32_ty : LLVMVectorType<v4f32, 4, llvm_float_ty>; // 4 x float
+def llvm_v2f64_ty : LLVMVectorType<v2f64, 2, llvm_double_ty>;// 2 x double
+
+// MMX Vector Types
+def llvm_v8i8_ty : LLVMVectorType<v8i8, 8, llvm_i8_ty>; // 8 x i8
+def llvm_v4i16_ty : LLVMVectorType<v4i16, 4, llvm_i16_ty>; // 4 x i16
+
+def llvm_vararg_ty : LLVMType<isVoid, "...">; // vararg
+
+//===----------------------------------------------------------------------===//
+// Intrinsic Definitions.
+//===----------------------------------------------------------------------===//
+
+// Intrinsic class - This is used to define one LLVM intrinsic. The name of the
+// intrinsic definition should start with "int_", then match the LLVM intrinsic
+// name with the "llvm." prefix removed, and all "."s turned into "_"s. For
+// example, llvm.bswap.i16 -> int_bswap_i16.
+//
+// * Types is a list containing the return type and the argument types
+// expected for the intrinsic.
+// * Properties can be set to describe the behavior of the intrinsic.
+//
+class Intrinsic<list<LLVMType> types,
+ list<IntrinsicProperty> properties = [],
+ string name = ""> {
+ string LLVMName = name;
+ string TargetPrefix = ""; // Set to a prefix for target-specific intrinsics.
+ list<LLVMType> Types = types;
+ list<IntrinsicProperty> Properties = properties;
+}
+
+/// GCCBuiltin - If this intrinsic exactly corresponds to a GCC builtin, this
+/// specifies the name of the builtin. This provides automatic CBE and CFE
+/// support.
+class GCCBuiltin<string name> {
+ string GCCBuiltinName = name;
+}
+
+
+//===--------------- Variable Argument Handling Intrinsics ----------------===//
+//
+
+def int_vastart : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [], "llvm.va_start">;
+def int_vacopy : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty], [],
+ "llvm.va_copy">;
+def int_vaend : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [], "llvm.va_end">;
+
+//===------------------- Garbage Collection Intrinsics --------------------===//
+//
+def int_gcroot : Intrinsic<[llvm_void_ty, llvm_ptrptr_ty, llvm_ptr_ty]>;
+def int_gcread : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptrptr_ty],
+ [IntrReadArgMem]>;
+def int_gcwrite : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_ptrptr_ty], [IntrWriteArgMem]>;
+
+//===--------------------- Code Generator Intrinsics ----------------------===//
+//
+def int_returnaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_frameaddress : Intrinsic<[llvm_ptr_ty, llvm_i32_ty], [IntrNoMem]>;
+def int_stacksave : Intrinsic<[llvm_ptr_ty], [IntrReadMem]>,
+ GCCBuiltin<"__builtin_stack_save">;
+def int_stackrestore : Intrinsic<[llvm_void_ty, llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_stack_restore">;
+def int_prefetch : Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+def int_pcmarker : Intrinsic<[llvm_void_ty, llvm_i32_ty]>;
+
+def int_readcyclecounter : Intrinsic<[llvm_i64_ty]>;
+
+//===------------------- Standard C Library Intrinsics --------------------===//
+//
+
+let Properties = [IntrWriteArgMem] in {
+ def int_memcpy_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+ def int_memcpy_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i64_ty, llvm_i32_ty]>;
+ def int_memmove_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+ def int_memmove_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_i64_ty, llvm_i32_ty]>;
+ def int_memset_i32 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i8_ty,
+ llvm_i32_ty, llvm_i32_ty]>;
+ def int_memset_i64 : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i8_ty,
+ llvm_i64_ty, llvm_i32_ty]>;
+}
+
+let Properties = [IntrNoMem] in {
+ def int_sqrt_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty]>;
+ def int_sqrt_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty]>;
+
+ def int_powi_f32 : Intrinsic<[llvm_float_ty , llvm_float_ty, llvm_i32_ty]>;
+ def int_powi_f64 : Intrinsic<[llvm_double_ty, llvm_double_ty, llvm_i32_ty]>;
+}
+
+// NOTE: these are internal interfaces.
+def int_setjmp : Intrinsic<[llvm_i32_ty , llvm_ptr_ty]>;
+def int_longjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty]>;
+def int_sigsetjmp : Intrinsic<[llvm_i32_ty , llvm_ptr_ty, llvm_i32_ty]>;
+def int_siglongjmp : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty]>;
+
+//===-------------------- Bit Manipulation Intrinsics ---------------------===//
+//
+
+// None of these intrinsics accesses memory at all.
+let Properties = [IntrNoMem] in {
+ def int_bswap: Intrinsic<[llvm_int_ty, llvm_int_ty]>;
+ def int_ctpop: Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
+ def int_ctlz : Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
+ def int_cttz : Intrinsic<[llvm_i32_ty, llvm_int_ty]>;
+ def int_part_select :
+ Intrinsic<[llvm_int_ty, llvm_int_ty, llvm_i32_ty, llvm_i32_ty]>;
+ def int_part_set :
+ Intrinsic<[llvm_int_ty, llvm_int_ty, llvm_int_ty, llvm_i32_ty,
+ llvm_i32_ty]>;
+}
+
+//===------------------------ Debugger Intrinsics -------------------------===//
+//
+
+def int_dbg_stoppoint : Intrinsic<[llvm_void_ty,
+ llvm_i32_ty, llvm_i32_ty,
+ llvm_descriptor_ty]>;
+def int_dbg_region_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
+def int_dbg_region_end : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
+def int_dbg_func_start : Intrinsic<[llvm_void_ty, llvm_descriptor_ty]>;
+def int_dbg_declare : Intrinsic<[llvm_void_ty, llvm_descriptor_ty,
+ llvm_descriptor_ty]>;
+
+//===------------------ Exception Handling Intrinsics----------------------===//
+//
+def int_eh_exception : Intrinsic<[llvm_ptr_ty]>;
+def int_eh_selector : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_vararg_ty]>;
+def int_eh_typeid_for : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
+
+def int_eh_return : Intrinsic<[llvm_void_ty, llvm_i32_ty, llvm_ptr_ty]>,
+ GCCBuiltin<"__builtin_eh_return">;
+
+def int_eh_unwind_init: Intrinsic<[llvm_void_ty]>,
+ GCCBuiltin<"__builtin_unwind_init">;
+
+def int_eh_dwarf_cfa : Intrinsic<[llvm_ptr_ty, llvm_i32_ty]>;
+
+//===---------------- Generic Variable Attribute Intrinsics----------------===//
+//
+def int_var_annotation : Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_ptr_ty,
+ llvm_ptr_ty, llvm_i32_ty],
+ [], "llvm.var.annotation">;
+
+//===----------------------------------------------------------------------===//
+// Target-specific intrinsics
+//===----------------------------------------------------------------------===//
+
+include "llvm/IntrinsicsPowerPC.td"
+include "llvm/IntrinsicsX86.td"
diff --git a/include/llvm/IntrinsicsPowerPC.td b/include/llvm/IntrinsicsPowerPC.td
new file mode 100644
index 0000000..666426a
--- /dev/null
+++ b/include/llvm/IntrinsicsPowerPC.td
@@ -0,0 +1,462 @@
+//===- IntrinsicsPowerPC.td - Defines PowerPC intrinsics ---*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the PowerPC-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Definitions for all PowerPC intrinsics.
+//
+
+// Non-altivec intrinsics.
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+ // dcba/dcbf/dcbi/dcbst/dcbt/dcbz/dcbzl(PPC970) instructions.
+ def int_ppc_dcba : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbf : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbi : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbst : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbt : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbtst: Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbz : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_ppc_dcbzl : Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+}
+
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ /// PowerPC_Vec_Intrinsic - Base class for all altivec intrinsics.
+ class PowerPC_Vec_Intrinsic<string GCCIntSuffix, list<LLVMType> types,
+ list<IntrinsicProperty> properties>
+ : GCCBuiltin<!strconcat("__builtin_altivec_", GCCIntSuffix)>,
+ Intrinsic<types, properties>;
+}
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Class Definitions.
+//
+
+/// PowerPC_Vec_FF_Intrinsic - A PowerPC intrinsic that takes one v4f32
+/// vector and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_FF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+
+/// PowerPC_Vec_FFF_Intrinsic - A PowerPC intrinsic that takes two v4f32
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_FFF_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4f32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_BBB_Intrinsic - A PowerPC intrinsic that takes two v16f8
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_BBB_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_HHH_Intrinsic - A PowerPC intrinsic that takes two v8i16
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_HHH_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+/// PowerPC_Vec_WWW_Intrinsic - A PowerPC intrinsic that takes two v4i32
+/// vectors and returns one. These intrinsics have no side effects.
+class PowerPC_Vec_WWW_Intrinsic<string GCCIntSuffix>
+ : PowerPC_Vec_Intrinsic<GCCIntSuffix,
+ [llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+
+//===----------------------------------------------------------------------===//
+// PowerPC Altivec Intrinsic Definitions.
+
+let TargetPrefix = "ppc" in { // All intrinsics start with "llvm.ppc.".
+ // Data Stream Control.
+ def int_ppc_altivec_dss : GCCBuiltin<"__builtin_altivec_dss">,
+ Intrinsic<[llvm_void_ty, llvm_i32_ty], [IntrWriteMem]>;
+ def int_ppc_altivec_dssall : GCCBuiltin<"__builtin_altivec_dssall">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+ def int_ppc_altivec_dst : GCCBuiltin<"__builtin_altivec_dst">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_dstt : GCCBuiltin<"__builtin_altivec_dstt">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_dstst : GCCBuiltin<"__builtin_altivec_dstst">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_dststt : GCCBuiltin<"__builtin_altivec_dststt">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty, llvm_i32_ty, llvm_i32_ty],
+ [IntrWriteMem]>;
+
+ // VSCR access.
+ def int_ppc_altivec_mfvscr : GCCBuiltin<"__builtin_altivec_mfvscr">,
+ Intrinsic<[llvm_v8i16_ty], [IntrReadMem]>;
+ def int_ppc_altivec_mtvscr : GCCBuiltin<"__builtin_altivec_mtvscr">,
+ Intrinsic<[llvm_void_ty, llvm_v4i32_ty], [IntrWriteMem]>;
+
+
+ // Loads. These don't map directly to GCC builtins because they represent the
+ // source address with a single pointer.
+ def int_ppc_altivec_lvx :
+ Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvxl :
+ Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvebx :
+ Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvehx :
+ Intrinsic<[llvm_v8i16_ty, llvm_ptr_ty], [IntrReadMem]>;
+ def int_ppc_altivec_lvewx :
+ Intrinsic<[llvm_v4i32_ty, llvm_ptr_ty], [IntrReadMem]>;
+
+ // Stores. These don't map directly to GCC builtins because they represent the
+ // source address with a single pointer.
+ def int_ppc_altivec_stvx :
+ Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_stvxl :
+ Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_stvebx :
+ Intrinsic<[llvm_void_ty, llvm_v16i8_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_stvehx :
+ Intrinsic<[llvm_void_ty, llvm_v8i16_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+ def int_ppc_altivec_stvewx :
+ Intrinsic<[llvm_void_ty, llvm_v4i32_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+
+ // Comparisons setting a vector.
+ def int_ppc_altivec_vcmpbfp : GCCBuiltin<"__builtin_altivec_vcmpbfp">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpeqfp : GCCBuiltin<"__builtin_altivec_vcmpeqfp">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgefp : GCCBuiltin<"__builtin_altivec_vcmpgefp">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtfp : GCCBuiltin<"__builtin_altivec_vcmpgtfp">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequw : GCCBuiltin<"__builtin_altivec_vcmpequw">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsw : GCCBuiltin<"__builtin_altivec_vcmpgtsw">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuw : GCCBuiltin<"__builtin_altivec_vcmpgtuw">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequh : GCCBuiltin<"__builtin_altivec_vcmpequh">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsh : GCCBuiltin<"__builtin_altivec_vcmpgtsh">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuh : GCCBuiltin<"__builtin_altivec_vcmpgtuh">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequb : GCCBuiltin<"__builtin_altivec_vcmpequb">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsb : GCCBuiltin<"__builtin_altivec_vcmpgtsb">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtub : GCCBuiltin<"__builtin_altivec_vcmpgtub">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+
+ // Predicate Comparisons. The first operand specifies interpretation of CR6.
+ def int_ppc_altivec_vcmpbfp_p : GCCBuiltin<"__builtin_altivec_vcmpbfp_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpeqfp_p : GCCBuiltin<"__builtin_altivec_vcmpeqfp_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgefp_p : GCCBuiltin<"__builtin_altivec_vcmpgefp_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4f32_ty,llvm_v4f32_ty],
+ [IntrNoMem]>;
+ 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_vcmpequw_p : GCCBuiltin<"__builtin_altivec_vcmpequw_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsw_p : GCCBuiltin<"__builtin_altivec_vcmpgtsw_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuw_p : GCCBuiltin<"__builtin_altivec_vcmpgtuw_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v4i32_ty,llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequh_p : GCCBuiltin<"__builtin_altivec_vcmpequh_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsh_p : GCCBuiltin<"__builtin_altivec_vcmpgtsh_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtuh_p : GCCBuiltin<"__builtin_altivec_vcmpgtuh_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v8i16_ty,llvm_v8i16_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vcmpequb_p : GCCBuiltin<"__builtin_altivec_vcmpequb_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtsb_p : GCCBuiltin<"__builtin_altivec_vcmpgtsb_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcmpgtub_p : GCCBuiltin<"__builtin_altivec_vcmpgtub_p">,
+ Intrinsic<[llvm_i32_ty, llvm_i32_ty, llvm_v16i8_ty,llvm_v16i8_ty],
+ [IntrNoMem]>;
+}
+
+// Vector average.
+def int_ppc_altivec_vavgsb : PowerPC_Vec_BBB_Intrinsic<"vavgsb">;
+def int_ppc_altivec_vavgsh : PowerPC_Vec_HHH_Intrinsic<"vavgsh">;
+def int_ppc_altivec_vavgsw : PowerPC_Vec_WWW_Intrinsic<"vavgsw">;
+def int_ppc_altivec_vavgub : PowerPC_Vec_BBB_Intrinsic<"vavgub">;
+def int_ppc_altivec_vavguh : PowerPC_Vec_HHH_Intrinsic<"vavguh">;
+def int_ppc_altivec_vavguw : PowerPC_Vec_WWW_Intrinsic<"vavguw">;
+
+// Vector maximum.
+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_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">;
+
+// 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_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">;
+
+// Saturating adds.
+def int_ppc_altivec_vaddubs : PowerPC_Vec_BBB_Intrinsic<"vaddubs">;
+def int_ppc_altivec_vaddsbs : PowerPC_Vec_BBB_Intrinsic<"vaddsbs">;
+def int_ppc_altivec_vadduhs : PowerPC_Vec_HHH_Intrinsic<"vadduhs">;
+def int_ppc_altivec_vaddshs : PowerPC_Vec_HHH_Intrinsic<"vaddshs">;
+def int_ppc_altivec_vadduws : PowerPC_Vec_WWW_Intrinsic<"vadduws">;
+def int_ppc_altivec_vaddsws : PowerPC_Vec_WWW_Intrinsic<"vaddsws">;
+def int_ppc_altivec_vaddcuw : PowerPC_Vec_WWW_Intrinsic<"vaddcuw">;
+
+// Saturating subs.
+def int_ppc_altivec_vsububs : PowerPC_Vec_BBB_Intrinsic<"vsububs">;
+def int_ppc_altivec_vsubsbs : PowerPC_Vec_BBB_Intrinsic<"vsubsbs">;
+def int_ppc_altivec_vsubuhs : PowerPC_Vec_HHH_Intrinsic<"vsubuhs">;
+def int_ppc_altivec_vsubshs : PowerPC_Vec_HHH_Intrinsic<"vsubshs">;
+def int_ppc_altivec_vsubuws : PowerPC_Vec_WWW_Intrinsic<"vsubuws">;
+def int_ppc_altivec_vsubsws : PowerPC_Vec_WWW_Intrinsic<"vsubsws">;
+def int_ppc_altivec_vsubcuw : PowerPC_Vec_WWW_Intrinsic<"vsubcuw">;
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ // Saturating multiply-adds.
+ def int_ppc_altivec_vmhaddshs : GCCBuiltin<"__builtin_altivec_vmhaddshs">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmhraddshs : GCCBuiltin<"__builtin_altivec_vmhraddshs">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
+ def int_ppc_altivec_vmaddfp : GCCBuiltin<"__builtin_altivec_vmaddfp">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vnmsubfp : GCCBuiltin<"__builtin_altivec_vnmsubfp">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+
+ // Vector Multiply Sum Intructions.
+ def int_ppc_altivec_vmsummbm : GCCBuiltin<"__builtin_altivec_vmsummbm">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumshm : GCCBuiltin<"__builtin_altivec_vmsumshm">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumshs : GCCBuiltin<"__builtin_altivec_vmsumshs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumubm : GCCBuiltin<"__builtin_altivec_vmsumubm">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumuhm : GCCBuiltin<"__builtin_altivec_vmsumuhm">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vmsumuhs : GCCBuiltin<"__builtin_altivec_vmsumuhs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+
+ // Vector Multiply Intructions.
+ def int_ppc_altivec_vmulesb : GCCBuiltin<"__builtin_altivec_vmulesb">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmulesh : GCCBuiltin<"__builtin_altivec_vmulesh">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_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_vmulosb : GCCBuiltin<"__builtin_altivec_vmulosb">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty, llvm_v16i8_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vmulosh : GCCBuiltin<"__builtin_altivec_vmulosh">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v8i16_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]>;
+
+ // Vector Sum Intructions.
+ def int_ppc_altivec_vsumsws : GCCBuiltin<"__builtin_altivec_vsumsws">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum2sws : GCCBuiltin<"__builtin_altivec_vsum2sws">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4sbs : GCCBuiltin<"__builtin_altivec_vsum4sbs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4shs : GCCBuiltin<"__builtin_altivec_vsum4shs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vsum4ubs : GCCBuiltin<"__builtin_altivec_vsum4ubs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v16i8_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // Other multiplies.
+ def int_ppc_altivec_vmladduhm : GCCBuiltin<"__builtin_altivec_vmladduhm">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+
+ // Packs.
+ def int_ppc_altivec_vpkpx : GCCBuiltin<"__builtin_altivec_vpkpx">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkshss : GCCBuiltin<"__builtin_altivec_vpkshss">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkshus : GCCBuiltin<"__builtin_altivec_vpkshus">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkswss : GCCBuiltin<"__builtin_altivec_vpkswss">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vpkswus : GCCBuiltin<"__builtin_altivec_vpkswus">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+ // vpkuhum is lowered to a shuffle.
+ def int_ppc_altivec_vpkuhus : GCCBuiltin<"__builtin_altivec_vpkuhus">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v8i16_ty, llvm_v8i16_ty],
+ [IntrNoMem]>;
+ // vpkuwum is lowered to a shuffle.
+ def int_ppc_altivec_vpkuwus : GCCBuiltin<"__builtin_altivec_vpkuwus">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v4i32_ty, llvm_v4i32_ty],
+ [IntrNoMem]>;
+
+ // Unpacks.
+ def int_ppc_altivec_vupkhpx : GCCBuiltin<"__builtin_altivec_vupkhpx">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupkhsb : GCCBuiltin<"__builtin_altivec_vupkhsb">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupkhsh : GCCBuiltin<"__builtin_altivec_vupkhsh">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklpx : GCCBuiltin<"__builtin_altivec_vupklpx">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklsb : GCCBuiltin<"__builtin_altivec_vupklsb">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vupklsh : GCCBuiltin<"__builtin_altivec_vupklsh">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty], [IntrNoMem]>;
+
+
+ // FP <-> integer conversion.
+ def int_ppc_altivec_vcfsx : GCCBuiltin<"__builtin_altivec_vcfsx">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vcfux : GCCBuiltin<"__builtin_altivec_vcfux">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4i32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vctsxs : GCCBuiltin<"__builtin_altivec_vctsxs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+ def int_ppc_altivec_vctuxs : GCCBuiltin<"__builtin_altivec_vctuxs">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty, llvm_i32_ty],
+ [IntrNoMem]>;
+
+ def int_ppc_altivec_vrfim : GCCBuiltin<"__builtin_altivec_vrfim">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfin : GCCBuiltin<"__builtin_altivec_vrfin">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfip : GCCBuiltin<"__builtin_altivec_vrfip">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vrfiz : GCCBuiltin<"__builtin_altivec_vrfiz">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vsl : PowerPC_Vec_WWW_Intrinsic<"vsl">;
+def int_ppc_altivec_vslo : PowerPC_Vec_WWW_Intrinsic<"vslo">;
+
+def int_ppc_altivec_vslb : PowerPC_Vec_BBB_Intrinsic<"vslb">;
+def int_ppc_altivec_vslh : PowerPC_Vec_HHH_Intrinsic<"vslh">;
+def int_ppc_altivec_vslw : PowerPC_Vec_WWW_Intrinsic<"vslw">;
+
+// Right Shifts.
+def int_ppc_altivec_vsr : PowerPC_Vec_WWW_Intrinsic<"vsr">;
+def int_ppc_altivec_vsro : PowerPC_Vec_WWW_Intrinsic<"vsro">;
+
+def int_ppc_altivec_vsrb : PowerPC_Vec_BBB_Intrinsic<"vsrb">;
+def int_ppc_altivec_vsrh : PowerPC_Vec_HHH_Intrinsic<"vsrh">;
+def int_ppc_altivec_vsrw : PowerPC_Vec_WWW_Intrinsic<"vsrw">;
+def int_ppc_altivec_vsrab : PowerPC_Vec_BBB_Intrinsic<"vsrab">;
+def int_ppc_altivec_vsrah : PowerPC_Vec_HHH_Intrinsic<"vsrah">;
+def int_ppc_altivec_vsraw : PowerPC_Vec_WWW_Intrinsic<"vsraw">;
+
+// Rotates.
+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">;
+
+let TargetPrefix = "ppc" in { // All PPC intrinsics start with "llvm.ppc.".
+ // Miscellaneous.
+ def int_ppc_altivec_lvsl :
+ Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrNoMem]>;
+ def int_ppc_altivec_lvsr :
+ Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrNoMem]>;
+
+ def int_ppc_altivec_vperm : GCCBuiltin<"__builtin_altivec_vperm_4si">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_ppc_altivec_vsel : GCCBuiltin<"__builtin_altivec_vsel_4si">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+def int_ppc_altivec_vexptefp : PowerPC_Vec_FF_Intrinsic<"vexptefp">;
+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">;
diff --git a/include/llvm/IntrinsicsX86.td b/include/llvm/IntrinsicsX86.td
new file mode 100644
index 0000000..0f61e24
--- /dev/null
+++ b/include/llvm/IntrinsicsX86.td
@@ -0,0 +1,715 @@
+//===- IntrinsicsX86.td - Defines X86 intrinsics -----------*- tablegen -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines all of the X86-specific intrinsics.
+//
+//===----------------------------------------------------------------------===//
+
+
+//===----------------------------------------------------------------------===//
+// SSE1
+
+// Arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_add_ss : GCCBuiltin<"__builtin_ia32_addss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_sub_ss : GCCBuiltin<"__builtin_ia32_subss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_mul_ss : GCCBuiltin<"__builtin_ia32_mulss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_div_ss : GCCBuiltin<"__builtin_ia32_divss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_sqrt_ss : GCCBuiltin<"__builtin_ia32_sqrtss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_sqrt_ps : GCCBuiltin<"__builtin_ia32_sqrtps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rcp_ss : GCCBuiltin<"__builtin_ia32_rcpss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rcp_ps : GCCBuiltin<"__builtin_ia32_rcpps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rsqrt_ss : GCCBuiltin<"__builtin_ia32_rsqrtss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_rsqrt_ps : GCCBuiltin<"__builtin_ia32_rsqrtps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty],
+ [IntrNoMem]>;
+ def int_x86_sse_min_ss : GCCBuiltin<"__builtin_ia32_minss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_min_ps : GCCBuiltin<"__builtin_ia32_minps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_max_ss : GCCBuiltin<"__builtin_ia32_maxss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_max_ps : GCCBuiltin<"__builtin_ia32_maxps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+// Comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_cmp_ss :
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse_cmp_ps :
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse_comieq_ss : GCCBuiltin<"__builtin_ia32_comieq">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comilt_ss : GCCBuiltin<"__builtin_ia32_comilt">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comile_ss : GCCBuiltin<"__builtin_ia32_comile">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comigt_ss : GCCBuiltin<"__builtin_ia32_comigt">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comige_ss : GCCBuiltin<"__builtin_ia32_comige">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_comineq_ss : GCCBuiltin<"__builtin_ia32_comineq">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomieq_ss : GCCBuiltin<"__builtin_ia32_ucomieq">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomilt_ss : GCCBuiltin<"__builtin_ia32_ucomilt">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomile_ss : GCCBuiltin<"__builtin_ia32_ucomile">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomigt_ss : GCCBuiltin<"__builtin_ia32_ucomigt">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomige_ss : GCCBuiltin<"__builtin_ia32_ucomige">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_ucomineq_ss : GCCBuiltin<"__builtin_ia32_ucomineq">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+
+// Conversion ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_cvtss2si : GCCBuiltin<"__builtin_ia32_cvtss2si">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvttss2si : GCCBuiltin<"__builtin_ia32_cvttss2si">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse_cvtsi2ss : GCCBuiltin<"__builtin_ia32_cvtsi2ss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+}
+
+// SIMD load ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_loadu_ps : GCCBuiltin<"__builtin_ia32_loadups">,
+ Intrinsic<[llvm_v4f32_ty, llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_storeu_ps : GCCBuiltin<"__builtin_ia32_storeups">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v4f32_ty], [IntrWriteMem]>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_movnt_ps : GCCBuiltin<"__builtin_ia32_movntps">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v4f32_ty], [IntrWriteMem]>;
+ def int_x86_sse_sfence : GCCBuiltin<"__builtin_ia32_sfence">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+}
+
+// Control register.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_stmxcsr :
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_x86_sse_ldmxcsr :
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse_movmsk_ps : GCCBuiltin<"__builtin_ia32_movmskps">,
+ Intrinsic<[llvm_i32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE2
+
+// FP arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_add_sd : GCCBuiltin<"__builtin_ia32_addsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_sub_sd : GCCBuiltin<"__builtin_ia32_subsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_mul_sd : GCCBuiltin<"__builtin_ia32_mulsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_div_sd : GCCBuiltin<"__builtin_ia32_divsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_sqrt_sd : GCCBuiltin<"__builtin_ia32_sqrtsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_sqrt_pd : GCCBuiltin<"__builtin_ia32_sqrtpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_rcp_sd : GCCBuiltin<"__builtin_ia32_rcpsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_rcp_pd : GCCBuiltin<"__builtin_ia32_rcppd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_rsqrt_sd : GCCBuiltin<"__builtin_ia32_rsqrtsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_rsqrt_pd : GCCBuiltin<"__builtin_ia32_rsqrtpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty],
+ [IntrNoMem]>;
+ def int_x86_sse2_min_sd : GCCBuiltin<"__builtin_ia32_minsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_min_pd : GCCBuiltin<"__builtin_ia32_minpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_max_sd : GCCBuiltin<"__builtin_ia32_maxsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_max_pd : GCCBuiltin<"__builtin_ia32_maxpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// FP comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_cmp_sd :
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_cmp_pd :
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_comieq_sd : GCCBuiltin<"__builtin_ia32_comisdeq">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comilt_sd : GCCBuiltin<"__builtin_ia32_comisdlt">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comile_sd : GCCBuiltin<"__builtin_ia32_comisdle">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comigt_sd : GCCBuiltin<"__builtin_ia32_comisdgt">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comige_sd : GCCBuiltin<"__builtin_ia32_comisdge">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_comineq_sd : GCCBuiltin<"__builtin_ia32_comisdneq">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomieq_sd : GCCBuiltin<"__builtin_ia32_ucomisdeq">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomilt_sd : GCCBuiltin<"__builtin_ia32_ucomisdlt">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomile_sd : GCCBuiltin<"__builtin_ia32_ucomisdle">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomigt_sd : GCCBuiltin<"__builtin_ia32_ucomisdgt">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomige_sd : GCCBuiltin<"__builtin_ia32_ucomisdge">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_ucomineq_sd : GCCBuiltin<"__builtin_ia32_ucomisdneq">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_padds_b : GCCBuiltin<"__builtin_ia32_paddsb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_padds_w : GCCBuiltin<"__builtin_ia32_paddsw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd128">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pminu_b : GCCBuiltin<"__builtin_ia32_pminub128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_psll_w :
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_d :
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_q :
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psll_dq : GCCBuiltin<"__builtin_ia32_pslldqi128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_w :
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_d :
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_q :
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psrl_dq : GCCBuiltin<"__builtin_ia32_psrldqi128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psra_w :
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_psra_d :
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+// Integer comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_pcmpeq_b : GCCBuiltin<"__builtin_ia32_pcmpeqb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pcmpeq_w : GCCBuiltin<"__builtin_ia32_pcmpeqw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pcmpeq_d : GCCBuiltin<"__builtin_ia32_pcmpeqd128">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_pcmpgt_b : GCCBuiltin<"__builtin_ia32_pcmpgtb128">,
+ Intrinsic<[llvm_v16i8_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_pcmpgt_w : GCCBuiltin<"__builtin_ia32_pcmpgtw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_pcmpgt_d : GCCBuiltin<"__builtin_ia32_pcmpgtd128">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+}
+
+// Conversion ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_cvtdq2pd : GCCBuiltin<"__builtin_ia32_cvtdq2pd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtdq2ps : GCCBuiltin<"__builtin_ia32_cvtdq2ps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtpd2dq : GCCBuiltin<"__builtin_ia32_cvtpd2dq">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttpd2dq : GCCBuiltin<"__builtin_ia32_cvttpd2dq">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtpd2ps : GCCBuiltin<"__builtin_ia32_cvtpd2ps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtps2dq : GCCBuiltin<"__builtin_ia32_cvtps2dq">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttps2dq : GCCBuiltin<"__builtin_ia32_cvttps2dq">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtps2pd : GCCBuiltin<"__builtin_ia32_cvtps2pd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsd2si : GCCBuiltin<"__builtin_ia32_cvtsd2si">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvttsd2si : GCCBuiltin<"__builtin_ia32_cvttsd2si">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsi2sd : GCCBuiltin<"__builtin_ia32_cvtsi2sd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtsd2ss : GCCBuiltin<"__builtin_ia32_cvtsd2ss">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_cvtss2sd : GCCBuiltin<"__builtin_ia32_cvtss2sd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+}
+
+// SIMD load ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_loadu_pd : GCCBuiltin<"__builtin_ia32_loadupd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_sse2_loadu_dq : GCCBuiltin<"__builtin_ia32_loaddqu">,
+ Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// SIMD store ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_storeu_pd : GCCBuiltin<"__builtin_ia32_storeupd">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v2f64_ty], [IntrWriteMem]>;
+ def int_x86_sse2_storeu_dq : GCCBuiltin<"__builtin_ia32_storedqu">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v16i8_ty], [IntrWriteMem]>;
+ def int_x86_sse2_storel_dq : GCCBuiltin<"__builtin_ia32_storelv4si">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v4i32_ty], [IntrWriteMem]>;
+}
+
+// Cacheability support ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_movnt_dq : GCCBuiltin<"__builtin_ia32_movntdq">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v2i64_ty], [IntrWriteMem]>;
+ def int_x86_sse2_movnt_pd : GCCBuiltin<"__builtin_ia32_movntpd">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v2f64_ty], [IntrWriteMem]>;
+ def int_x86_sse2_movnt_i : GCCBuiltin<"__builtin_ia32_movnti">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_i32_ty], [IntrWriteMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_packsswb_128 : GCCBuiltin<"__builtin_ia32_packsswb128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_packssdw_128 : GCCBuiltin<"__builtin_ia32_packssdw128">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty,
+ llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_packuswb_128 : GCCBuiltin<"__builtin_ia32_packuswb128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+ def int_x86_sse2_movl_dq : GCCBuiltin<"__builtin_ia32_movqv4si">,
+ Intrinsic<[llvm_v4i32_ty, llvm_v4i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_movmsk_pd : GCCBuiltin<"__builtin_ia32_movmskpd">,
+ Intrinsic<[llvm_i32_ty, llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_pmovmskb_128 : GCCBuiltin<"__builtin_ia32_pmovmskb128">,
+ Intrinsic<[llvm_i32_ty, llvm_v16i8_ty], [IntrNoMem]>;
+ def int_x86_sse2_maskmov_dqu : GCCBuiltin<"__builtin_ia32_maskmovdqu">,
+ Intrinsic<[llvm_void_ty, llvm_v16i8_ty,
+ llvm_v16i8_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_x86_sse2_clflush : GCCBuiltin<"__builtin_ia32_clflush">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty], [IntrWriteMem]>;
+ def int_x86_sse2_lfence : GCCBuiltin<"__builtin_ia32_lfence">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+ def int_x86_sse2_mfence : GCCBuiltin<"__builtin_ia32_mfence">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+}
+
+// Shuffles.
+// FIXME: Temporary workarounds since 2-wide shuffle is broken.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse2_movs_d : GCCBuiltin<"__builtin_ia32_movsd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_loadh_pd : GCCBuiltin<"__builtin_ia32_loadhpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_sse2_loadl_pd : GCCBuiltin<"__builtin_ia32_loadlpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_ptr_ty], [IntrReadMem]>;
+ def int_x86_sse2_shuf_pd : GCCBuiltin<"__builtin_ia32_shufpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty, llvm_i32_ty], [IntrNoMem]>;
+ def int_x86_sse2_unpckh_pd : GCCBuiltin<"__builtin_ia32_unpckhpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_unpckl_pd : GCCBuiltin<"__builtin_ia32_unpcklpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse2_punpckh_qdq : GCCBuiltin<"__builtin_ia32_punpckhqdq128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+ def int_x86_sse2_punpckl_qdq : GCCBuiltin<"__builtin_ia32_punpcklqdq128">,
+ Intrinsic<[llvm_v2i64_ty, llvm_v2i64_ty,
+ llvm_v2i64_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSE3
+
+// Addition / subtraction ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_addsub_ps : GCCBuiltin<"__builtin_ia32_addsubps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_addsub_pd : GCCBuiltin<"__builtin_ia32_addsubpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Horizontal ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_hadd_ps : GCCBuiltin<"__builtin_ia32_haddps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_hadd_pd : GCCBuiltin<"__builtin_ia32_haddpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+ def int_x86_sse3_hsub_ps : GCCBuiltin<"__builtin_ia32_hsubps">,
+ Intrinsic<[llvm_v4f32_ty, llvm_v4f32_ty,
+ llvm_v4f32_ty], [IntrNoMem]>;
+ def int_x86_sse3_hsub_pd : GCCBuiltin<"__builtin_ia32_hsubpd">,
+ Intrinsic<[llvm_v2f64_ty, llvm_v2f64_ty,
+ llvm_v2f64_ty], [IntrNoMem]>;
+}
+
+// Specialized unaligned load.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_ldu_dq : GCCBuiltin<"__builtin_ia32_lddqu">,
+ Intrinsic<[llvm_v16i8_ty, llvm_ptr_ty], [IntrReadMem]>;
+}
+
+// Thread synchronization ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_sse3_monitor : GCCBuiltin<"__builtin_ia32_monitor">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_i32_ty, llvm_i32_ty], [IntrWriteMem]>;
+ def int_x86_sse3_mwait : GCCBuiltin<"__builtin_ia32_mwait">,
+ Intrinsic<[llvm_void_ty, llvm_i32_ty,
+ llvm_i32_ty], [IntrWriteMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// SSSE3
+
+// FP arithmetic ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_ssse3_pmulhrsw_128 : GCCBuiltin<"__builtin_ia32_pmulhrsw128">,
+ Intrinsic<[llvm_v8i16_ty, llvm_v8i16_ty,
+ llvm_v8i16_ty], [IntrNoMem]>;
+}
+
+//===----------------------------------------------------------------------===//
+// MMX
+
+// Empty MMX state op.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_emms : GCCBuiltin<"__builtin_ia32_emms">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+ def int_x86_mmx_femms : GCCBuiltin<"__builtin_ia32_femms">,
+ Intrinsic<[llvm_void_ty], [IntrWriteMem]>;
+}
+
+// Integer arithmetic ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // Addition
+ def int_x86_mmx_padds_b : GCCBuiltin<"__builtin_ia32_paddsb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_padds_w : GCCBuiltin<"__builtin_ia32_paddsw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_paddus_b : GCCBuiltin<"__builtin_ia32_paddusb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_paddus_w : GCCBuiltin<"__builtin_ia32_paddusw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Subtraction
+ def int_x86_mmx_psubs_b : GCCBuiltin<"__builtin_ia32_psubsb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_psubs_w : GCCBuiltin<"__builtin_ia32_psubsw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psubus_b : GCCBuiltin<"__builtin_ia32_psubusb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_psubus_w : GCCBuiltin<"__builtin_ia32_psubusw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Multiplication
+ def int_x86_mmx_pmulh_w : GCCBuiltin<"__builtin_ia32_pmulhw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+ def int_x86_mmx_pmulhu_w : GCCBuiltin<"__builtin_ia32_pmulhuw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+ def int_x86_mmx_pmulu_dq : GCCBuiltin<"__builtin_ia32_pmuludq">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_pmadd_wd : GCCBuiltin<"__builtin_ia32_pmaddwd">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Averages
+ def int_x86_mmx_pavg_b : GCCBuiltin<"__builtin_ia32_pavgb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_pavg_w : GCCBuiltin<"__builtin_ia32_pavgw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Maximum
+ def int_x86_mmx_pmaxu_b : GCCBuiltin<"__builtin_ia32_pmaxub">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_pmaxs_w : GCCBuiltin<"__builtin_ia32_pmaxsw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Minimum
+ def int_x86_mmx_pminu_b : GCCBuiltin<"__builtin_ia32_pminub">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_pmins_w : GCCBuiltin<"__builtin_ia32_pminsw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+
+ // Packed sum of absolute differences
+ def int_x86_mmx_psad_bw : GCCBuiltin<"__builtin_ia32_psadbw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+}
+
+// Integer shift ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ // Shift left logical
+ def int_x86_mmx_psll_w : GCCBuiltin<"__builtin_ia32_psllw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psll_d : GCCBuiltin<"__builtin_ia32_pslld">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psll_q : GCCBuiltin<"__builtin_ia32_psllq">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psrl_w : GCCBuiltin<"__builtin_ia32_psrlw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrl_d : GCCBuiltin<"__builtin_ia32_psrld">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psrl_q : GCCBuiltin<"__builtin_ia32_psrlq">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_psra_w : GCCBuiltin<"__builtin_ia32_psraw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_psra_d : GCCBuiltin<"__builtin_ia32_psrad">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+}
+
+// Pack ops.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_packsswb : GCCBuiltin<"__builtin_ia32_packsswb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+ def int_x86_mmx_packssdw : GCCBuiltin<"__builtin_ia32_packssdw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+ def int_x86_mmx_packuswb : GCCBuiltin<"__builtin_ia32_packuswb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+}
+
+// Integer comparison ops
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_pcmpeq_b : GCCBuiltin<"__builtin_ia32_pcmpeqb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpeq_w : GCCBuiltin<"__builtin_ia32_pcmpeqw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpeq_d : GCCBuiltin<"__builtin_ia32_pcmpeqd">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_pcmpgt_b : GCCBuiltin<"__builtin_ia32_pcmpgtb">,
+ Intrinsic<[llvm_v8i8_ty, llvm_v8i8_ty,
+ llvm_v8i8_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpgt_w : GCCBuiltin<"__builtin_ia32_pcmpgtw">,
+ Intrinsic<[llvm_v4i16_ty, llvm_v4i16_ty,
+ llvm_v4i16_ty], [IntrNoMem]>;
+ def int_x86_mmx_pcmpgt_d : GCCBuiltin<"__builtin_ia32_pcmpgtd">,
+ Intrinsic<[llvm_v2i32_ty, llvm_v2i32_ty,
+ llvm_v2i32_ty], [IntrNoMem]>;
+}
+
+// Misc.
+let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
+ def int_x86_mmx_maskmovq : GCCBuiltin<"__builtin_ia32_maskmovq">,
+ Intrinsic<[llvm_void_ty, llvm_v8i8_ty, llvm_v8i8_ty, llvm_ptr_ty],
+ [IntrWriteMem]>;
+
+ def int_x86_mmx_pmovmskb : GCCBuiltin<"__builtin_ia32_pmovmskb">,
+ Intrinsic<[llvm_i32_ty, llvm_v8i8_ty], [IntrNoMem]>;
+
+ def int_x86_mmx_movnt_dq : GCCBuiltin<"__builtin_ia32_movntq">,
+ Intrinsic<[llvm_void_ty, llvm_ptr_ty,
+ llvm_v1i64_ty], [IntrWriteMem]>;
+}
diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h
new file mode 100644
index 0000000..b445ba0
--- /dev/null
+++ b/include/llvm/LinkAllPasses.h
@@ -0,0 +1,127 @@
+//===- llvm/LinkAllPasses.h ------------ Reference All Passes ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Jeff Cohen and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all transformation and analysis passes for tools
+// like opt and bugpoint that need this functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKALLPASSES_H
+#define LLVM_LINKALLPASSES_H
+
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Analysis/IntervalPartition.h"
+#include "llvm/Analysis/LoadValueNumbering.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/Function.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include <cstdlib>
+
+namespace {
+ struct ForcePassLinking {
+ ForcePassLinking() {
+ // We must reference the passes in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+
+ (void) llvm::createAAEvalPass();
+ (void) llvm::createAggressiveDCEPass();
+ (void) llvm::createAliasAnalysisCounterPass();
+ (void) llvm::createAliasDebugger();
+ (void) llvm::createAndersensPass();
+ (void) llvm::createArgumentPromotionPass();
+ (void) llvm::createBasicAliasAnalysisPass();
+ (void) llvm::createBasicVNPass();
+ (void) llvm::createBlockPlacementPass();
+ (void) llvm::createBlockProfilerPass();
+ (void) llvm::createBreakCriticalEdgesPass();
+ (void) llvm::createCFGSimplificationPass();
+ (void) llvm::createConstantMergePass();
+ (void) llvm::createConstantPropagationPass();
+ (void) llvm::createCorrelatedExpressionEliminationPass();
+ (void) llvm::createDeadArgEliminationPass();
+ (void) llvm::createDeadCodeEliminationPass();
+ (void) llvm::createDeadInstEliminationPass();
+ (void) llvm::createDeadStoreEliminationPass();
+ (void) llvm::createDeadTypeEliminationPass();
+ (void) llvm::createEdgeProfilerPass();
+ (void) llvm::createFastDeadStoreEliminationPass();
+ (void) llvm::createFunctionInliningPass();
+ (void) llvm::createFunctionProfilerPass();
+ (void) llvm::createGCSEPass();
+ (void) llvm::createGlobalDCEPass();
+ (void) llvm::createGlobalOptimizerPass();
+ (void) llvm::createGlobalsModRefPass();
+ (void) llvm::createGVNPREPass();
+ (void) llvm::createIPConstantPropagationPass();
+ (void) llvm::createIPSCCPPass();
+ (void) llvm::createIndVarSimplifyPass();
+ (void) llvm::createInstructionCombiningPass();
+ (void) llvm::createInternalizePass(false);
+ (void) llvm::createLCSSAPass();
+ (void) llvm::createLICMPass();
+ (void) llvm::createLoadValueNumberingPass();
+ (void) llvm::createLoopExtractorPass();
+ (void) llvm::createLoopSimplifyPass();
+ (void) llvm::createLoopStrengthReducePass();
+ (void) llvm::createLoopUnrollPass();
+ (void) llvm::createLoopUnswitchPass();
+ (void) llvm::createLoopRotatePass();
+ (void) llvm::createLowerAllocationsPass();
+ (void) llvm::createLowerGCPass();
+ (void) llvm::createLowerInvokePass();
+ (void) llvm::createLowerPackedPass();
+ (void) llvm::createLowerSelectPass();
+ (void) llvm::createLowerSetJmpPass();
+ (void) llvm::createLowerSwitchPass();
+ (void) llvm::createNoAAPass();
+ (void) llvm::createNoProfileInfoPass();
+ (void) llvm::createProfileLoaderPass();
+ (void) llvm::createPromoteMemoryToRegisterPass();
+ (void) llvm::createDemoteRegisterToMemoryPass();
+ (void) llvm::createPruneEHPass();
+ (void) llvm::createRaiseAllocationsPass();
+ (void) llvm::createReassociatePass();
+ (void) llvm::createSCCPPass();
+ (void) llvm::createScalarReplAggregatesPass();
+ (void) llvm::createSimplifyLibCallsPass();
+ (void) llvm::createSingleLoopExtractorPass();
+ (void) llvm::createStripSymbolsPass();
+ (void) llvm::createTailCallEliminationPass();
+ (void) llvm::createTailDuplicationPass();
+ (void) llvm::createUnifyFunctionExitNodesPass();
+ (void) llvm::createCondPropagationPass();
+ (void) llvm::createNullProfilerRSPass();
+ (void) llvm::createRSProfilingPass();
+ (void) llvm::createIndMemRemPass();
+ (void) llvm::createInstCountPass();
+ (void) llvm::createPredicateSimplifierPass();
+ (void) llvm::createCodeGenPreparePass();
+
+ (void)new llvm::IntervalPartition();
+ (void)new llvm::FindUsedTypes();
+ (void)new llvm::ScalarEvolution();
+ ((llvm::Function*)0)->viewCFGOnly();
+ llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0);
+ X.add((llvm::Value*)0, 0); // for -print-alias-sets
+ }
+ } ForcePassLinking; // Force link by creating a global definition.
+}
+
+#endif
diff --git a/include/llvm/LinkAllVMCore.h b/include/llvm/LinkAllVMCore.h
new file mode 100644
index 0000000..ae1e1cd
--- /dev/null
+++ b/include/llvm/LinkAllVMCore.h
@@ -0,0 +1,57 @@
+//===- LinkAllVMCore.h - Reference All VMCore Code --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file pulls in all the object modules of the VMCore library so
+// that tools like llc, opt, and lli can ensure they are linked with all symbols
+// from libVMCore.a It should only be used from a tool's main program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKALLVMCORE_H
+#define LLVM_LINKALLVMCORE_H
+
+#include "llvm/System/IncludeFile.h"
+
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/System/Alarm.h"
+#include "llvm/System/DynamicLibrary.h"
+#include "llvm/System/MappedFile.h"
+#include "llvm/System/Memory.h"
+#include "llvm/System/Mutex.h"
+#include "llvm/System/Path.h"
+#include "llvm/System/Process.h"
+#include "llvm/System/Program.h"
+#include "llvm/System/Signals.h"
+#include "llvm/System/TimeValue.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Mangler.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/SlowOperationInformer.h"
+
+namespace {
+ struct ForceVMCoreLinking {
+ ForceVMCoreLinking() {
+ // We must reference VMCore in such a way that compilers will not
+ // delete it all as dead code, even with whole program optimization,
+ // yet is effectively a NO-OP. As the compiler isn't smart enough
+ // to know that getenv() never returns -1, this will do the job.
+ if (std::getenv("bar") != (char*) -1)
+ return;
+ (void)new llvm::Module("");
+ (void)new llvm::UnreachableInst();
+ (void) llvm::createVerifierPass();
+ }
+ } ForceVMCoreLinking;
+}
+
+#endif
diff --git a/include/llvm/LinkTimeOptimizer.h b/include/llvm/LinkTimeOptimizer.h
new file mode 100644
index 0000000..164232d
--- /dev/null
+++ b/include/llvm/LinkTimeOptimizer.h
@@ -0,0 +1,153 @@
+//===-- llvm/LinkTimeOptimizer.h - Public Interface ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header provides public interface to use LLVM link time optimization
+// library. This is intended to be used by linker to do link time optimization.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef __LTO_H__
+#define __LTO_H__
+
+#include <string>
+#include <vector>
+#include <set>
+#include <llvm/ADT/hash_map>
+
+namespace llvm {
+
+ class Module;
+ class GlobalValue;
+ class TargetMachine;
+
+ enum LTOStatus {
+ LTO_UNKNOWN,
+ LTO_OPT_SUCCESS,
+ LTO_READ_SUCCESS,
+ LTO_READ_FAILURE,
+ LTO_WRITE_FAILURE,
+ LTO_NO_TARGET,
+ LTO_NO_WORK,
+ LTO_MODULE_MERGE_FAILURE,
+ LTO_ASM_FAILURE
+ };
+
+ enum LTOLinkageTypes {
+ LTOExternalLinkage, // Externally visible function
+ LTOLinkOnceLinkage, // Keep one copy of named function when linking (inline)
+ LTOWeakLinkage, // Keep one copy of named function when linking (weak)
+ LTOInternalLinkage // Rename collisions when linking (static functions)
+ };
+
+ /// This class represents LLVM symbol information without exposing details
+ /// of LLVM global values. It encapsulates symbol linkage information. This
+ /// is typically used in hash_map where associated name identifies the
+ /// the symbol name.
+ class LLVMSymbol {
+
+ public:
+
+ LTOLinkageTypes getLinkage() const { return linkage; }
+ void mayBeNotUsed();
+
+ LLVMSymbol (enum LTOLinkageTypes lt, GlobalValue *g, const std::string &n,
+ const std::string &m, int a) : linkage(lt), gv(g), name(n),
+ mangledName(m), alignment(a) {}
+
+ const char *getName() { return name.c_str(); }
+ const char *getMangledName() { return mangledName.c_str(); }
+ int getAlignment() { return alignment; }
+
+ private:
+ enum LTOLinkageTypes linkage;
+ GlobalValue *gv;
+ std::string name;
+ std::string mangledName;
+ int alignment;
+ };
+
+ class string_compare {
+ public:
+ bool operator()(const char* left, const char* right) const {
+ return (strcmp(left, right) == 0);
+ }
+ };
+
+ /// This is abstract class to facilitate dlopen() interface.
+ /// See LTO below for more info.
+ class LinkTimeOptimizer {
+ public:
+ typedef hash_map<const char*, LLVMSymbol*, hash<const char*>,
+ string_compare> NameToSymbolMap;
+ typedef hash_map<const char*, Module*, hash<const char*>,
+ string_compare> NameToModuleMap;
+ virtual enum LTOStatus readLLVMObjectFile(const std::string &,
+ NameToSymbolMap &,
+ std::set<std::string> &) = 0;
+ virtual enum LTOStatus optimizeModules(const std::string &,
+ std::vector<const char*> &,
+ std::string &, bool,
+ const char *) = 0;
+ virtual void getTargetTriple(const std::string &, std::string &) = 0;
+ virtual void removeModule (const std::string &InputFilename) = 0;
+ virtual void printVersion () = 0;
+ virtual ~LinkTimeOptimizer() = 0;
+ };
+
+ /// This is the main link time optimization class. It exposes simple API
+ /// to perform link time optimization using LLVM intermodular optimizer.
+ class LTO : public LinkTimeOptimizer {
+
+ public:
+ typedef hash_map<const char*, LLVMSymbol*, hash<const char*>,
+ string_compare> NameToSymbolMap;
+ typedef hash_map<const char*, Module*, hash<const char*>,
+ string_compare> NameToModuleMap;
+
+ enum LTOStatus readLLVMObjectFile(const std::string &InputFilename,
+ NameToSymbolMap &symbols,
+ std::set<std::string> &references);
+ enum LTOStatus optimizeModules(const std::string &OutputFilename,
+ std::vector<const char*> &exportList,
+ std::string &targetTriple, bool saveTemps,
+ const char *);
+ void getTargetTriple(const std::string &InputFilename,
+ std::string &targetTriple);
+ void removeModule (const std::string &InputFilename);
+ void printVersion();
+
+ // Constructors and destructors
+ LTO() {
+ /// TODO: Use Target info, it is available at this time.
+ Target = NULL;
+ }
+ ~LTO();
+
+ private:
+ Module *getModule (const std::string &InputFilename);
+ enum LTOStatus optimize(Module *, std::ostream &,
+ std::vector<const char *> &);
+ void getTarget(Module *);
+
+ private:
+ std::vector<Module *> modules;
+ NameToSymbolMap allSymbols;
+ NameToModuleMap allModules;
+ TargetMachine *Target;
+ };
+
+} // End llvm namespace
+
+/// This provides C interface to initialize link time optimizer. This allows
+/// linker to use dlopen() interface to dynamically load LinkTimeOptimizer.
+/// extern "C" helps, because dlopen() interface uses name to find the symbol.
+extern "C"
+llvm::LinkTimeOptimizer *createLLVMOptimizer();
+
+#endif
diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h
new file mode 100644
index 0000000..cc0372d
--- /dev/null
+++ b/include/llvm/Linker.h
@@ -0,0 +1,297 @@
+//===- llvm/Linker.h - Module Linker Interface ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interface to the module/file/archive linker.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LINKER_H
+#define LLVM_LINKER_H
+
+#include "llvm/System/Path.h"
+#include <vector>
+#include <memory>
+
+namespace llvm {
+
+class Module;
+
+/// This class provides the core functionality of linking in LLVM. It retains a
+/// Module object which is the composite of the modules and libraries linked
+/// into it. The composite Module can be retrieved via the getModule() method.
+/// In this case the Linker still retains ownership of the Module. If the
+/// releaseModule() method is used, the ownership of the Module is transferred
+/// to the caller and the Linker object is only suitable for destruction.
+/// The Linker can link Modules from memory, bitcode files, or bitcode
+/// archives. It retains a set of search paths in which to find any libraries
+/// presented to it. By default, the linker will generate error and warning
+/// messages to std::cerr but this capability can be turned off with the
+/// QuietWarnings and QuietErrors flags. It can also be instructed to verbosely
+/// print out the linking actions it is taking with the Verbose flag.
+/// @brief The LLVM Linker.
+class Linker {
+
+ /// @name Types
+ /// @{
+ public:
+ /// This type is used to pass the linkage items (libraries and files) to
+ /// the LinkItems function. It is composed of string/bool pairs. The string
+ /// provides the name of the file or library (as with the -l option). The
+ /// bool should be true for libraries and false for files, signifying
+ /// "isLibrary".
+ /// @brief A list of linkage items
+ typedef std::vector<std::pair<std::string,bool> > ItemList;
+
+ /// This enumeration is used to control various optional features of the
+ /// linker.
+ enum ControlFlags {
+ Verbose = 1, ///< Print to std::cerr what steps the linker is taking
+ QuietWarnings = 2, ///< Don't print errors and warnings to std::cerr.
+ QuietErrors = 4 ///< Indicate that this link is for a native executable
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct the Linker with an empty module which will be given the
+ /// name \p progname. \p progname will also be used for error messages.
+ /// @brief Construct with empty module
+ Linker(
+ const std::string& progname, ///< name of tool running linker
+ const std::string& modulename, ///< name of linker's end-result module
+ unsigned Flags = 0 ///< ControlFlags (one or more |'d together)
+ );
+
+ /// Construct the Linker with a previously defined module, \p aModule. Use
+ /// \p progname for the name of the program in error messages.
+ /// @brief Construct with existing module
+ Linker(const std::string& progname, Module* aModule, unsigned Flags = 0);
+
+ /// Destruct the Linker.
+ /// @brief Destructor
+ ~Linker();
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// This method gets the composite module into which linking is being
+ /// done. The Composite module starts out empty and accumulates modules
+ /// linked into it via the various LinkIn* methods. This method does not
+ /// release the Module to the caller. The Linker retains ownership and will
+ /// destruct the Module when the Linker is destructed.
+ /// @see releaseModule
+ /// @brief Get the linked/composite module.
+ Module* getModule() const { return Composite; }
+
+ /// This method releases the composite Module into which linking is being
+ /// done. Ownership of the composite Module is transferred to the caller who
+ /// must arrange for its destruct. After this method is called, the Linker
+ /// terminates the linking session for the returned Module. It will no
+ /// longer utilize the returned Module but instead resets itself for
+ /// subsequent linking as if the constructor had been called. The Linker's
+ /// LibPaths and flags to be reset, and memory will be released.
+ /// @brief Release the linked/composite module.
+ Module* releaseModule();
+
+ /// This method gets the list of libraries that form the path that the
+ /// Linker will search when it is presented with a library name.
+ /// @brief Get the Linkers library path
+ const std::vector<sys::Path>& getLibPaths() const { return LibPaths; }
+
+ /// This method returns an error string suitable for printing to the user.
+ /// The return value will be empty unless an error occurred in one of the
+ /// LinkIn* methods. In those cases, the LinkIn* methods will have returned
+ /// true, indicating an error occurred. At most one error is retained so
+ /// this function always returns the last error that occurred. Note that if
+ /// the Quiet control flag is not set, the error string will have already
+ /// been printed to std::cerr.
+ /// @brief Get the text of the last error that occurred.
+ const std::string& getLastError() const { return Error; }
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// Add a path to the list of paths that the Linker will search. The Linker
+ /// accumulates the set of libraries added
+ /// library paths for the target platform. The standard libraries will
+ /// always be searched last. The added libraries will be searched in the
+ /// order added.
+ /// @brief Add a path.
+ void addPath(const sys::Path& path);
+
+ /// Add a set of paths to the list of paths that the linker will search. The
+ /// Linker accumulates the set of libraries added. The \p paths will be
+ /// added to the end of the Linker's list. Order will be retained.
+ /// @brief Add a set of paths.
+ void addPaths(const std::vector<std::string>& paths);
+
+ /// This method augments the Linker's list of library paths with the system
+ /// paths of the host operating system, include LLVM_LIB_SEARCH_PATH.
+ /// @brief Add the system paths.
+ void addSystemPaths();
+
+ /// Control optional linker behavior by setting a group of flags. The flags
+ /// are defined in the ControlFlags enumeration.
+ /// @see ControlFlags
+ /// @brief Set control flags.
+ void setFlags(unsigned flags) { Flags = flags; }
+
+ /// This method is the main interface to the linker. It can be used to
+ /// link a set of linkage items into a module. A linkage item is either a
+ /// file name with fully qualified path, or a library for which the Linker's
+ /// LibraryPath will be utilized to locate the library. The bool value in
+ /// the LinkItemKind should be set to true for libraries. This function
+ /// allows linking to preserve the order of specification associated with
+ /// the command line, or for other purposes. Each item will be linked in
+ /// turn as it occurs in \p Items.
+ /// @returns true if an error occurred, false otherwise
+ /// @see LinkItemKind
+ /// @see getLastError
+ /// @throws nothing
+ bool LinkInItems (
+ const ItemList& Items, ///< Set of libraries/files to link in
+ ItemList& NativeItems ///< Output list of native files/libs
+ );
+
+ /// This function links the bitcode \p Files into the composite module.
+ /// Note that this does not do any linking of unresolved symbols. The \p
+ /// Files are all completely linked into \p HeadModule regardless of
+ /// unresolved symbols. This function just loads each bitcode file and
+ /// calls LinkInModule on them.
+ /// @returns true if an error occurs, false otherwise
+ /// @see getLastError
+ /// @brief Link in multiple files.
+ bool LinkInFiles (
+ const std::vector<sys::Path> & Files ///< Files to link in
+ );
+
+ /// This function links a single bitcode file, \p File, into the composite
+ /// module. Note that this does not attempt to resolve symbols. This method
+ /// just loads the bitcode file and calls LinkInModule on it. If an error
+ /// occurs, the Linker's error string is set.
+ /// @returns true if an error occurs, false otherwise
+ /// @see getLastError
+ /// @brief Link in a single file.
+ bool LinkInFile(
+ const sys::Path& File, ///< File to link in.
+ bool &is_native ///< Indicates if the file is native object file
+ );
+
+ /// This function provides a way to selectively link in a set of modules,
+ /// found in libraries, based on the unresolved symbols in the composite
+ /// module. Each item in \p Libraries should be the base name of a library,
+ /// as if given with the -l option of a linker tool. The Linker's LibPaths
+ /// are searched for the \p Libraries and any found will be linked in with
+ /// LinkInArchive. If an error occurs, the Linker's error string is set.
+ /// @see LinkInArchive
+ /// @see getLastError
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Link libraries into the module
+ bool LinkInLibraries (
+ const std::vector<std::string> & Libraries ///< Libraries to link in
+ );
+
+ /// This function provides a way to selectively link in a set of modules,
+ /// found in one library, based on the unresolved symbols in the composite
+ /// module.The \p Library should be the base name of a library, as if given
+ /// with the -l option of a linker tool. The Linker's LibPaths are searched
+ /// for the \P Library and if found, it will be linked in with via the
+ /// LinkInArchive method. If an error occurs, the Linker's error string is
+ /// set.
+ /// @see LinkInArchive
+ /// @see getLastError
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Link one library into the module
+ bool LinkInLibrary (
+ const std::string& Library, ///< The library to link in
+ bool& is_native ///< Indicates if lib a native library
+ );
+
+ /// This function links one bitcode archive, \p Filename, into the module.
+ /// The archive is searched to resolve outstanding symbols. Any modules in
+ /// the archive that resolve outstanding symbols will be linked in. The
+ /// library is searched repeatedly until no more modules that resolve
+ /// symbols can be found. If an error occurs, the error string is set.
+ /// To speed up this function, ensure the the archive has been processed
+ /// llvm-ranlib or the S option was given to llvm-ar when the archive was
+ /// created. These tools add a symbol table to the archive which makes the
+ /// search for undefined symbols much faster.
+ /// @see getLastError
+ /// @returns true if an error occurs, otherwise false.
+ /// @brief Link in one archive.
+ bool LinkInArchive(
+ const sys::Path& Filename, ///< Filename of the archive to link
+ bool& is_native ///< Indicates if archive is a native archive
+ );
+
+ /// This method links the \p Src module into the Linker's Composite module
+ /// by calling LinkModules. All the other LinkIn* methods eventually
+ /// result in calling this method to link a Module into the Linker's
+ /// composite.
+ /// @see LinkModules
+ /// @returns True if an error occurs, false otherwise.
+ /// @brief Link in a module.
+ bool LinkInModule(
+ Module* Src, ///< Module linked into \p Dest
+ std::string* ErrorMsg = 0 /// Error/diagnostic string
+ ) {
+ return LinkModules(Composite, Src, ErrorMsg );
+ }
+
+ /// This is the heart of the linker. This method will take unconditional
+ /// control of the \p Src module and link it into the \p Dest module. The
+ /// \p Src module will be destructed or subsumed by this method. In either
+ /// case it is not usable by the caller after this method is invoked. Only
+ /// the \p Dest module will remain. The \p Src module is linked into the
+ /// Linker's composite module such that types, global variables, functions,
+ /// and etc. are matched and resolved. If an error occurs, this function
+ /// returns true and ErrorMsg is set to a descriptive message about the
+ /// error.
+ /// @returns True if an error occurs, false otherwise.
+ /// @brief Generically link two modules together.
+ static bool LinkModules(Module* Dest, Module* Src, std::string* ErrorMsg);
+
+ /// This function looks through the Linker's LibPaths to find a library with
+ /// the name \p Filename. If the library cannot be found, the returned path
+ /// will be empty (i.e. sys::Path::isEmpty() will return true).
+ /// @returns A sys::Path to the found library
+ /// @brief Find a library from its short name.
+ sys::Path FindLib(const std::string &Filename);
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// Read in and parse the bitcode file named by FN and return the
+ /// Module it contains (wrapped in an auto_ptr), or 0 if an error occurs.
+ std::auto_ptr<Module> LoadObject(const sys::Path& FN);
+
+ bool warning(const std::string& message);
+ bool error(const std::string& message);
+ void verbose(const std::string& message);
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ Module* Composite; ///< The composite module linked together
+ std::vector<sys::Path> LibPaths; ///< The library search paths
+ unsigned Flags; ///< Flags to control optional behavior.
+ std::string Error; ///< Text of error that occurred.
+ std::string ProgramName; ///< Name of the program being linked
+ /// @}
+
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Module.h b/include/llvm/Module.h
new file mode 100644
index 0000000..9bd02ec
--- /dev/null
+++ b/include/llvm/Module.h
@@ -0,0 +1,425 @@
+//===-- llvm/Module.h - C++ class to represent a VM module ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// @file This file contains the declarations for the Module class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MODULE_H
+#define LLVM_MODULE_H
+
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/GlobalAlias.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+
+namespace llvm {
+
+class GlobalValueRefMap; // Used by ConstantVals.cpp
+class FunctionType;
+
+template<> struct ilist_traits<Function>
+ : public SymbolTableListTraits<Function, Module> {
+ // createSentinel is used to create a node that marks the end of the list.
+ static Function *createSentinel();
+ static void destroySentinel(Function *F) { delete F; }
+ static iplist<Function> &getList(Module *M);
+ static inline ValueSymbolTable *getSymTab(Module *M);
+ static int getListOffset();
+};
+template<> struct ilist_traits<GlobalVariable>
+ : public SymbolTableListTraits<GlobalVariable, Module> {
+ // createSentinel is used to create a node that marks the end of the list.
+ static GlobalVariable *createSentinel();
+ static void destroySentinel(GlobalVariable *GV) { delete GV; }
+ static iplist<GlobalVariable> &getList(Module *M);
+ static inline ValueSymbolTable *getSymTab(Module *M);
+ static int getListOffset();
+};
+template<> struct ilist_traits<GlobalAlias>
+ : public SymbolTableListTraits<GlobalAlias, Module> {
+ // createSentinel is used to create a node that marks the end of the list.
+ static GlobalAlias *createSentinel();
+ static void destroySentinel(GlobalAlias *GA) { delete GA; }
+ static iplist<GlobalAlias> &getList(Module *M);
+ static inline ValueSymbolTable *getSymTab(Module *M);
+ static int getListOffset();
+};
+
+/// A Module instance is used to store all the information related to an
+/// LLVM module. Modules are the top level container of all other LLVM
+/// Intermediate Representation (IR) objects. Each module directly contains a
+/// list of globals variables, a list of functions, a list of libraries (or
+/// other modules) this module depends on, a symbol table, and various data
+/// about the target's characteristics.
+///
+/// A module maintains a GlobalValRefMap object that is used to hold all
+/// constant references to global variables in the module. When a global
+/// variable is destroyed, it should have no entries in the GlobalValueRefMap.
+/// @brief The main container class for the LLVM Intermediate Representation.
+class Module {
+/// @name Types And Enumerations
+/// @{
+public:
+ /// The type for the list of global variables.
+ typedef iplist<GlobalVariable> GlobalListType;
+ /// The type for the list of functions.
+ typedef iplist<Function> FunctionListType;
+ /// The type for the list of aliases.
+ typedef iplist<GlobalAlias> AliasListType;
+
+ /// The type for the list of dependent libraries.
+ typedef std::vector<std::string> LibraryListType;
+
+ /// The Global Variable iterator.
+ typedef GlobalListType::iterator global_iterator;
+ /// The Global Variable constant iterator.
+ typedef GlobalListType::const_iterator const_global_iterator;
+
+ /// The Function iterators.
+ typedef FunctionListType::iterator iterator;
+ /// The Function constant iterator
+ typedef FunctionListType::const_iterator const_iterator;
+
+ /// The Global Alias iterators.
+ typedef AliasListType::iterator alias_iterator;
+ /// The Global Alias constant iterator
+ typedef AliasListType::const_iterator const_alias_iterator;
+
+ /// The Library list iterator.
+ typedef LibraryListType::const_iterator lib_iterator;
+
+ /// An enumeration for describing the endianess of the target machine.
+ enum Endianness { AnyEndianness, LittleEndian, BigEndian };
+
+ /// An enumeration for describing the size of a pointer on the target machine.
+ enum PointerSize { AnyPointerSize, Pointer32, Pointer64 };
+
+/// @}
+/// @name Member Variables
+/// @{
+private:
+ GlobalListType GlobalList; ///< The Global Variables in the module
+ FunctionListType FunctionList; ///< The Functions in the module
+ AliasListType AliasList; ///< The Aliases in the module
+ LibraryListType LibraryList; ///< The Libraries needed by the module
+ std::string GlobalScopeAsm; ///< Inline Asm at global scope.
+ ValueSymbolTable *ValSymTab; ///< Symbol table for values
+ TypeSymbolTable *TypeSymTab; ///< Symbol table for types
+ std::string ModuleID; ///< Human readable identifier for the module
+ std::string TargetTriple; ///< Platform target triple Module compiled on
+ std::string DataLayout; ///< Target data description
+
+ friend class Constant;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+ /// The Module constructor. Note that there is no default constructor. You
+ /// must provide a name for the module upon construction.
+ explicit Module(const std::string &ModuleID);
+ /// The module destructor. This will dropAllReferences.
+ ~Module();
+
+/// @}
+/// @name Module Level Accessors
+/// @{
+public:
+ /// Get the module identifier which is, essentially, the name of the module.
+ /// @returns the module identifier as a string
+ const std::string &getModuleIdentifier() const { return ModuleID; }
+
+ /// Get the data layout string for the module's target platform. This encodes
+ /// the type sizes and alignments expected by this module.
+ /// @returns the data layout as a string
+ const std::string& getDataLayout() const { return DataLayout; }
+
+ /// Get the target triple which is a string describing the target host.
+ /// @returns a string containing the target triple.
+ const std::string &getTargetTriple() const { return TargetTriple; }
+
+ /// Get the target endian information.
+ /// @returns Endianess - an enumeration for the endianess of the target
+ Endianness getEndianness() const;
+
+ /// Get the target pointer size.
+ /// @returns PointerSize - an enumeration for the size of the target's pointer
+ PointerSize getPointerSize() const;
+
+ /// Get any module-scope inline assembly blocks.
+ /// @returns a string containing the module-scope inline assembly blocks.
+ const std::string &getModuleInlineAsm() const { return GlobalScopeAsm; }
+/// @}
+/// @name Module Level Mutators
+/// @{
+public:
+
+ /// Set the module identifier.
+ void setModuleIdentifier(const std::string &ID) { ModuleID = ID; }
+
+ /// Set the data layout
+ void setDataLayout(const std::string& DL) { DataLayout = DL; }
+
+ /// Set the target triple.
+ void setTargetTriple(const std::string &T) { TargetTriple = T; }
+
+ /// Set the module-scope inline assembly blocks.
+ void setModuleInlineAsm(const std::string &Asm) { GlobalScopeAsm = Asm; }
+
+ /// Append to the module-scope inline assembly blocks, automatically
+ /// appending a newline to the end.
+ void appendModuleInlineAsm(const std::string &Asm) {
+ GlobalScopeAsm += Asm;
+ GlobalScopeAsm += '\n';
+ }
+
+/// @}
+/// @name Function Accessors
+/// @{
+public:
+ /// getOrInsertFunction - Look up the specified function in the module symbol
+ /// table. Four possibilities:
+ /// 1. If it does not exist, add a prototype for the function and return it.
+ /// 2. If it exists, and has internal linkage, the existing function is
+ /// renamed and a new one is inserted.
+ /// 3. Otherwise, if the existing function has the correct prototype, return
+ /// the existing function.
+ /// 4. Finally, the function exists but has the wrong prototype: return the
+ /// function with a constantexpr cast to the right prototype.
+ Constant *getOrInsertFunction(const std::string &Name, const FunctionType *T);
+
+ /// getOrInsertFunction - Look up the specified function in the module symbol
+ /// table. If it does not exist, add a prototype for the function and return
+ /// it. This function guarantees to return a constant of pointer to the
+ /// specified function type or a ConstantExpr BitCast of that type if the
+ /// named function has a different type. This version of the method takes a
+ /// null terminated list of function arguments, which makes it easier for
+ /// clients to use.
+ Constant *getOrInsertFunction(const std::string &Name, const Type *RetTy,...)
+ END_WITH_NULL;
+
+ /// getFunction - Look up the specified function in the module symbol table.
+ /// If it does not exist, return null.
+ Function *getFunction(const std::string &Name) const;
+
+/// @}
+/// @name Global Variable Accessors
+/// @{
+public:
+ /// getGlobalVariable - Look up the specified global variable in the module
+ /// symbol table. If it does not exist, return null. The type argument
+ /// should be the underlying type of the global, i.e., it should not have
+ /// the top-level PointerType, which represents the address of the global.
+ /// If AllowInternal is set to true, this function will return types that
+ /// have InternalLinkage. By default, these types are not returned.
+ GlobalVariable *getGlobalVariable(const std::string &Name,
+ bool AllowInternal = false) const;
+
+ /// getNamedGlobal - Return the first global variable in the module with the
+ /// specified name, of arbitrary type. This method returns null if a global
+ /// with the specified name is not found.
+ GlobalVariable *getNamedGlobal(const std::string &Name) const {
+ return getGlobalVariable(Name, true);
+ }
+
+/// @}
+/// @name Global Variable Accessors
+/// @{
+public:
+ /// getNamedGlobal - Return the first global alias in the module with the
+ /// specified name, of arbitrary type. This method returns null if a global
+ /// with the specified name is not found.
+ GlobalAlias *getNamedAlias(const std::string &Name) const;
+
+/// @}
+/// @name Type Accessors
+/// @{
+public:
+ /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If
+ /// there is already an entry for this name, true is returned and the symbol
+ /// table is not modified.
+ bool addTypeName(const std::string &Name, const Type *Ty);
+
+ /// getTypeName - If there is at least one entry in the symbol table for the
+ /// specified type, return it.
+ std::string getTypeName(const Type *Ty) const;
+
+ /// getTypeByName - Return the type with the specified name in this module, or
+ /// null if there is none by that name.
+ const Type *getTypeByName(const std::string &Name) const;
+
+/// @}
+/// @name Direct access to the globals list, functions list, and symbol table
+/// @{
+public:
+ /// Get the Module's list of global variables (constant).
+ const GlobalListType &getGlobalList() const { return GlobalList; }
+ /// Get the Module's list of global variables.
+ GlobalListType &getGlobalList() { return GlobalList; }
+ /// Get the Module's list of functions (constant).
+ const FunctionListType &getFunctionList() const { return FunctionList; }
+ /// Get the Module's list of functions.
+ FunctionListType &getFunctionList() { return FunctionList; }
+ /// Get the Module's list of aliases (constant).
+ const AliasListType &getAliasList() const { return AliasList; }
+ /// Get the Module's list of aliases.
+ AliasListType &getAliasList() { return AliasList; }
+ /// Get the symbol table of global variable and function identifiers
+ const ValueSymbolTable &getValueSymbolTable() const { return *ValSymTab; }
+ /// Get the Module's symbol table of global variable and function identifiers.
+ ValueSymbolTable &getValueSymbolTable() { return *ValSymTab; }
+ /// Get the symbol table of types
+ const TypeSymbolTable &getTypeSymbolTable() const { return *TypeSymTab; }
+ /// Get the Module's symbol table of types
+ TypeSymbolTable &getTypeSymbolTable() { return *TypeSymTab; }
+
+/// @}
+/// @name Global Variable Iteration
+/// @{
+public:
+ /// Get an iterator to the first global variable
+ global_iterator global_begin() { return GlobalList.begin(); }
+ /// Get a constant iterator to the first global variable
+ const_global_iterator global_begin() const { return GlobalList.begin(); }
+ /// Get an iterator to the last global variable
+ global_iterator global_end () { return GlobalList.end(); }
+ /// Get a constant iterator to the last global variable
+ const_global_iterator global_end () const { return GlobalList.end(); }
+ /// Determine if the list of globals is empty.
+ bool global_empty() const { return GlobalList.empty(); }
+
+/// @}
+/// @name Function Iteration
+/// @{
+public:
+ /// Get an iterator to the first function.
+ iterator begin() { return FunctionList.begin(); }
+ /// Get a constant iterator to the first function.
+ const_iterator begin() const { return FunctionList.begin(); }
+ /// Get an iterator to the last function.
+ iterator end () { return FunctionList.end(); }
+ /// Get a constant iterator to the last function.
+ const_iterator end () const { return FunctionList.end(); }
+ /// Determine how many functions are in the Module's list of functions.
+ size_t size() const { return FunctionList.size(); }
+ /// Determine if the list of functions is empty.
+ bool empty() const { return FunctionList.empty(); }
+
+/// @}
+/// @name Dependent Library Iteration
+/// @{
+public:
+ /// @brief Get a constant iterator to beginning of dependent library list.
+ inline lib_iterator lib_begin() const { return LibraryList.begin(); }
+ /// @brief Get a constant iterator to end of dependent library list.
+ inline lib_iterator lib_end() const { return LibraryList.end(); }
+ /// @brief Returns the number of items in the list of libraries.
+ inline size_t lib_size() const { return LibraryList.size(); }
+ /// @brief Add a library to the list of dependent libraries
+ void addLibrary(const std::string& Lib);
+ /// @brief Remove a library from the list of dependent libraries
+ void removeLibrary(const std::string& Lib);
+ /// @brief Get all the libraries
+ inline const LibraryListType& getLibraries() const { return LibraryList; }
+
+/// @}
+/// @name Alias Iteration
+/// @{
+public:
+ /// Get an iterator to the first alias.
+ alias_iterator alias_begin() { return AliasList.begin(); }
+ /// Get a constant iterator to the first alias.
+ const_alias_iterator alias_begin() const { return AliasList.begin(); }
+ /// Get an iterator to the last alias.
+ alias_iterator alias_end () { return AliasList.end(); }
+ /// Get a constant iterator to the last alias.
+ const_alias_iterator alias_end () const { return AliasList.end(); }
+ /// Determine how many functions are in the Module's list of aliases.
+ size_t alias_size () const { return AliasList.size(); }
+ /// Determine if the list of aliases is empty.
+ bool alias_empty() const { return AliasList.empty(); }
+
+/// @}
+/// @name Utility functions for printing and dumping Module objects
+/// @{
+public:
+ /// Print the module to an output stream
+ void print(std::ostream &OS) const { print(OS, 0); }
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+ /// Print the module to an output stream with AssemblyAnnotationWriter.
+ void print(std::ostream &OS, AssemblyAnnotationWriter *AAW) const;
+ void print(std::ostream *OS, AssemblyAnnotationWriter *AAW) const {
+ if (OS) print(*OS, AAW);
+ }
+ /// Dump the module to std::cerr (for debugging).
+ void dump() const;
+ /// This function causes all the subinstructions to "let go" of all references
+ /// that they are maintaining. This allows one to 'delete' a whole class at
+ /// a time, even though there may be circular references... first all
+ /// references are dropped, and all use counts go to zero. Then everything
+ /// is delete'd for real. Note that no operations are valid on an object
+ /// that has "dropped all references", except operator delete.
+ void dropAllReferences();
+/// @}
+
+ static unsigned getFunctionListOffset() {
+ Module *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->FunctionList));
+ }
+ static unsigned getGlobalVariableListOffset() {
+ Module *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->GlobalList));
+ }
+ static unsigned getAliasListOffset() {
+ Module *Obj = 0;
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->AliasList));
+ }
+};
+
+/// An iostream inserter for modules.
+inline std::ostream &operator<<(std::ostream &O, const Module &M) {
+ M.print(O);
+ return O;
+}
+
+inline ValueSymbolTable *
+ilist_traits<Function>::getSymTab(Module *M) {
+ return M ? &M->getValueSymbolTable() : 0;
+}
+
+inline ValueSymbolTable *
+ilist_traits<GlobalVariable>::getSymTab(Module *M) {
+ return M ? &M->getValueSymbolTable() : 0;
+}
+
+inline ValueSymbolTable *
+ilist_traits<GlobalAlias>::getSymTab(Module *M) {
+ return M ? &M->getValueSymbolTable() : 0;
+}
+
+inline int
+ilist_traits<Function>::getListOffset() {
+ return Module::getFunctionListOffset();
+}
+
+inline int
+ilist_traits<GlobalVariable>::getListOffset() {
+ return Module::getGlobalVariableListOffset();
+}
+
+inline int
+ilist_traits<GlobalAlias>::getListOffset() {
+ return Module::getAliasListOffset();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ModuleProvider.h b/include/llvm/ModuleProvider.h
new file mode 100644
index 0000000..0a91cd1
--- /dev/null
+++ b/include/llvm/ModuleProvider.h
@@ -0,0 +1,88 @@
+//===-- llvm/ModuleProvider.h - Interface for module providers --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an abstract interface for loading a module from some
+// place. This interface allows incremental or random access loading of
+// functions from the file. This is useful for applications like JIT compilers
+// or interprocedural optimizers that do not need the entire program in memory
+// at the same time.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MODULEPROVIDER_H
+#define MODULEPROVIDER_H
+
+#include <string>
+
+namespace llvm {
+
+class Function;
+class Module;
+
+class ModuleProvider {
+protected:
+ Module *TheModule;
+ ModuleProvider();
+
+public:
+ virtual ~ModuleProvider();
+
+ /// getModule - returns the module this provider is encapsulating.
+ ///
+ Module* getModule() { return TheModule; }
+
+ /// materializeFunction - make sure the given function is fully read. If the
+ /// module is corrupt, this returns true and fills in the optional string
+ /// with information about the problem. If successful, this returns false.
+ ///
+ virtual bool materializeFunction(Function *F, std::string *ErrInfo = 0) = 0;
+
+ /// dematerializeFunction - If the given function is read in, and if the
+ /// module provider supports it, release the memory for the function, and set
+ /// it up to be materialized lazily. If the provider doesn't support this
+ /// capability, this method is a noop.
+ ///
+ virtual void dematerializeFunction(Function *F) {}
+
+ /// materializeModule - make sure the entire Module has been completely read.
+ /// On error, return null and fill in the error string if specified.
+ ///
+ virtual Module* materializeModule(std::string *ErrInfo = 0) = 0;
+
+ /// releaseModule - no longer delete the Module* when provider is destroyed.
+ /// On error, return null and fill in the error string if specified.
+ ///
+ virtual Module* releaseModule(std::string *ErrInfo = 0) {
+ // Since we're losing control of this Module, we must hand it back complete
+ if (!materializeModule(ErrInfo))
+ return 0;
+ Module *tempM = TheModule;
+ TheModule = 0;
+ return tempM;
+ }
+};
+
+
+/// ExistingModuleProvider - Allow conversion from a fully materialized Module
+/// into a ModuleProvider, allowing code that expects a ModuleProvider to work
+/// if we just have a Module. Note that the ModuleProvider takes ownership of
+/// the Module specified.
+struct ExistingModuleProvider : public ModuleProvider {
+ ExistingModuleProvider(Module *M) {
+ TheModule = M;
+ }
+ bool materializeFunction(Function *F, std::string *ErrInfo = 0) {
+ return false;
+ }
+ Module* materializeModule(std::string *ErrInfo = 0) { return TheModule; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ParameterAttributes.h b/include/llvm/ParameterAttributes.h
new file mode 100644
index 0000000..b1cb966
--- /dev/null
+++ b/include/llvm/ParameterAttributes.h
@@ -0,0 +1,221 @@
+//===-- llvm/ParameterAttributes.h - Container for ParamAttrs ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the types necessary to represent the parameter attributes
+// associated with functions and their calls.
+//
+// The implementations of these classes live in lib/VMCore/Function.cpp.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PARAMETER_ATTRIBUTES_H
+#define LLVM_PARAMETER_ATTRIBUTES_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace llvm {
+namespace ParamAttr {
+
+/// Function parameters and results can have attributes to indicate how they
+/// should be treated by optimizations and code generation. This enumeration
+/// lists the attributes that can be associated with parameters or function
+/// results.
+/// @brief Function parameter attributes.
+enum Attributes {
+ None = 0, ///< No attributes have been set
+ ZExt = 1 << 0, ///< zero extended before/after call
+ SExt = 1 << 1, ///< sign extended before/after call
+ NoReturn = 1 << 2, ///< mark the function as not returning
+ InReg = 1 << 3, ///< force argument to be passed in register
+ StructRet = 1 << 4, ///< hidden pointer to structure to return
+ NoUnwind = 1 << 5, ///< Function doesn't unwind stack
+ NoAlias = 1 << 6, ///< Considered to not alias after call.
+ ByVal = 1 << 7 ///< Pass structure by value
+};
+
+}
+
+/// This is just a pair of values to associate a set of parameter attributes
+/// with a parameter index.
+/// @brief ParameterAttributes with a parameter index.
+struct ParamAttrsWithIndex {
+ uint16_t attrs; ///< The attributes that are set, |'d together
+ uint16_t index; ///< Index of the parameter for which the attributes apply
+
+ static ParamAttrsWithIndex get(uint16_t idx, uint16_t attrs) {
+ ParamAttrsWithIndex P;
+ P.index = idx;
+ P.attrs = attrs;
+ return P;
+ }
+};
+
+/// @brief A vector of attribute/index pairs.
+typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
+
+/// @brief A more friendly way to reference the attributes.
+typedef ParamAttr::Attributes ParameterAttributes;
+
+/// This class represents a list of attribute/index pairs for parameter
+/// attributes. Each entry in the list contains the index of a function
+/// parameter and the associated ParameterAttributes. If a parameter's index is
+/// not present in the list, then no attributes are set for that parameter. The
+/// list may also be empty, but this does not occur in practice. An item in
+/// the list with an index of 0 refers to the function as a whole or its result.
+/// To construct a ParamAttrsList, you must first fill a ParamAttrsVector with
+/// the attribute/index pairs you wish to set. The list of attributes can be
+/// turned into a string of mnemonics suitable for LLVM Assembly output.
+/// Various accessors are provided to obtain information about the attributes.
+/// Note that objects of this class are "uniqued". The \p get method can return
+/// the pointer of an existing and identical instance. Consequently, reference
+/// counting is necessary in order to determine when the last reference to a
+/// ParamAttrsList of a given shape is dropped. Users of this class should use
+/// the addRef and dropRef methods to add/drop references. When the reference
+/// count goes to zero, the ParamAttrsList object is deleted.
+/// This class is used by Function, CallInst and InvokeInst to represent their
+/// sets of parameter attributes.
+/// @brief A List of ParameterAttributes.
+class ParamAttrsList : public FoldingSetNode {
+ /// @name Construction
+ /// @{
+ private:
+ // ParamAttrsList is uniqued, these should not be publicly available
+ void operator=(const ParamAttrsList &); // Do not implement
+ ParamAttrsList(const ParamAttrsList &); // Do not implement
+ ParamAttrsList(); // Do not implement
+ ~ParamAttrsList(); // Private implementation
+
+ /// Only the \p get method can invoke this when it wants to create a
+ /// new instance.
+ /// @brief Construct an ParamAttrsList from a ParamAttrsVector
+ explicit ParamAttrsList(const ParamAttrsVector &attrVec)
+ : attrs(attrVec), refCount(0) {}
+
+ public:
+ /// This method ensures the uniqueness of ParamAttrsList instances. The
+ /// argument is a vector of attribute/index pairs as represented by the
+ /// ParamAttrsWithIndex structure. The vector is used in the construction of
+ /// the ParamAttrsList instance. If an instance with identical vector pairs
+ /// exists, it will be returned instead of creating a new instance.
+ /// @brief Get a ParamAttrsList instance.
+ static ParamAttrsList *get(const ParamAttrsVector &attrVec);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// The parameter attributes for the \p indexth parameter are returned.
+ /// The 0th parameter refers to the return type of the function. Note that
+ /// the \p param_index is an index into the function's parameters, not an
+ /// index into this class's list of attributes. The result of getParamIndex
+ /// is always suitable input to this function.
+ /// @returns The all the ParameterAttributes for the \p indexth parameter
+ /// as a uint16_t of enumeration values OR'd together.
+ /// @brief Get the attributes for a parameter
+ uint16_t getParamAttrs(uint16_t param_index) const;
+
+ /// This checks to see if the \p ith function parameter has the parameter
+ /// attribute given by \p attr set.
+ /// @returns true if the parameter attribute is set
+ /// @brief Determine if a ParameterAttributes is set
+ bool paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+ return getParamAttrs(i) & attr;
+ }
+
+ /// The set of ParameterAttributes set in Attributes is converted to a
+ /// string of equivalent mnemonics. This is, presumably, for writing out
+ /// the mnemonics for the assembly writer.
+ /// @brief Convert parameter attribute bits to text
+ static std::string getParamAttrsText(uint16_t Attributes);
+
+ /// The \p Indexth parameter attribute is converted to string.
+ /// @brief Get the text for the parmeter attributes for one parameter.
+ std::string getParamAttrsTextByIndex(uint16_t Index) const {
+ return getParamAttrsText(getParamAttrs(Index));
+ }
+
+ /// @brief Comparison operator for ParamAttrsList
+ bool operator < (const ParamAttrsList& that) const {
+ if (this->attrs.size() < that.attrs.size())
+ return true;
+ if (this->attrs.size() > that.attrs.size())
+ return false;
+ for (unsigned i = 0; i < attrs.size(); ++i) {
+ if (attrs[i].index < that.attrs[i].index)
+ return true;
+ if (attrs[i].index > that.attrs[i].index)
+ return false;
+ if (attrs[i].attrs < that.attrs[i].attrs)
+ return true;
+ if (attrs[i].attrs > that.attrs[i].attrs)
+ return false;
+ }
+ return false;
+ }
+
+ /// Returns the parameter index of a particular parameter attribute in this
+ /// list of attributes. Note that the attr_index is an index into this
+ /// class's list of attributes, not the index of a parameter. The result
+ /// is the index of the parameter. Clients generally should not use this
+ /// method. It is used internally by LLVM.
+ /// @brief Get a parameter index
+ uint16_t getParamIndex(unsigned attr_index) const {
+ return attrs[attr_index].index;
+ }
+
+ uint16_t getParamAttrsAtIndex(unsigned attr_index) const {
+ return attrs[attr_index].attrs;
+ }
+
+ /// Determines how many parameter attributes are set in this ParamAttrsList.
+ /// This says nothing about how many parameters the function has. It also
+ /// says nothing about the highest parameter index that has attributes.
+ /// Clients generally should not use this method. It is used internally by
+ /// LLVM.
+ /// @returns the number of parameter attributes in this ParamAttrsList.
+ /// @brief Return the number of parameter attributes this type has.
+ unsigned size() const { return attrs.size(); }
+
+ /// Classes retaining references to ParamAttrsList objects should call this
+ /// method to increment the reference count. This ensures that the
+ /// ParamAttrsList object will not disappear until the class drops it.
+ /// @brief Add a reference to this instance.
+ void addRef() const { refCount++; }
+
+ /// Classes retaining references to ParamAttrsList objects should call this
+ /// method to decrement the reference count and possibly delete the
+ /// ParamAttrsList object. This ensures that ParamAttrsList objects are
+ /// cleaned up only when the last reference to them is dropped.
+ /// @brief Drop a reference to this instance.
+ void dropRef() const {
+ assert(refCount != 0 && "dropRef without addRef");
+ if (--refCount == 0)
+ delete this;
+ }
+
+ /// @}
+ /// @name Implementation Details
+ /// @{
+ public:
+ void Profile(FoldingSetNodeID &ID) const;
+ void dump() const;
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ ParamAttrsVector attrs; ///< The list of attributes
+ mutable unsigned refCount; ///< The number of references to this object
+ /// @}
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Pass.h b/include/llvm/Pass.h
new file mode 100644
index 0000000..a5a98f5
--- /dev/null
+++ b/include/llvm/Pass.h
@@ -0,0 +1,418 @@
+//===- llvm/Pass.h - Base class for Passes ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a base class that indicates that a specified class is a
+// transformation pass implementation.
+//
+// Passes are designed this way so that it is possible to run passes in a cache
+// and organizationally optimal order without having to specify it at the front
+// end. This allows arbitrary passes to be strung together and have them
+// executed as effeciently as possible.
+//
+// Passes should extend one of the classes below, depending on the guarantees
+// that it can make about what will be modified as it is run. For example, most
+// global optimizations should derive from FunctionPass, because they do not add
+// or delete functions, they operate on the internals of the function.
+//
+// Note that this file #includes PassSupport.h and PassAnalysisSupport.h (at the
+// bottom), so the APIs exposed by these files are also automatically available
+// to all users of this file.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_H
+#define LLVM_PASS_H
+
+#include "llvm/Support/Streams.h"
+#include <vector>
+#include <deque>
+#include <map>
+#include <iosfwd>
+#include <cassert>
+
+namespace llvm {
+
+class Value;
+class BasicBlock;
+class Function;
+class Module;
+class AnalysisUsage;
+class PassInfo;
+class ImmutablePass;
+class PMStack;
+class AnalysisResolver;
+class PMDataManager;
+
+// AnalysisID - Use the PassInfo to identify a pass...
+typedef const PassInfo* AnalysisID;
+
+/// Different types of internal pass managers. External pass managers
+/// (PassManager and FunctionPassManager) are not represented here.
+/// Ordering of pass manager types is important here.
+enum PassManagerType {
+ PMT_Unknown = 0,
+ PMT_ModulePassManager = 1, /// MPPassManager
+ PMT_CallGraphPassManager, /// CGPassManager
+ PMT_FunctionPassManager, /// FPPassManager
+ PMT_LoopPassManager, /// LPPassManager
+ PMT_BasicBlockPassManager, /// BBPassManager
+ PMT_Last
+};
+
+typedef enum PassManagerType PassManagerType;
+
+//===----------------------------------------------------------------------===//
+/// Pass interface - Implemented by all 'passes'. Subclass this if you are an
+/// interprocedural optimization or you do not fit into any of the more
+/// constrained passes described below.
+///
+class Pass {
+ AnalysisResolver *Resolver; // Used to resolve analysis
+ intptr_t PassID;
+
+ // AnalysisImpls - This keeps track of which passes implement the interfaces
+ // that are required by the current pass (to implement getAnalysis()).
+ //
+ std::vector<std::pair<const PassInfo*, Pass*> > AnalysisImpls;
+
+ void operator=(const Pass&); // DO NOT IMPLEMENT
+ Pass(const Pass &); // DO NOT IMPLEMENT
+public:
+ explicit Pass(intptr_t pid) : Resolver(0), PassID(pid) {}
+ virtual ~Pass();
+
+ /// getPassName - Return a nice clean name for a pass. This usually
+ /// implemented in terms of the name that is registered by one of the
+ /// Registration templates, but can be overloaded directly, and if nothing
+ /// else is available, C++ RTTI will be consulted to get a SOMEWHAT
+ /// intelligible name for the pass.
+ ///
+ virtual const char *getPassName() const;
+
+ /// getPassInfo - Return the PassInfo data structure that corresponds to this
+ /// pass... If the pass has not been registered, this will return null.
+ ///
+ const PassInfo *getPassInfo() const;
+
+ /// runPass - Run this pass, returning true if a modification was made to the
+ /// module argument. This should be implemented by all concrete subclasses.
+ ///
+ virtual bool runPass(Module &M) { return false; }
+ virtual bool runPass(BasicBlock&) { return false; }
+
+ /// print - Print out the internal state of the pass. This is called by
+ /// Analyze to print out the contents of an analysis. Otherwise it is not
+ /// necessary to implement this method. Beware that the module pointer MAY be
+ /// null. This automatically forwards to a virtual function that does not
+ /// provide the Module* in case the analysis doesn't need it it can just be
+ /// ignored.
+ ///
+ virtual void print(std::ostream &O, const Module *M) const;
+ void print(std::ostream *O, const Module *M) const { if (O) print(*O, M); }
+ void dump() const; // dump - call print(std::cerr, 0);
+
+ /// Each pass is responsible for assigning a pass manager to itself.
+ /// PMS is the stack of available pass manager.
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType T = PMT_Unknown) {}
+ /// Check if available pass managers are suitable for this pass or not.
+ virtual void preparePassManager(PMStack &PMS) {}
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_Unknown;
+ }
+
+ // Access AnalysisResolver
+ inline void setResolver(AnalysisResolver *AR) {
+ assert (!Resolver && "Resolver is already set");
+ Resolver = AR;
+ }
+ inline AnalysisResolver *getResolver() {
+ assert (Resolver && "Resolver is not set");
+ return Resolver;
+ }
+
+ /// getAnalysisUsage - This function should be overriden by passes that need
+ /// analysis information to do their job. If a pass specifies that it uses a
+ /// particular analysis result to this function, it can then use the
+ /// getAnalysis<AnalysisType>() function, below.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const {
+ // By default, no analysis results are used, all are invalidated.
+ }
+
+ /// releaseMemory() - This member can be implemented by a pass if it wants to
+ /// be able to release its memory when it is no longer needed. The default
+ /// behavior of passes is to hold onto memory for the entire duration of their
+ /// lifetime (which is the entire compile time). For pipelined passes, this
+ /// is not a big deal because that memory gets recycled every time the pass is
+ /// invoked on another program unit. For IP passes, it is more important to
+ /// free memory when it is unused.
+ ///
+ /// Optionally implement this function to release pass memory when it is no
+ /// longer used.
+ ///
+ virtual void releaseMemory() {}
+
+ // dumpPassStructure - Implement the -debug-passes=PassStructure option
+ virtual void dumpPassStructure(unsigned Offset = 0);
+
+ template<typename AnalysisClass>
+ static const PassInfo *getClassPassInfo() {
+ return lookupPassInfo((intptr_t)&AnalysisClass::ID);
+ }
+
+ // lookupPassInfo - Return the pass info object for the specified pass class,
+ // or null if it is not known.
+ static const PassInfo *lookupPassInfo(intptr_t TI);
+
+ /// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
+ /// to get to the analysis information that might be around that needs to be
+ /// updated. This is different than getAnalysis in that it can fail (ie the
+ /// analysis results haven't been computed), so should only be used if you
+ /// provide the capability to update an analysis that exists. This method is
+ /// often used by transformation APIs to update analysis results for a pass
+ /// automatically as the transform is performed.
+ ///
+ template<typename AnalysisType>
+ AnalysisType *getAnalysisToUpdate() const; // Defined in PassAnalysisSupport.h
+
+ /// mustPreserveAnalysisID - This method serves the same function as
+ /// getAnalysisToUpdate, but works if you just have an AnalysisID. This
+ /// obviously cannot give you a properly typed instance of the class if you
+ /// don't have the class name available (use getAnalysisToUpdate if you do),
+ /// but it can tell you if you need to preserve the pass at least.
+ ///
+ bool mustPreserveAnalysisID(const PassInfo *AnalysisID) const;
+
+ /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+ /// to the analysis information that they claim to use by overriding the
+ /// getAnalysisUsage function.
+ ///
+ template<typename AnalysisType>
+ AnalysisType &getAnalysis() const; // Defined in PassAnalysisSupport.h
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysis(Function &F); // Defined in PassanalysisSupport.h
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysisID(const PassInfo *PI) const;
+
+ template<typename AnalysisType>
+ AnalysisType &getAnalysisID(const PassInfo *PI, Function &F);
+};
+
+inline std::ostream &operator<<(std::ostream &OS, const Pass &P) {
+ P.print(OS, 0); return OS;
+}
+
+//===----------------------------------------------------------------------===//
+/// ModulePass class - This class is used to implement unstructured
+/// interprocedural optimizations and analyses. ModulePasses may do anything
+/// they want to the program.
+///
+class ModulePass : public Pass {
+public:
+ /// runOnModule - Virtual method overriden by subclasses to process the module
+ /// being operated on.
+ virtual bool runOnModule(Module &M) = 0;
+
+ virtual bool runPass(Module &M) { return runOnModule(M); }
+ virtual bool runPass(BasicBlock&) { return false; }
+
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType T = PMT_ModulePassManager);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_ModulePassManager;
+ }
+
+ explicit ModulePass(intptr_t pid) : Pass(pid) {}
+ // Force out-of-line virtual method.
+ virtual ~ModulePass();
+};
+
+
+//===----------------------------------------------------------------------===//
+/// ImmutablePass class - This class is used to provide information that does
+/// not need to be run. This is useful for things like target information and
+/// "basic" versions of AnalysisGroups.
+///
+class ImmutablePass : public ModulePass {
+public:
+ /// initializePass - This method may be overriden by immutable passes to allow
+ /// them to perform various initialization actions they require. This is
+ /// primarily because an ImmutablePass can "require" another ImmutablePass,
+ /// and if it does, the overloaded version of initializePass may get access to
+ /// these passes with getAnalysis<>.
+ ///
+ virtual void initializePass() {}
+
+ /// ImmutablePasses are never run.
+ ///
+ virtual bool runOnModule(Module &M) { return false; }
+
+ explicit ImmutablePass(intptr_t pid) : ModulePass(pid) {}
+ // Force out-of-line virtual method.
+ virtual ~ImmutablePass();
+};
+
+//===----------------------------------------------------------------------===//
+/// FunctionPass class - This class is used to implement most global
+/// optimizations. Optimizations should subclass this class if they meet the
+/// following constraints:
+///
+/// 1. Optimizations are organized globally, i.e., a function at a time
+/// 2. Optimizing a function does not cause the addition or removal of any
+/// functions in the module
+///
+class FunctionPass : public Pass {
+public:
+ explicit FunctionPass(intptr_t pid) : Pass(pid) {}
+
+ /// doInitialization - Virtual method overridden by subclasses to do
+ /// any necessary per-module initialization.
+ ///
+ virtual bool doInitialization(Module &M) { return false; }
+
+ /// runOnFunction - Virtual method overriden by subclasses to do the
+ /// per-function processing of the pass.
+ ///
+ virtual bool runOnFunction(Function &F) = 0;
+
+ /// doFinalization - Virtual method overriden by subclasses to do any post
+ /// processing needed after all passes have run.
+ ///
+ virtual bool doFinalization(Module &M) { return false; }
+
+ /// runOnModule - On a module, we run this pass by initializing,
+ /// ronOnFunction'ing once for every function in the module, then by
+ /// finalizing.
+ ///
+ virtual bool runOnModule(Module &M);
+
+ /// run - On a function, we simply initialize, run the function, then
+ /// finalize.
+ ///
+ bool run(Function &F);
+
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType T = PMT_FunctionPassManager);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_FunctionPassManager;
+ }
+};
+
+
+
+//===----------------------------------------------------------------------===//
+/// BasicBlockPass class - This class is used to implement most local
+/// optimizations. Optimizations should subclass this class if they
+/// meet the following constraints:
+/// 1. Optimizations are local, operating on either a basic block or
+/// instruction at a time.
+/// 2. Optimizations do not modify the CFG of the contained function, or any
+/// other basic block in the function.
+/// 3. Optimizations conform to all of the constraints of FunctionPasses.
+///
+class BasicBlockPass : public Pass {
+public:
+ explicit BasicBlockPass(intptr_t pid) : Pass(pid) {}
+
+ /// doInitialization - Virtual method overridden by subclasses to do
+ /// any necessary per-module initialization.
+ ///
+ virtual bool doInitialization(Module &M) { return false; }
+
+ /// doInitialization - Virtual method overridden by BasicBlockPass subclasses
+ /// to do any necessary per-function initialization.
+ ///
+ virtual bool doInitialization(Function &F) { return false; }
+
+ /// runOnBasicBlock - Virtual method overriden by subclasses to do the
+ /// per-basicblock processing of the pass.
+ ///
+ virtual bool runOnBasicBlock(BasicBlock &BB) = 0;
+
+ /// doFinalization - Virtual method overriden by BasicBlockPass subclasses to
+ /// do any post processing needed after all passes have run.
+ ///
+ virtual bool doFinalization(Function &F) { return false; }
+
+ /// doFinalization - Virtual method overriden by subclasses to do any post
+ /// processing needed after all passes have run.
+ ///
+ virtual bool doFinalization(Module &M) { return false; }
+
+
+ // To run this pass on a function, we simply call runOnBasicBlock once for
+ // each function.
+ //
+ bool runOnFunction(Function &F);
+
+ /// To run directly on the basic block, we initialize, runOnBasicBlock, then
+ /// finalize.
+ ///
+ virtual bool runPass(Module &M) { return false; }
+ virtual bool runPass(BasicBlock &BB);
+
+ virtual void assignPassManager(PMStack &PMS,
+ PassManagerType T = PMT_BasicBlockPassManager);
+
+ /// Return what kind of Pass Manager can manage this pass.
+ virtual PassManagerType getPotentialPassManagerType() const {
+ return PMT_BasicBlockPassManager;
+ }
+};
+
+/// PMStack
+/// Top level pass manager (see PasManager.cpp) maintains active Pass Managers
+/// using PMStack. Each Pass implements assignPassManager() to connect itself
+/// with appropriate manager. assignPassManager() walks PMStack to find
+/// suitable manager.
+///
+/// PMStack is just a wrapper around standard deque that overrides pop() and
+/// push() methods.
+class PMStack {
+public:
+ typedef std::deque<PMDataManager *>::reverse_iterator iterator;
+ iterator begin() { return S.rbegin(); }
+ iterator end() { return S.rend(); }
+
+ void handleLastUserOverflow();
+
+ void pop();
+ inline PMDataManager *top() { return S.back(); }
+ void push(Pass *P);
+ inline bool empty() { return S.empty(); }
+
+ void dump();
+private:
+ std::deque<PMDataManager *> S;
+};
+
+
+/// If the user specifies the -time-passes argument on an LLVM tool command line
+/// then the value of this boolean will be true, otherwise false.
+/// @brief This is the storage for the -time-passes option.
+extern bool TimePassesIsEnabled;
+
+} // End llvm namespace
+
+// Include support files that contain important APIs commonly used by Passes,
+// but that we want to separate out to make it easier to read the header files.
+//
+#include "llvm/PassSupport.h"
+#include "llvm/PassAnalysisSupport.h"
+
+#endif
diff --git a/include/llvm/PassAnalysisSupport.h b/include/llvm/PassAnalysisSupport.h
new file mode 100644
index 0000000..0454f21
--- /dev/null
+++ b/include/llvm/PassAnalysisSupport.h
@@ -0,0 +1,240 @@
+//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines stuff that is used to define and "use" Analysis Passes.
+// This file is automatically #included by Pass.h, so:
+//
+// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
+#define LLVM_PASS_ANALYSIS_SUPPORT_H
+
+#include <vector>
+
+namespace llvm {
+
+// No need to include Pass.h, we are being included by it!
+
+//===----------------------------------------------------------------------===//
+// AnalysisUsage - Represent the analysis usage information of a pass. This
+// tracks analyses that the pass REQUIRES (must be available when the pass
+// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the
+// pass), and analyses that the pass PRESERVES (the pass does not invalidate the
+// results of these analyses). This information is provided by a pass to the
+// Pass infrastructure through the getAnalysisUsage virtual function.
+//
+class AnalysisUsage {
+ // Sets of analyses required and preserved by a pass
+ std::vector<AnalysisID> Required, RequiredTransitive, Preserved;
+ bool PreservesAll;
+public:
+ AnalysisUsage() : PreservesAll(false) {}
+
+ // addRequired - Add the specified ID to the required set of the usage info
+ // for a pass.
+ //
+ AnalysisUsage &addRequiredID(AnalysisID ID) {
+ assert(ID && "Pass class not registered!");
+ Required.push_back(ID);
+ return *this;
+ }
+ template<class PassClass>
+ AnalysisUsage &addRequired() {
+ return addRequiredID(Pass::getClassPassInfo<PassClass>());
+ }
+
+ AnalysisUsage &addRequiredTransitiveID(AnalysisID ID) {
+ assert(ID && "Pass class not registered!");
+ Required.push_back(ID);
+ RequiredTransitive.push_back(ID);
+ return *this;
+ }
+ template<class PassClass>
+ AnalysisUsage &addRequiredTransitive() {
+ AnalysisID ID = Pass::getClassPassInfo<PassClass>();
+ return addRequiredTransitiveID(ID);
+ }
+
+ // addPreserved - Add the specified ID to the set of analyses preserved by
+ // this pass
+ //
+ AnalysisUsage &addPreservedID(AnalysisID ID) {
+ Preserved.push_back(ID);
+ return *this;
+ }
+
+ template<class PassClass>
+ AnalysisUsage &addPreserved() {
+ assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!");
+ Preserved.push_back(Pass::getClassPassInfo<PassClass>());
+ return *this;
+ }
+
+ // setPreservesAll - Set by analyses that do not transform their input at all
+ void setPreservesAll() { PreservesAll = true; }
+ bool getPreservesAll() const { return PreservesAll; }
+
+ /// setPreservesCFG - This function should be called by the pass, iff they do
+ /// not:
+ ///
+ /// 1. Add or remove basic blocks from the function
+ /// 2. Modify terminator instructions in any way.
+ ///
+ /// This function annotates the AnalysisUsage info object to say that analyses
+ /// that only depend on the CFG are preserved by this pass.
+ ///
+ void setPreservesCFG();
+
+ const std::vector<AnalysisID> &getRequiredSet() const { return Required; }
+ const std::vector<AnalysisID> &getRequiredTransitiveSet() const {
+ return RequiredTransitive;
+ }
+ const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; }
+};
+
+//===----------------------------------------------------------------------===//
+// AnalysisResolver - Simple interface used by Pass objects to pull all
+// analysis information out of pass manager that is responsible to manage
+// the pass.
+//
+class PMDataManager;
+class AnalysisResolver {
+private:
+ AnalysisResolver(); // DO NOT IMPLEMENT
+
+public:
+ explicit AnalysisResolver(PMDataManager &P) : PM(P) { }
+
+ inline PMDataManager &getPMDataManager() { return PM; }
+
+ // Find pass that is implementing PI.
+ Pass *findImplPass(const PassInfo *PI) {
+ Pass *ResultPass = 0;
+ for (unsigned i = 0; i < AnalysisImpls.size() ; ++i) {
+ if (AnalysisImpls[i].first == PI) {
+ ResultPass = AnalysisImpls[i].second;
+ break;
+ }
+ }
+ return ResultPass;
+ }
+
+ // Find pass that is implementing PI. Initialize pass for Function F.
+ Pass *findImplPass(Pass *P, const PassInfo *PI, Function &F);
+
+ void addAnalysisImplsPair(const PassInfo *PI, Pass *P) {
+ std::pair<const PassInfo*, Pass*> pir = std::make_pair(PI,P);
+ AnalysisImpls.push_back(pir);
+ }
+
+ // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
+ Pass *getAnalysisToUpdate(AnalysisID ID, bool Direction) const;
+
+ // AnalysisImpls - This keeps track of which passes implements the interfaces
+ // that are required by the current pass (to implement getAnalysis()).
+ // NOTE : Remove AnalysisImpls from class Pass, when AnalysisResolver
+ // replaces AnalysisResolver
+ std::vector<std::pair<const PassInfo*, Pass*> > AnalysisImpls;
+
+private:
+ // PassManager that is used to resolve analysis info
+ PMDataManager &PM;
+};
+
+/// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
+/// to get to the analysis information that might be around that needs to be
+/// updated. This is different than getAnalysis in that it can fail (ie the
+/// analysis results haven't been computed), so should only be used if you
+/// provide the capability to update an analysis that exists. This method is
+/// often used by transformation APIs to update analysis results for a pass
+/// automatically as the transform is performed.
+///
+template<typename AnalysisType>
+AnalysisType *Pass::getAnalysisToUpdate() const {
+ assert(Resolver && "Pass not resident in a PassManager object!");
+
+ const PassInfo *PI = getClassPassInfo<AnalysisType>();
+ if (PI == 0) return 0;
+ return dynamic_cast<AnalysisType*>
+ (Resolver->getAnalysisToUpdate(PI, true));
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis() const {
+ assert(Resolver &&"Pass has not been inserted into a PassManager object!");
+
+ return getAnalysisID<AnalysisType>(getClassPassInfo<AnalysisType>());
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(const PassInfo *PI) const {
+ assert(PI && "getAnalysis for unregistered pass!");
+ assert(Resolver&&"Pass has not been inserted into a PassManager object!");
+ // PI *must* appear in AnalysisImpls. Because the number of passes used
+ // should be a small number, we just do a linear search over a (dense)
+ // vector.
+ Pass *ResultPass = Resolver->findImplPass(PI);
+ assert (ResultPass &&
+ "getAnalysis*() called on an analysis that was not "
+ "'required' by pass!");
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we must use dynamic_cast here to potentially adjust the
+ // return pointer (because the class may multiply inherit, once from pass,
+ // once from AnalysisType).
+ //
+ AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass);
+ assert(Result && "Pass does not implement interface required!");
+ return *Result;
+}
+
+/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
+/// to the analysis information that they claim to use by overriding the
+/// getAnalysisUsage function.
+///
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysis(Function &F) {
+ assert(Resolver &&"Pass has not been inserted into a PassManager object!");
+
+ return getAnalysisID<AnalysisType>(getClassPassInfo<AnalysisType>(), F);
+}
+
+template<typename AnalysisType>
+AnalysisType &Pass::getAnalysisID(const PassInfo *PI, Function &F) {
+ assert(PI && "getAnalysis for unregistered pass!");
+ assert(Resolver&&"Pass has not been inserted into a PassManager object!");
+ // PI *must* appear in AnalysisImpls. Because the number of passes used
+ // should be a small number, we just do a linear search over a (dense)
+ // vector.
+ Pass *ResultPass = Resolver->findImplPass(this, PI, F);
+ assert (ResultPass &&
+ "getAnalysis*() called on an analysis that was not "
+ "'required' by pass!");
+
+ // Because the AnalysisType may not be a subclass of pass (for
+ // AnalysisGroups), we must use dynamic_cast here to potentially adjust the
+ // return pointer (because the class may multiply inherit, once from pass,
+ // once from AnalysisType).
+ //
+ AnalysisType *Result = dynamic_cast<AnalysisType*>(ResultPass);
+ assert(Result && "Pass does not implement interface required!");
+ return *Result;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/PassManager.h b/include/llvm/PassManager.h
new file mode 100644
index 0000000..5d936c4
--- /dev/null
+++ b/include/llvm/PassManager.h
@@ -0,0 +1,93 @@
+//===- llvm/PassManager.h - Container for Passes ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the PassManager class. This class is used to hold,
+// maintain, and optimize execution of Passes. The PassManager class ensures
+// that analysis results are available before a pass runs, and that Pass's are
+// destroyed when the PassManager is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSMANAGER_H
+#define LLVM_PASSMANAGER_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class Pass;
+class ModulePass;
+class Module;
+class ModuleProvider;
+
+class PassManagerImpl;
+class FunctionPassManagerImpl;
+
+/// PassManager manages ModulePassManagers
+class PassManager {
+
+public:
+
+ PassManager();
+ ~PassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes ownership of
+ /// the Pass to the PassManager. When the PassManager is destroyed, the pass
+ /// will be destroyed as well, so there is no need to delete the pass. This
+ /// implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool run(Module &M);
+
+private:
+
+ /// PassManagerImpl_New is the actual class. PassManager is just the
+ /// wraper to publish simple pass manager interface
+ PassManagerImpl *PM;
+
+};
+
+/// FunctionPassManager manages FunctionPasses and BasicBlockPassManagers.
+class FunctionPassManager {
+public:
+ explicit FunctionPassManager(ModuleProvider *P);
+ FunctionPassManager();
+ ~FunctionPassManager();
+
+ /// add - Add a pass to the queue of passes to run. This passes
+ /// ownership of the Pass to the PassManager. When the
+ /// PassManager_X is destroyed, the pass will be destroyed as well, so
+ /// there is no need to delete the pass. (TODO delete passes.)
+ /// This implies that all passes MUST be allocated with 'new'.
+ void add(Pass *P);
+
+ /// run - Execute all of the passes scheduled for execution. Keep
+ /// track of whether any of the passes modifies the function, and if
+ /// so, return true.
+ ///
+ bool run(Function &F);
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization();
+
+ /// doFinalization - Run all of the initializers for the function passes.
+ ///
+ bool doFinalization();
+private:
+
+ FunctionPassManagerImpl *FPM;
+ ModuleProvider *MP;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/PassManagers.h b/include/llvm/PassManagers.h
new file mode 100644
index 0000000..da05647
--- /dev/null
+++ b/include/llvm/PassManagers.h
@@ -0,0 +1,382 @@
+//===- llvm/PassManager.h - Pass Inftrastructre classes --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the LLVM Pass Manager infrastructure.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/PassManager.h"
+#include "llvm/ADT/SmallVector.h"
+using namespace llvm;
+class llvm::PMDataManager;
+class llvm::PMStack;
+
+//===----------------------------------------------------------------------===//
+// Overview:
+// The Pass Manager Infrastructure manages passes. It's responsibilities are:
+//
+// o Manage optimization pass execution order
+// o Make required Analysis information available before pass P is run
+// o Release memory occupied by dead passes
+// o If Analysis information is dirtied by a pass then regenerate Analysis
+// information before it is consumed by another pass.
+//
+// Pass Manager Infrastructure uses multiple pass managers. They are
+// PassManager, FunctionPassManager, MPPassManager, FPPassManager, BBPassManager.
+// This class hierarcy uses multiple inheritance but pass managers do not derive
+// from another pass manager.
+//
+// PassManager and FunctionPassManager are two top-level pass manager that
+// represents the external interface of this entire pass manager infrastucture.
+//
+// Important classes :
+//
+// [o] class PMTopLevelManager;
+//
+// Two top level managers, PassManager and FunctionPassManager, derive from
+// PMTopLevelManager. PMTopLevelManager manages information used by top level
+// managers such as last user info.
+//
+// [o] class PMDataManager;
+//
+// PMDataManager manages information, e.g. list of available analysis info,
+// used by a pass manager to manage execution order of passes. It also provides
+// a place to implement common pass manager APIs. All pass managers derive from
+// PMDataManager.
+//
+// [o] class BBPassManager : public FunctionPass, public PMDataManager;
+//
+// BBPassManager manages BasicBlockPasses.
+//
+// [o] class FunctionPassManager;
+//
+// This is a external interface used by JIT to manage FunctionPasses. This
+// interface relies on FunctionPassManagerImpl to do all the tasks.
+//
+// [o] class FunctionPassManagerImpl : public ModulePass, PMDataManager,
+// public PMTopLevelManager;
+//
+// FunctionPassManagerImpl is a top level manager. It manages FPPassManagers
+//
+// [o] class FPPassManager : public ModulePass, public PMDataManager;
+//
+// FPPassManager manages FunctionPasses and BBPassManagers
+//
+// [o] class MPPassManager : public Pass, public PMDataManager;
+//
+// MPPassManager manages ModulePasses and FPPassManagers
+//
+// [o] class PassManager;
+//
+// This is a external interface used by various tools to manages passes. It
+// relies on PassManagerImpl to do all the tasks.
+//
+// [o] class PassManagerImpl : public Pass, public PMDataManager,
+// public PMDTopLevelManager
+//
+// PassManagerImpl is a top level pass manager responsible for managing
+// MPPassManagers.
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+
+/// FunctionPassManager and PassManager, two top level managers, serve
+/// as the public interface of pass manager infrastructure.
+enum TopLevelManagerType {
+ TLM_Function, // FunctionPassManager
+ TLM_Pass // PassManager
+};
+
+// enums for debugging strings
+enum PassDebuggingString {
+ EXECUTION_MSG, // "Executing Pass '"
+ MODIFICATION_MSG, // "' Made Modification '"
+ FREEING_MSG, // " Freeing Pass '"
+ ON_BASICBLOCK_MSG, // "' on BasicBlock '" + PassName + "'...\n"
+ ON_FUNCTION_MSG, // "' on Function '" + FunctionName + "'...\n"
+ ON_MODULE_MSG, // "' on Module '" + ModuleName + "'...\n"
+ ON_LOOP_MSG, // " 'on Loop ...\n'"
+ ON_CG_MSG // "' on Call Graph ...\n'"
+};
+
+//===----------------------------------------------------------------------===//
+// PMTopLevelManager
+//
+/// PMTopLevelManager manages LastUser info and collects common APIs used by
+/// top level pass managers.
+class PMTopLevelManager {
+public:
+
+ virtual unsigned getNumContainedManagers() {
+ return PassManagers.size();
+ }
+
+ /// Schedule pass P for execution. Make sure that passes required by
+ /// P are run before P is run. Update analysis info maintained by
+ /// the manager. Remove dead passes. This is a recursive function.
+ void schedulePass(Pass *P);
+
+ /// This is implemented by top level pass manager and used by
+ /// schedulePass() to add analysis info passes that are not available.
+ virtual void addTopLevelPass(Pass *P) = 0;
+
+ /// Set pass P as the last user of the given analysis passes.
+ void setLastUser(std::vector<Pass *> &AnalysisPasses, Pass *P);
+
+ /// Collect passes whose last user is P
+ void collectLastUses(std::vector<Pass *> &LastUses, Pass *P);
+
+ /// Find the pass that implements Analysis AID. Search immutable
+ /// passes and all pass managers. If desired pass is not found
+ /// then return NULL.
+ Pass *findAnalysisPass(AnalysisID AID);
+
+ explicit PMTopLevelManager(enum TopLevelManagerType t);
+ virtual ~PMTopLevelManager();
+
+ /// Add immutable pass and initialize it.
+ inline void addImmutablePass(ImmutablePass *P) {
+ P->initializePass();
+ ImmutablePasses.push_back(P);
+ }
+
+ inline std::vector<ImmutablePass *>& getImmutablePasses() {
+ return ImmutablePasses;
+ }
+
+ void addPassManager(Pass *Manager) {
+ PassManagers.push_back(Manager);
+ }
+
+ // Add Manager into the list of managers that are not directly
+ // maintained by this top level pass manager
+ inline void addIndirectPassManager(PMDataManager *Manager) {
+ IndirectPassManagers.push_back(Manager);
+ }
+
+ // Print passes managed by this top level manager.
+ void dumpPasses() const;
+ void dumpArguments() const;
+
+ void initializeAllAnalysisInfo();
+
+ // Active Pass Managers
+ PMStack activeStack;
+
+protected:
+
+ /// Collection of pass managers
+ std::vector<Pass *> PassManagers;
+
+private:
+
+ /// Collection of pass managers that are not directly maintained
+ /// by this pass manager
+ std::vector<PMDataManager *> IndirectPassManagers;
+
+ // Map to keep track of last user of the analysis pass.
+ // LastUser->second is the last user of Lastuser->first.
+ std::map<Pass *, Pass *> LastUser;
+
+ /// Immutable passes are managed by top level manager.
+ std::vector<ImmutablePass *> ImmutablePasses;
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// PMDataManager
+
+/// PMDataManager provides the common place to manage the analysis data
+/// used by pass managers.
+class PMDataManager {
+public:
+
+ explicit PMDataManager(int Depth) : TPM(NULL), Depth(Depth) {
+ initializeAnalysisInfo();
+ }
+
+ virtual ~PMDataManager();
+
+ /// Return true IFF pass P's required analysis set does not required new
+ /// manager.
+ bool manageablePass(Pass *P);
+
+ /// Augment AvailableAnalysis by adding analysis made available by pass P.
+ void recordAvailableAnalysis(Pass *P);
+
+ /// Remove Analysis that is not preserved by the pass
+ void removeNotPreservedAnalysis(Pass *P);
+
+ /// Remove dead passes
+ void removeDeadPasses(Pass *P, std::string Msg, enum PassDebuggingString);
+
+ /// Add pass P into the PassVector. Update
+ /// AvailableAnalysis appropriately if ProcessAnalysis is true.
+ void add(Pass *P, bool ProcessAnalysis = true);
+
+ /// Add RequiredPass into list of lower level passes required by pass P.
+ /// RequiredPass is run on the fly by Pass Manager when P requests it
+ /// through getAnalysis interface.
+ virtual void addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
+ assert (0 &&
+ "Unable to handle Pass that requires lower level Analysis pass");
+ }
+
+ virtual Pass * getOnTheFlyPass(Pass *P, const PassInfo *PI, Function &F) {
+ assert (0 && "Unable to find on the fly pass");
+ return NULL;
+ }
+
+ /// Initialize available analysis information.
+ void initializeAnalysisInfo() {
+ AvailableAnalysis.clear();
+ for (unsigned i = 0; i < PMT_Last; ++i)
+ InheritedAnalysis[i] = NULL;
+ }
+
+ // Return true if P preserves high level analysis used by other
+ // passes that are managed by this manager.
+ bool preserveHigherLevelAnalysis(Pass *P);
+
+
+ /// Populate RequiredPasses with analysis pass that are required by
+ /// pass P and are available. Populate ReqPassNotAvailable with analysis
+ /// pass that are required by pass P but are not available.
+ void collectRequiredAnalysis(SmallVector<Pass *, 8> &RequiredPasses,
+ SmallVector<AnalysisID, 8> &ReqPassNotAvailable,
+ Pass *P);
+
+ /// All Required analyses should be available to the pass as it runs! Here
+ /// we fill in the AnalysisImpls member of the pass so that it can
+ /// successfully use the getAnalysis() method to retrieve the
+ /// implementations it needs.
+ void initializeAnalysisImpl(Pass *P);
+
+ /// Find the pass that implements Analysis AID. If desired pass is not found
+ /// then return NULL.
+ Pass *findAnalysisPass(AnalysisID AID, bool Direction);
+
+ // Access toplevel manager
+ PMTopLevelManager *getTopLevelManager() { return TPM; }
+ void setTopLevelManager(PMTopLevelManager *T) { TPM = T; }
+
+ unsigned getDepth() const { return Depth; }
+
+ // Print routines used by debug-pass
+ void dumpLastUses(Pass *P, unsigned Offset) const;
+ void dumpPassArguments() const;
+ void dumpPassInfo(Pass *P, enum PassDebuggingString S1,
+ enum PassDebuggingString S2, std::string Msg);
+ void dumpAnalysisSetInfo(const char *Msg, Pass *P,
+ const std::vector<AnalysisID> &Set) const;
+
+ virtual unsigned getNumContainedPasses() {
+ return PassVector.size();
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ assert ( 0 && "Invalid use of getPassManagerType");
+ return PMT_Unknown;
+ }
+
+ std::map<AnalysisID, Pass*> *getAvailableAnalysis() {
+ return &AvailableAnalysis;
+ }
+
+ // Collect AvailableAnalysis from all the active Pass Managers.
+ void populateInheritedAnalysis(PMStack &PMS) {
+ unsigned Index = 0;
+ for (PMStack::iterator I = PMS.begin(), E = PMS.end();
+ I != E; ++I)
+ InheritedAnalysis[Index++] = (*I)->getAvailableAnalysis();
+ }
+
+protected:
+
+ // Top level manager.
+ PMTopLevelManager *TPM;
+
+ // Collection of pass that are managed by this manager
+ std::vector<Pass *> PassVector;
+
+ // Collection of Analysis provided by Parent pass manager and
+ // used by current pass manager. At at time there can not be more
+ // then PMT_Last active pass mangers.
+ std::map<AnalysisID, Pass *> *InheritedAnalysis[PMT_Last];
+
+private:
+ // Set of available Analysis. This information is used while scheduling
+ // pass. If a pass requires an analysis which is not not available then
+ // equired analysis pass is scheduled to run before the pass itself is
+ // scheduled to run.
+ std::map<AnalysisID, Pass*> AvailableAnalysis;
+
+ // Collection of higher level analysis used by the pass managed by
+ // this manager.
+ std::vector<Pass *> HigherLevelAnalysis;
+
+ unsigned Depth;
+};
+
+//===----------------------------------------------------------------------===//
+// FPPassManager
+//
+/// FPPassManager manages BBPassManagers and FunctionPasses.
+/// It batches all function passes and basic block pass managers together and
+/// sequence them to process one function at a time before processing next
+/// function.
+
+class FPPassManager : public ModulePass, public PMDataManager {
+
+public:
+ static char ID;
+ explicit FPPassManager(int Depth)
+ : ModulePass((intptr_t)&ID), PMDataManager(Depth) { }
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool runOnFunction(Function &F);
+ bool runOnModule(Module &M);
+
+ /// doInitialization - Run all of the initializers for the function passes.
+ ///
+ bool doInitialization(Module &M);
+
+ /// doFinalization - Run all of the initializers for the function passes.
+ ///
+ bool doFinalization(Module &M);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.setPreservesAll();
+ }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset);
+
+ virtual const char *getPassName() const {
+ return "Function Pass Manager";
+ }
+
+ FunctionPass *getContainedPass(unsigned N) {
+ assert ( N < PassVector.size() && "Pass number out of range!");
+ FunctionPass *FP = static_cast<FunctionPass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_FunctionPassManager;
+ }
+};
+
+}
+
+extern void StartPassTimer(Pass *);
+extern void StopPassTimer(Pass *);
diff --git a/include/llvm/PassSupport.h b/include/llvm/PassSupport.h
new file mode 100644
index 0000000..f594d45
--- /dev/null
+++ b/include/llvm/PassSupport.h
@@ -0,0 +1,257 @@
+//===- llvm/PassSupport.h - Pass Support code -------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines stuff that is used to define and "use" Passes. This file
+// is automatically #included by Pass.h, so:
+//
+// NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
+//
+// Instead, #include Pass.h.
+//
+// This file defines Pass registration code and classes used for it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASS_SUPPORT_H
+#define LLVM_PASS_SUPPORT_H
+
+#include "llvm/System/IncludeFile.h"
+// No need to include Pass.h, we are being included by it!
+
+namespace llvm {
+
+class TargetMachine;
+
+//===---------------------------------------------------------------------------
+/// PassInfo class - An instance of this class exists for every pass known by
+/// the system, and can be obtained from a live Pass by calling its
+/// getPassInfo() method. These objects are set up by the RegisterPass<>
+/// template, defined below.
+///
+class PassInfo {
+ const char *PassName; // Nice name for Pass
+ const char *PassArgument; // Command Line argument to run this pass
+ intptr_t PassID;
+ bool IsCFGOnlyPass; // Pass only looks at the CFG.
+ bool IsAnalysisGroup; // True if an analysis group.
+ std::vector<const PassInfo*> ItfImpl;// Interfaces implemented by this pass
+
+ Pass *(*NormalCtor)();
+
+public:
+ /// PassInfo ctor - Do not call this directly, this should only be invoked
+ /// through RegisterPass.
+ PassInfo(const char *name, const char *arg, intptr_t pi,
+ Pass *(*normal)() = 0, bool isCFGOnly = false)
+ : PassName(name), PassArgument(arg), PassID(pi),
+ IsCFGOnlyPass(isCFGOnly), IsAnalysisGroup(false), NormalCtor(normal) {
+ }
+
+ /// getPassName - Return the friendly name for the pass, never returns null
+ ///
+ const char *getPassName() const { return PassName; }
+ void setPassName(const char *Name) { PassName = Name; }
+
+ /// getPassArgument - Return the command line option that may be passed to
+ /// 'opt' that will cause this pass to be run. This will return null if there
+ /// is no argument.
+ ///
+ const char *getPassArgument() const { return PassArgument; }
+
+ /// getTypeInfo - Return the type_info object for the pass...
+ /// TODO : Rename
+ intptr_t getTypeInfo() const { return PassID; }
+
+ /// isAnalysisGroup - Return true if this is an analysis group, not a normal
+ /// pass.
+ ///
+ bool isAnalysisGroup() const { return IsAnalysisGroup; }
+ void SetIsAnalysisGroup() { IsAnalysisGroup = true; }
+
+ /// isCFGOnlyPass - return true if this pass only looks at the CFG for the
+ /// function.
+ bool isCFGOnlyPass() const { return IsCFGOnlyPass; }
+
+ /// getNormalCtor - Return a pointer to a function, that when called, creates
+ /// an instance of the pass and returns it. This pointer may be null if there
+ /// is no default constructor for the pass.
+ ///
+ Pass *(*getNormalCtor() const)() {
+ return NormalCtor;
+ }
+ void setNormalCtor(Pass *(*Ctor)()) {
+ NormalCtor = Ctor;
+ }
+
+ /// createPass() - Use this method to create an instance of this pass.
+ Pass *createPass() const {
+ assert((!isAnalysisGroup() || NormalCtor) &&
+ "No default implementation found for analysis group!");
+ assert(NormalCtor &&
+ "Cannot call createPass on PassInfo without default ctor!");
+ return NormalCtor();
+ }
+
+ /// addInterfaceImplemented - This method is called when this pass is
+ /// registered as a member of an analysis group with the RegisterAnalysisGroup
+ /// template.
+ ///
+ void addInterfaceImplemented(const PassInfo *ItfPI) {
+ ItfImpl.push_back(ItfPI);
+ }
+
+ /// getInterfacesImplemented - Return a list of all of the analysis group
+ /// interfaces implemented by this pass.
+ ///
+ const std::vector<const PassInfo*> &getInterfacesImplemented() const {
+ return ItfImpl;
+ }
+};
+
+
+//===---------------------------------------------------------------------------
+/// RegisterPass<t> template - This template class is used to notify the system
+/// that a Pass is available for use, and registers it into the internal
+/// database maintained by the PassManager. Unless this template is used, opt,
+/// for example will not be able to see the pass and attempts to create the pass
+/// will fail. This template is used in the follow manner (at global scope, in
+/// your .cpp file):
+///
+/// static RegisterPass<YourPassClassName> tmp("passopt", "My Pass Name");
+///
+/// This statement will cause your pass to be created by calling the default
+/// constructor exposed by the pass. If you have a different constructor that
+/// must be called, create a global constructor function (which takes the
+/// arguments you need and returns a Pass*) and register your pass like this:
+///
+/// static RegisterPass<PassClassName> tmp("passopt", "My Name");
+///
+struct RegisterPassBase {
+ /// getPassInfo - Get the pass info for the registered class...
+ ///
+ const PassInfo *getPassInfo() const { return &PIObj; }
+
+ typedef Pass* (*NormalCtor_t)();
+
+ RegisterPassBase(const char *Name, const char *Arg, intptr_t TI,
+ NormalCtor_t NormalCtor = 0, bool CFGOnly = false)
+ : PIObj(Name, Arg, TI, NormalCtor, CFGOnly) {
+ registerPass();
+ }
+ RegisterPassBase(intptr_t TI)
+ : PIObj("", "", TI) {
+ // This ctor may only be used for analysis groups: it does not auto-register
+ // the pass.
+ PIObj.SetIsAnalysisGroup();
+ }
+
+protected:
+ PassInfo PIObj; // The PassInfo object for this pass
+ void registerPass();
+ void unregisterPass();
+};
+
+template<typename PassName>
+Pass *callDefaultCtor() { return new PassName(); }
+
+template<typename PassName>
+struct RegisterPass : public RegisterPassBase {
+
+ // Register Pass using default constructor...
+ RegisterPass(const char *PassArg, const char *Name, bool CFGOnly = false)
+ : RegisterPassBase(Name, PassArg, (intptr_t)&PassName::ID,
+ (RegisterPassBase::NormalCtor_t)callDefaultCtor<PassName>, CFGOnly) {
+ }
+};
+
+
+/// RegisterAnalysisGroup - Register a Pass as a member of an analysis _group_.
+/// Analysis groups are used to define an interface (which need not derive from
+/// Pass) that is required by passes to do their job. Analysis Groups differ
+/// from normal analyses because any available implementation of the group will
+/// be used if it is available.
+///
+/// If no analysis implementing the interface is available, a default
+/// implementation is created and added. A pass registers itself as the default
+/// implementation by specifying 'true' as the third template argument of this
+/// class.
+///
+/// In addition to registering itself as an analysis group member, a pass must
+/// register itself normally as well. Passes may be members of multiple groups
+/// and may still be "required" specifically by name.
+///
+/// The actual interface may also be registered as well (by not specifying the
+/// second template argument). The interface should be registered to associate
+/// a nice name with the interface.
+///
+class RegisterAGBase : public RegisterPassBase {
+ PassInfo *InterfaceInfo;
+ const PassInfo *ImplementationInfo;
+ bool isDefaultImplementation;
+protected:
+ explicit RegisterAGBase(intptr_t InterfaceID,
+ intptr_t PassID = 0,
+ bool isDefault = false);
+ void setGroupName(const char *Name);
+};
+
+template<typename Interface, bool Default = false>
+struct RegisterAnalysisGroup : public RegisterAGBase {
+ explicit RegisterAnalysisGroup(RegisterPassBase &RPB)
+ : RegisterAGBase((intptr_t) &Interface::ID, RPB.getPassInfo()->getTypeInfo(),
+ Default) {
+ }
+
+ explicit RegisterAnalysisGroup(const char *Name)
+ : RegisterAGBase((intptr_t) &Interface::ID) {
+ setGroupName(Name);
+ }
+};
+
+
+
+//===---------------------------------------------------------------------------
+/// PassRegistrationListener class - This class is meant to be derived from by
+/// clients that are interested in which passes get registered and unregistered
+/// at runtime (which can be because of the RegisterPass constructors being run
+/// as the program starts up, or may be because a shared object just got
+/// loaded). Deriving from the PassRegistationListener class automatically
+/// registers your object to receive callbacks indicating when passes are loaded
+/// and removed.
+///
+struct PassRegistrationListener {
+
+ /// PassRegistrationListener ctor - Add the current object to the list of
+ /// PassRegistrationListeners...
+ PassRegistrationListener();
+
+ /// dtor - Remove object from list of listeners...
+ ///
+ virtual ~PassRegistrationListener();
+
+ /// Callback functions - These functions are invoked whenever a pass is loaded
+ /// or removed from the current executable.
+ ///
+ virtual void passRegistered(const PassInfo *P) {}
+
+ /// enumeratePasses - Iterate over the registered passes, calling the
+ /// passEnumerate callback on each PassInfo object.
+ ///
+ void enumeratePasses();
+
+ /// passEnumerate - Callback function invoked when someone calls
+ /// enumeratePasses on this PassRegistrationListener object.
+ ///
+ virtual void passEnumerate(const PassInfo *P) {}
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/AIXDataTypesFix.h b/include/llvm/Support/AIXDataTypesFix.h
new file mode 100644
index 0000000..256e45f
--- /dev/null
+++ b/include/llvm/Support/AIXDataTypesFix.h
@@ -0,0 +1,25 @@
+//===-- llvm/Support/AIXDataTypesFix.h - Fix datatype defs ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file overrides default system-defined types and limits which cannot be
+// done in DataTypes.h.in because it is processed by autoheader first, which
+// comments out any #undef statement
+//
+//===----------------------------------------------------------------------===//
+
+// No include guards desired!
+
+#ifndef SUPPORT_DATATYPES_H
+#error "AIXDataTypesFix.h must only be included via DataTypes.h!"
+#endif
+
+// GCC is strict about defining large constants: they must have LL modifier.
+// These will be defined properly at the end of DataTypes.h
+#undef INT64_MAX
+#undef INT64_MIN
diff --git a/include/llvm/Support/Allocator.h b/include/llvm/Support/Allocator.h
new file mode 100644
index 0000000..527d4c6
--- /dev/null
+++ b/include/llvm/Support/Allocator.h
@@ -0,0 +1,48 @@
+//===--- Allocator.h - Simple memory allocation abstraction -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MallocAllocator and BumpPtrAllocator interfaces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ALLOCATOR_H
+#define LLVM_SUPPORT_ALLOCATOR_H
+
+#include <cstdlib>
+
+namespace llvm {
+
+class MallocAllocator {
+public:
+ MallocAllocator() {}
+ ~MallocAllocator() {}
+
+ void *Allocate(unsigned Size, unsigned Alignment) { return malloc(Size); }
+ void Deallocate(void *Ptr) { free(Ptr); }
+ void PrintStats() const {}
+};
+
+/// BumpPtrAllocator - This allocator is useful for containers that need very
+/// simple memory allocation strategies. In particular, this just keeps
+/// allocating memory, and never deletes it until the entire block is dead. This
+/// makes allocation speedy, but must only be used when the trade-off is ok.
+class BumpPtrAllocator {
+ void *TheMemory;
+public:
+ BumpPtrAllocator();
+ ~BumpPtrAllocator();
+
+ void *Allocate(unsigned Size, unsigned Alignment);
+ void Deallocate(void *Ptr) {}
+ void PrintStats() const;
+};
+
+} // end namespace clang
+
+#endif
diff --git a/include/llvm/Support/Annotation.h b/include/llvm/Support/Annotation.h
new file mode 100644
index 0000000..f9d9f60
--- /dev/null
+++ b/include/llvm/Support/Annotation.h
@@ -0,0 +1,216 @@
+//===-- llvm/Support/Annotation.h - Annotation classes ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the declarations for two classes: Annotation & Annotable.
+// Using these two simple classes, anything that derives from Annotable can have
+// Annotation subclasses attached to them, ready for easy retrieval.
+//
+// Annotations are designed to be easily attachable to various classes.
+//
+// The AnnotationManager class is essential for using these classes. It is
+// responsible for turning Annotation name strings into tokens [unique id #'s]
+// that may be used to search for and create annotations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ANNOTATION_H
+#define LLVM_SUPPORT_ANNOTATION_H
+
+#include <string>
+#include <cassert>
+
+namespace llvm {
+
+class AnnotationID;
+class Annotation;
+class Annotable;
+struct AnnotationManager;
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationID - This class is a thin wrapper around an unsigned integer that
+// is used to hopefully prevent errors using AnnotationID's. They may be copied
+// freely around and passed byvalue with little or no overhead.
+//
+class AnnotationID {
+ friend struct AnnotationManager;
+ unsigned ID;
+
+ AnnotationID(); // Default ctor is disabled
+ inline AnnotationID(unsigned i) : ID(i) {} // Only creatable from AnnMgr
+public:
+ inline AnnotationID(const AnnotationID &A) : ID(A.ID) {}
+
+ inline bool operator==(const AnnotationID &A) const {
+ return A.ID == ID;
+ }
+ inline bool operator<(const AnnotationID &A) const {
+ return ID < A.ID;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotation Class - This class serves as a base class for any specific
+// annotations that you might need. Simply subclass this to add extra
+// information to the annotations.
+//
+class Annotation {
+ friend class Annotable; // Annotable manipulates Next list
+ AnnotationID ID; // ID number, as obtained from AnnotationManager
+ Annotation *Next; // The next annotation in the linked list
+public:
+ inline Annotation(AnnotationID id) : ID(id), Next(0) {}
+ virtual ~Annotation(); // Designed to be subclassed
+
+ // getID - Return the unique ID# of this annotation
+ inline AnnotationID getID() const { return ID; }
+
+ // getNext - Return the next annotation in the list...
+ inline Annotation *getNext() const { return Next; }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// Annotable - This class is used as a base class for all objects that would
+// like to have annotation capability.
+//
+// Annotable objects keep their annotation list sorted as annotations are
+// inserted and deleted. This is used to ensure that annotations with identical
+// ID#'s are stored sequentially.
+//
+class Annotable {
+ mutable Annotation *AnnotationList;
+
+ Annotable(const Annotable &); // Do not implement
+ void operator=(const Annotable &); // Do not implement
+public:
+ Annotable() : AnnotationList(0) {}
+ ~Annotable();
+
+ // getAnnotation - Search the list for annotations of the specified ID. The
+ // pointer returned is either null (if no annotations of the specified ID
+ // exist), or it points to the first element of a potentially list of elements
+ // with identical ID #'s.
+ //
+ Annotation *getAnnotation(AnnotationID ID) const {
+ for (Annotation *A = AnnotationList; A; A = A->getNext())
+ if (A->getID() == ID) return A;
+ return 0;
+ }
+
+ // getOrCreateAnnotation - Search through the annotation list, if there is
+ // no annotation with the specified ID, then use the AnnotationManager to
+ // create one.
+ //
+ inline Annotation *getOrCreateAnnotation(AnnotationID ID) const;
+
+ // addAnnotation - Insert the annotation into the list in a sorted location.
+ //
+ void addAnnotation(Annotation *A) const {
+ assert(A->Next == 0 && "Annotation already in list?!?");
+
+ Annotation **AL = &AnnotationList;
+ while (*AL && (*AL)->ID < A->getID()) // Find where to insert annotation
+ AL = &((*AL)->Next);
+ A->Next = *AL; // Link the annotation in
+ *AL = A;
+ }
+
+ // unlinkAnnotation - Remove the first annotation of the specified ID... and
+ // then return the unlinked annotation. The annotation object is not deleted.
+ //
+ inline Annotation *unlinkAnnotation(AnnotationID ID) const {
+ for (Annotation **A = &AnnotationList; *A; A = &((*A)->Next))
+ if ((*A)->getID() == ID) {
+ Annotation *Ret = *A;
+ *A = Ret->Next;
+ Ret->Next = 0;
+ return Ret;
+ }
+ return 0;
+ }
+
+ // deleteAnnotation - Delete the first annotation of the specified ID in the
+ // list. Unlink unlinkAnnotation, this actually deletes the annotation object
+ //
+ bool deleteAnnotation(AnnotationID ID) const {
+ Annotation *A = unlinkAnnotation(ID);
+ delete A;
+ return A != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+//
+// AnnotationManager - This class is primarily responsible for maintaining a
+// one-to-one mapping between string Annotation names and Annotation ID numbers.
+//
+// Compared to the rest of the Annotation system, these mapping methods are
+// relatively slow, so they should be avoided by locally caching Annotation
+// ID #'s. These methods are safe to call at any time, even by static ctors, so
+// they should be used by static ctors most of the time.
+//
+// This class also provides support for annotations that are created on demand
+// by the Annotable::getOrCreateAnnotation method. To get this to work, simply
+// register an annotation handler
+//
+struct AnnotationManager {
+ typedef Annotation *(*Factory)(AnnotationID, const Annotable *, void*);
+
+ //===--------------------------------------------------------------------===//
+ // Basic ID <-> Name map functionality
+
+ static AnnotationID getID(const std::string &Name); // Name -> ID
+ static const std::string &getName(AnnotationID ID); // ID -> Name
+
+ // getID - Name -> ID + registration of a factory function for demand driven
+ // annotation support.
+ static AnnotationID getID(const std::string &Name, Factory Fact,
+ void *Data = 0);
+
+ //===--------------------------------------------------------------------===//
+ // Annotation creation on demand support...
+
+ // registerAnnotationFactory - This method is used to register a callback
+ // function used to create an annotation on demand if it is needed by the
+ // Annotable::getOrCreateAnnotation method.
+ //
+ static void registerAnnotationFactory(AnnotationID ID, Factory Func,
+ void *ExtraData = 0);
+
+ // createAnnotation - Create an annotation of the specified ID for the
+ // specified object, using a register annotation creation function.
+ //
+ static Annotation *createAnnotation(AnnotationID ID, const Annotable *Obj);
+};
+
+
+
+// getOrCreateAnnotation - Search through the annotation list, if there is
+// no annotation with the specified ID, then use the AnnotationManager to
+// create one.
+//
+inline Annotation *Annotable::getOrCreateAnnotation(AnnotationID ID) const {
+ Annotation *A = getAnnotation(ID); // Fast path, check for preexisting ann
+ if (A) return A;
+
+ // No annotation found, ask the annotation manager to create an annotation...
+ A = AnnotationManager::createAnnotation(ID, this);
+ assert(A && "AnnotationManager could not create annotation!");
+ addAnnotation(A);
+ return A;
+}
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Support/CFG.h b/include/llvm/Support/CFG.h
new file mode 100644
index 0000000..4efefa7
--- /dev/null
+++ b/include/llvm/Support/CFG.h
@@ -0,0 +1,266 @@
+//===-- llvm/Support/CFG.h - Process LLVM structures as graphs --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines specializations of GraphTraits that allow Function and
+// BasicBlock graphs to be treated as proper graphs for generic algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CFG_H
+#define LLVM_SUPPORT_CFG_H
+
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/Function.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+//===--------------------------------------------------------------------===//
+// BasicBlock pred_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class _Ptr, class _USE_iterator> // Predecessor Iterator
+class PredIterator : public forward_iterator<_Ptr, ptrdiff_t> {
+ typedef forward_iterator<_Ptr, ptrdiff_t> super;
+ _Ptr *BB;
+ _USE_iterator It;
+public:
+ typedef PredIterator<_Ptr,_USE_iterator> _Self;
+ typedef typename super::pointer pointer;
+
+ inline void advancePastNonTerminators() {
+ // Loop to ignore non terminator uses (for example PHI nodes)...
+ while (It != BB->use_end() && !isa<TerminatorInst>(*It))
+ ++It;
+ }
+
+ inline PredIterator(_Ptr *bb) : BB(bb), It(bb->use_begin()) {
+ advancePastNonTerminators();
+ }
+ inline PredIterator(_Ptr *bb, bool) : BB(bb), It(bb->use_end()) {}
+
+ inline bool operator==(const _Self& x) const { return It == x.It; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const {
+ assert(It != BB->use_end() && "pred_iterator out of range!");
+ return cast<TerminatorInst>(*It)->getParent();
+ }
+ inline pointer *operator->() const { return &(operator*()); }
+
+ inline _Self& operator++() { // Preincrement
+ assert(It != BB->use_end() && "pred_iterator out of range!");
+ ++It; advancePastNonTerminators();
+ return *this;
+ }
+
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+};
+
+typedef PredIterator<BasicBlock, Value::use_iterator> pred_iterator;
+typedef PredIterator<const BasicBlock,
+ Value::use_const_iterator> pred_const_iterator;
+
+inline pred_iterator pred_begin(BasicBlock *BB) { return pred_iterator(BB); }
+inline pred_const_iterator pred_begin(const BasicBlock *BB) {
+ return pred_const_iterator(BB);
+}
+inline pred_iterator pred_end(BasicBlock *BB) { return pred_iterator(BB, true);}
+inline pred_const_iterator pred_end(const BasicBlock *BB) {
+ return pred_const_iterator(BB, true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// BasicBlock succ_iterator definition
+//===--------------------------------------------------------------------===//
+
+template <class Term_, class BB_> // Successor Iterator
+class SuccIterator : public bidirectional_iterator<BB_, ptrdiff_t> {
+ const Term_ Term;
+ unsigned idx;
+ typedef bidirectional_iterator<BB_, ptrdiff_t> super;
+public:
+ typedef SuccIterator<Term_, BB_> _Self;
+ typedef typename super::pointer pointer;
+ // TODO: This can be random access iterator, need operator+ and stuff tho
+
+ inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
+ assert(T && "getTerminator returned null!");
+ }
+ inline SuccIterator(Term_ T, bool) // end iterator
+ : Term(T), idx(Term->getNumSuccessors()) {
+ assert(T && "getTerminator returned null!");
+ }
+
+ 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; }
+
+ inline bool operator==(const _Self& x) const { return idx == x.idx; }
+ inline bool operator!=(const _Self& x) const { return !operator==(x); }
+
+ inline pointer operator*() const { return Term->getSuccessor(idx); }
+ inline pointer operator->() const { return operator*(); }
+
+ inline _Self& operator++() { ++idx; return *this; } // Preincrement
+ inline _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ inline _Self& operator--() { --idx; return *this; } // Predecrement
+ inline _Self operator--(int) { // Postdecrement
+ _Self tmp = *this; --*this; return tmp;
+ }
+};
+
+typedef SuccIterator<TerminatorInst*, BasicBlock> succ_iterator;
+typedef SuccIterator<const TerminatorInst*,
+ const BasicBlock> succ_const_iterator;
+
+inline succ_iterator succ_begin(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator());
+}
+inline succ_const_iterator succ_begin(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator());
+}
+inline succ_iterator succ_end(BasicBlock *BB) {
+ return succ_iterator(BB->getTerminator(), true);
+}
+inline succ_const_iterator succ_end(const BasicBlock *BB) {
+ return succ_const_iterator(BB->getTerminator(), true);
+}
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks...
+
+template <> struct GraphTraits<BasicBlock*> {
+ typedef BasicBlock NodeType;
+ typedef succ_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(BasicBlock *BB) { return BB; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+template <> struct GraphTraits<const BasicBlock*> {
+ typedef const BasicBlock NodeType;
+ typedef succ_const_iterator ChildIteratorType;
+
+ static NodeType *getEntryNode(const BasicBlock *BB) { return BB; }
+
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return succ_end(N);
+ }
+};
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<BasicBlock*> > {
+ typedef BasicBlock NodeType;
+ typedef pred_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<BasicBlock *> G) { return G.Graph; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+template <> struct GraphTraits<Inverse<const BasicBlock*> > {
+ typedef const BasicBlock NodeType;
+ typedef pred_const_iterator ChildIteratorType;
+ static NodeType *getEntryNode(Inverse<const BasicBlock*> G) {
+ return G.Graph;
+ }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return pred_begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return pred_end(N);
+ }
+};
+
+
+
+//===--------------------------------------------------------------------===//
+// GraphTraits specializations for function basic block graphs (CFGs)
+//===--------------------------------------------------------------------===//
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... these are the same as the basic block iterators,
+// except that the root node is implicitly the first node of the function.
+//
+template <> struct GraphTraits<Function*> : public GraphTraits<BasicBlock*> {
+ static NodeType *getEntryNode(Function *F) { return &F->getEntryBlock(); }
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::iterator nodes_iterator;
+ static nodes_iterator nodes_begin(Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (Function *F) { return F->end(); }
+};
+template <> struct GraphTraits<const Function*> :
+ public GraphTraits<const BasicBlock*> {
+ static NodeType *getEntryNode(const Function *F) {return &F->getEntryBlock();}
+
+ // nodes_iterator/begin/end - Allow iteration over all nodes in the graph
+ typedef Function::const_iterator nodes_iterator;
+ static nodes_iterator nodes_begin(const Function *F) { return F->begin(); }
+ static nodes_iterator nodes_end (const Function *F) { return F->end(); }
+};
+
+
+// Provide specializations of GraphTraits to be able to treat a function as a
+// graph of basic blocks... and to walk it in inverse order. Inverse order for
+// a function is considered to be when traversing the predecessor edges of a BB
+// instead of the successor edges.
+//
+template <> struct GraphTraits<Inverse<Function*> > :
+ public GraphTraits<Inverse<BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<Function*> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+template <> struct GraphTraits<Inverse<const Function*> > :
+ public GraphTraits<Inverse<const BasicBlock*> > {
+ static NodeType *getEntryNode(Inverse<const Function *> G) {
+ return &G.Graph->getEntryBlock();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CallSite.h b/include/llvm/Support/CallSite.h
new file mode 100644
index 0000000..e14caad
--- /dev/null
+++ b/include/llvm/Support/CallSite.h
@@ -0,0 +1,122 @@
+//===-- llvm/Support/CallSite.h - Abstract Call & Invoke instrs -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the CallSite class, which is a handy wrapper for code that
+// wants to treat Call and Invoke instructions in a generic way.
+//
+// NOTE: This class is supposed to have "value semantics". So it should be
+// passed by value, not by reference; it should not be "new"ed or "delete"d. It
+// is efficiently copyable, assignable and constructable, with cost equivalent
+// to copying a pointer (notice that it has only a single data member).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CALLSITE_H
+#define LLVM_SUPPORT_CALLSITE_H
+
+#include "llvm/Instruction.h"
+#include "llvm/BasicBlock.h"
+
+namespace llvm {
+
+class CallInst;
+class InvokeInst;
+
+class CallSite {
+ Instruction *I;
+public:
+ CallSite() : I(0) {}
+ CallSite(CallInst *CI) : I(reinterpret_cast<Instruction*>(CI)) {}
+ CallSite(InvokeInst *II) : I(reinterpret_cast<Instruction*>(II)) {}
+ CallSite(const CallSite &CS) : I(CS.I) {}
+ CallSite &operator=(const CallSite &CS) { I = CS.I; return *this; }
+
+ /// CallSite::get - This static method is sort of like a constructor. It will
+ /// create an appropriate call site for a Call or Invoke instruction, but it
+ /// can also create a null initialized CallSite object for something which is
+ /// NOT a call site.
+ ///
+ static CallSite get(Value *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V)) {
+ if (I->getOpcode() == Instruction::Call)
+ return CallSite(reinterpret_cast<CallInst*>(I));
+ else if (I->getOpcode() == Instruction::Invoke)
+ return CallSite(reinterpret_cast<InvokeInst*>(I));
+ }
+ return CallSite();
+ }
+
+ /// getCallingConv/setCallingConv - get or set the calling convention of the
+ /// call.
+ unsigned getCallingConv() const;
+ void setCallingConv(unsigned CC);
+
+ /// getType - Return the type of the instruction that generated this call site
+ ///
+ const Type *getType() const { return I->getType(); }
+
+ /// getInstruction - Return the instruction this call site corresponds to
+ ///
+ Instruction *getInstruction() const { return I; }
+
+ /// getCaller - Return the caller function for this call site
+ ///
+ Function *getCaller() const { return I->getParent()->getParent(); }
+
+ /// getCalledValue - Return the pointer to function that is being called...
+ ///
+ Value *getCalledValue() const {
+ assert(I && "Not a call or invoke instruction!");
+ return I->getOperand(0);
+ }
+
+ /// getCalledFunction - Return the function being called if this is a direct
+ /// call, otherwise return null (if it's an indirect call).
+ ///
+ Function *getCalledFunction() const {
+ return dyn_cast<Function>(getCalledValue());
+ }
+
+ /// setCalledFunction - Set the callee to the specified value...
+ ///
+ void setCalledFunction(Value *V) {
+ assert(I && "Not a call or invoke instruction!");
+ I->setOperand(0, V);
+ }
+
+ Value *getArgument(unsigned ArgNo) const {
+ assert(arg_begin() + ArgNo < arg_end() && "Argument # out of range!");
+ return *(arg_begin()+ArgNo);
+ }
+
+ /// arg_iterator - The type of iterator to use when looping over actual
+ /// arguments at this call site...
+ typedef User::op_iterator arg_iterator;
+
+ /// arg_begin/arg_end - Return iterators corresponding to the actual argument
+ /// list for a call site.
+ ///
+ arg_iterator arg_begin() const {
+ assert(I && "Not a call or invoke instruction!");
+ if (I->getOpcode() == Instruction::Call)
+ return I->op_begin()+1; // Skip Function
+ else
+ return I->op_begin()+3; // Skip Function, BB, BB
+ }
+ arg_iterator arg_end() const { return I->op_end(); }
+ unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
+
+ bool operator<(const CallSite &CS) const {
+ return getInstruction() < CS.getInstruction();
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Casting.h b/include/llvm/Support/Casting.h
new file mode 100644
index 0000000..dc31839
--- /dev/null
+++ b/include/llvm/Support/Casting.h
@@ -0,0 +1,303 @@
+//===-- llvm/Support/Casting.h - Allow flexible, checked, casts -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the isa<X>(), cast<X>(), dyn_cast<X>(), cast_or_null<X>(),
+// and dyn_cast_or_null<X>() templates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CASTING_H
+#define LLVM_SUPPORT_CASTING_H
+
+#include <cassert>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// isa<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<typename FromCl> struct isa_impl_cl;
+
+// Define a template that can be specialized by smart pointers to reflect the
+// fact that they are automatically dereferenced, and are not involved with the
+// template selection process... the default implementation is a noop.
+//
+template<typename From> struct simplify_type {
+ typedef From SimpleType; // The real type this represents...
+
+ // An accessor to get the real value...
+ static SimpleType &getSimplifiedValue(From &Val) { return Val; }
+};
+
+template<typename From> struct simplify_type<const From> {
+ typedef const From SimpleType;
+ static SimpleType &getSimplifiedValue(const From &Val) {
+ return simplify_type<From>::getSimplifiedValue(static_cast<From&>(Val));
+ }
+};
+
+
+// isa<X> - Return true if the parameter to the template is an instance of the
+// template type argument. Used like this:
+//
+// if (isa<Type*>(myVal)) { ... }
+//
+template <typename To, typename From>
+inline bool isa_impl(const From &Val) {
+ return To::classof(&Val);
+}
+
+template<typename To, typename From, typename SimpleType>
+struct isa_impl_wrap {
+ // When From != SimplifiedType, we can simplify the type some more by using
+ // the simplify_type template.
+ static bool doit(const From &Val) {
+ return isa_impl_cl<const SimpleType>::template
+ isa<To>(simplify_type<const From>::getSimplifiedValue(Val));
+ }
+};
+
+template<typename To, typename FromTy>
+struct isa_impl_wrap<To, const FromTy, const FromTy> {
+ // When From == SimpleType, we are as simple as we are going to get.
+ static bool doit(const FromTy &Val) {
+ return isa_impl<To,FromTy>(Val);
+ }
+};
+
+// isa_impl_cl - Use class partial specialization to transform types to a single
+// canonical form for isa_impl.
+//
+template<typename FromCl>
+struct isa_impl_cl {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_wrap<ToCl,const FromCl,
+ typename simplify_type<const FromCl>::SimpleType>::doit(Val);
+ }
+};
+
+// Specialization used to strip const qualifiers off of the FromCl type...
+template<typename FromCl>
+struct isa_impl_cl<const FromCl> {
+ template<class ToCl>
+ static bool isa(const FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(Val);
+ }
+};
+
+// Define pointer traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl*> {
+ template<class ToCl>
+ static bool isa(FromCl *Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(*Val);
+ }
+};
+
+// Define reference traits in terms of base traits...
+template<class FromCl>
+struct isa_impl_cl<FromCl&> {
+ template<class ToCl>
+ static bool isa(FromCl &Val) {
+ return isa_impl_cl<FromCl>::template isa<ToCl>(&Val);
+ }
+};
+
+template <class X, class Y>
+inline bool isa(const Y &Val) {
+ return isa_impl_cl<Y>::template isa<X>(Val);
+}
+
+//===----------------------------------------------------------------------===//
+// cast<x> Support Templates
+//===----------------------------------------------------------------------===//
+
+template<class To, class From> struct cast_retty;
+
+
+// Calculate what type the 'cast' function should return, based on a requested
+// type of To and a source type of From.
+template<class To, class From> struct cast_retty_impl {
+ typedef To& ret_type; // Normal case, return Ty&
+};
+template<class To, class From> struct cast_retty_impl<To, const From> {
+ typedef const To &ret_type; // Normal case, return Ty&
+};
+
+template<class To, class From> struct cast_retty_impl<To, From*> {
+ typedef To* ret_type; // Pointer arg case, return Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+template<class To, class From> struct cast_retty_impl<To, const From*const> {
+ typedef const To* ret_type; // Constant pointer arg case, return const Ty*
+};
+
+
+template<class To, class From, class SimpleFrom>
+struct cast_retty_wrap {
+ // When the simplified type and the from type are not the same, use the type
+ // simplifier to reduce the type, then reuse cast_retty_impl to get the
+ // resultant type.
+ typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;
+};
+
+template<class To, class FromTy>
+struct cast_retty_wrap<To, FromTy, FromTy> {
+ // When the simplified type is equal to the from type, use it directly.
+ typedef typename cast_retty_impl<To,FromTy>::ret_type ret_type;
+};
+
+template<class To, class From>
+struct cast_retty {
+ typedef typename cast_retty_wrap<To, From,
+ typename simplify_type<From>::SimpleType>::ret_type ret_type;
+};
+
+// Ensure the non-simple values are converted using the simplify_type template
+// that may be specialized by smart pointers...
+//
+template<class To, class From, class SimpleFrom> struct cast_convert_val {
+ // This is not a simple type, use the template to simplify it...
+ static typename cast_retty<To, From>::ret_type doit(const From &Val) {
+ return cast_convert_val<To, SimpleFrom,
+ typename simplify_type<SimpleFrom>::SimpleType>::doit(
+ simplify_type<From>::getSimplifiedValue(Val));
+ }
+};
+
+template<class To, class FromTy> struct cast_convert_val<To,FromTy,FromTy> {
+ // This _is_ a simple type, just cast it.
+ static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
+ return reinterpret_cast<typename cast_retty<To, FromTy>::ret_type>(
+ const_cast<FromTy&>(Val));
+ }
+};
+
+
+
+// cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator asserts that the type is correct, so it does not return null
+// on failure. But it will correctly return NULL when the input is NULL.
+// Used Like this:
+//
+// cast<Instruction>(myVal)->getParent()
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type cast(const Y &Val) {
+ assert(isa<X>(Val) && "cast<Ty>() argument of incompatible type!");
+ return cast_convert_val<X, Y,
+ typename simplify_type<Y>::SimpleType>::doit(Val);
+}
+
+// cast_or_null<X> - Functionally identical to cast, except that a null value is
+// accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y*>::ret_type cast_or_null(Y *Val) {
+ if (Val == 0) return 0;
+ assert(isa<X>(Val) && "cast_or_null<Ty>() argument of incompatible type!");
+ return cast<X>(Val);
+}
+
+
+// dyn_cast<X> - Return the argument parameter cast to the specified type. This
+// casting operator returns null if the argument is of the wrong type, so it can
+// be used to test for a type as well as cast if successful. This should be
+// used in the context of an if statement like this:
+//
+// if (const Instruction *I = dyn_cast<Instruction>(myVal)) { ... }
+//
+
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast(Y Val) {
+ return isa<X>(Val) ? cast<X, Y>(Val) : 0;
+}
+
+// dyn_cast_or_null<X> - Functionally identical to dyn_cast, except that a null
+// value is accepted.
+//
+template <class X, class Y>
+inline typename cast_retty<X, Y>::ret_type dyn_cast_or_null(Y Val) {
+ return (Val && isa<X>(Val)) ? cast<X, Y>(Val) : 0;
+}
+
+
+#ifdef DEBUG_CAST_OPERATORS
+#include "llvm/Support/Debug.h"
+
+struct bar {
+ bar() {}
+private:
+ bar(const bar &);
+};
+struct foo {
+ void ext() const;
+ /* static bool classof(const bar *X) {
+ cerr << "Classof: " << X << "\n";
+ return true;
+ }*/
+};
+
+template <> inline bool isa_impl<foo,bar>(const bar &Val) {
+ cerr << "Classof: " << &Val << "\n";
+ return true;
+}
+
+
+bar *fub();
+void test(bar &B1, const bar *B2) {
+ // test various configurations of const
+ const bar &B3 = B1;
+ const bar *const B4 = B2;
+
+ // test isa
+ if (!isa<foo>(B1)) return;
+ if (!isa<foo>(B2)) return;
+ if (!isa<foo>(B3)) return;
+ if (!isa<foo>(B4)) return;
+
+ // test cast
+ foo &F1 = cast<foo>(B1);
+ const foo *F3 = cast<foo>(B2);
+ const foo *F4 = cast<foo>(B2);
+ const foo &F8 = cast<foo>(B3);
+ const foo *F9 = cast<foo>(B4);
+ foo *F10 = cast<foo>(fub());
+
+ // test cast_or_null
+ const foo *F11 = cast_or_null<foo>(B2);
+ const foo *F12 = cast_or_null<foo>(B2);
+ const foo *F13 = cast_or_null<foo>(B4);
+ const foo *F14 = cast_or_null<foo>(fub()); // Shouldn't print.
+
+ // These lines are errors...
+ //foo *F20 = cast<foo>(B2); // Yields const foo*
+ //foo &F21 = cast<foo>(B3); // Yields const foo&
+ //foo *F22 = cast<foo>(B4); // Yields const foo*
+ //foo &F23 = cast_or_null<foo>(B1);
+ //const foo &F24 = cast_or_null<foo>(B3);
+}
+
+bar *fub() { return 0; }
+void main() {
+ bar B;
+ test(B, &B);
+}
+
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
new file mode 100644
index 0000000..23b7cf3
--- /dev/null
+++ b/include/llvm/Support/CommandLine.h
@@ -0,0 +1,1332 @@
+//===- llvm/Support/CommandLine.h - Command line handler --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class implements a command line argument processor that is useful when
+// creating a tool. It provides a simple, minimalistic interface that is easily
+// extensible and supports nonlocal (library) command line options.
+//
+// Note that rather than trying to figure out what this code does, you should
+// read the library documentation located in docs/CommandLine.html or looks at
+// the many example usages in tools/*/*.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMMANDLINE_H
+#define LLVM_SUPPORT_COMMANDLINE_H
+
+#include "llvm/Support/type_traits.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+#include <vector>
+#include <utility>
+#include <cstdarg>
+#include <cassert>
+
+namespace llvm {
+
+/// cl Namespace - This namespace contains all of the command line option
+/// processing machinery. It is intentionally a short name to make qualified
+/// usage concise.
+namespace cl {
+
+//===----------------------------------------------------------------------===//
+// ParseCommandLineOptions - Command line option processing entry point.
+//
+void ParseCommandLineOptions(int &argc, char **argv,
+ const char *Overview = 0);
+
+//===----------------------------------------------------------------------===//
+// ParseEnvironmentOptions - Environment variable option processing alternate
+// entry point.
+//
+void ParseEnvironmentOptions(const char *progName, const char *envvar,
+ const char *Overview = 0);
+
+///===---------------------------------------------------------------------===//
+/// SetVersionPrinter - Override the default (LLVM specific) version printer
+/// used to print out the version when --version is given
+/// on the command line. This gives other systems using the
+/// CommandLine utilities to print their own version string.
+void SetVersionPrinter(void (*func)());
+
+
+// MarkOptionsChanged - Internal helper function.
+void MarkOptionsChanged();
+
+//===----------------------------------------------------------------------===//
+// Flags permitted to be passed to command line arguments
+//
+
+enum NumOccurrences { // Flags for the number of occurrences allowed
+ Optional = 0x01, // Zero or One occurrence
+ ZeroOrMore = 0x02, // Zero or more occurrences allowed
+ Required = 0x03, // One occurrence required
+ OneOrMore = 0x04, // One or more occurrences required
+
+ // ConsumeAfter - Indicates that this option is fed anything that follows the
+ // last positional argument required by the application (it is an error if
+ // there are zero positional arguments, and a ConsumeAfter option is used).
+ // Thus, for example, all arguments to LLI are processed until a filename is
+ // found. Once a filename is found, all of the succeeding arguments are
+ // passed, unprocessed, to the ConsumeAfter option.
+ //
+ ConsumeAfter = 0x05,
+
+ OccurrencesMask = 0x07
+};
+
+enum ValueExpected { // Is a value required for the option?
+ ValueOptional = 0x08, // The value can appear... or not
+ ValueRequired = 0x10, // The value is required to appear!
+ ValueDisallowed = 0x18, // A value may not be specified (for flags)
+ ValueMask = 0x18
+};
+
+enum OptionHidden { // Control whether -help shows this option
+ NotHidden = 0x20, // Option included in --help & --help-hidden
+ Hidden = 0x40, // -help doesn't, but --help-hidden does
+ ReallyHidden = 0x60, // Neither --help nor --help-hidden show this arg
+ HiddenMask = 0x60
+};
+
+// Formatting flags - This controls special features that the option might have
+// that cause it to be parsed differently...
+//
+// Prefix - This option allows arguments that are otherwise unrecognized to be
+// matched by options that are a prefix of the actual value. This is useful for
+// cases like a linker, where options are typically of the form '-lfoo' or
+// '-L../../include' where -l or -L are the actual flags. When prefix is
+// enabled, and used, the value for the flag comes from the suffix of the
+// argument.
+//
+// Grouping - With this option enabled, multiple letter options are allowed to
+// bunch together with only a single hyphen for the whole group. This allows
+// emulation of the behavior that ls uses for example: ls -la === ls -l -a
+//
+
+enum FormattingFlags {
+ NormalFormatting = 0x000, // Nothing special
+ Positional = 0x080, // Is a positional argument, no '-' required
+ Prefix = 0x100, // Can this option directly prefix its value?
+ Grouping = 0x180, // Can this option group with other options?
+ FormattingMask = 0x180 // Union of the above flags.
+};
+
+enum MiscFlags { // Miscellaneous flags to adjust argument
+ CommaSeparated = 0x200, // Should this cl::list split between commas?
+ PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
+ MiscMask = 0x600 // Union of the above flags.
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Option Base class
+//
+class alias;
+class Option {
+ friend void cl::ParseCommandLineOptions(int &, char **, const char *);
+ friend class alias;
+
+ // handleOccurrences - Overriden by subclasses to handle the value passed into
+ // an argument. Should return true if there was an error processing the
+ // argument and the program should exit.
+ //
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) = 0;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // Out of line virtual function to provide home for the class.
+ virtual void anchor();
+
+ int NumOccurrences; // The number of times specified
+ int Flags; // Flags for the argument
+ unsigned Position; // Position of last occurrence of the option
+ Option *NextRegistered; // Singly linked list of registered options.
+public:
+ const char *ArgStr; // The argument string itself (ex: "help", "o")
+ const char *HelpStr; // The descriptive text message for --help
+ const char *ValueStr; // String describing what the value of this option is
+
+ inline enum NumOccurrences getNumOccurrencesFlag() const {
+ return static_cast<enum NumOccurrences>(Flags & OccurrencesMask);
+ }
+ inline enum ValueExpected getValueExpectedFlag() const {
+ int VE = Flags & ValueMask;
+ return VE ? static_cast<enum ValueExpected>(VE)
+ : getValueExpectedFlagDefault();
+ }
+ inline enum OptionHidden getOptionHiddenFlag() const {
+ return static_cast<enum OptionHidden>(Flags & HiddenMask);
+ }
+ inline enum FormattingFlags getFormattingFlag() const {
+ return static_cast<enum FormattingFlags>(Flags & FormattingMask);
+ }
+ inline unsigned getMiscFlags() const {
+ return Flags & MiscMask;
+ }
+ inline unsigned getPosition() const { return Position; }
+
+ // hasArgStr - Return true if the argstr != ""
+ bool hasArgStr() const { return ArgStr[0] != 0; }
+
+ //-------------------------------------------------------------------------===
+ // Accessor functions set by OptionModifiers
+ //
+ void setArgStr(const char *S) { ArgStr = S; }
+ void setDescription(const char *S) { HelpStr = S; }
+ void setValueStr(const char *S) { ValueStr = S; }
+
+ void setFlag(unsigned Flag, unsigned FlagMask) {
+ Flags &= ~FlagMask;
+ Flags |= Flag;
+ }
+
+ void setNumOccurrencesFlag(enum NumOccurrences Val) {
+ setFlag(Val, OccurrencesMask);
+ }
+ void setValueExpectedFlag(enum ValueExpected Val) { setFlag(Val, ValueMask); }
+ void setHiddenFlag(enum OptionHidden Val) { setFlag(Val, HiddenMask); }
+ void setFormattingFlag(enum FormattingFlags V) { setFlag(V, FormattingMask); }
+ void setMiscFlag(enum MiscFlags M) { setFlag(M, M); }
+ void setPosition(unsigned pos) { Position = pos; }
+protected:
+ explicit Option(unsigned DefaultFlags)
+ : NumOccurrences(0), Flags(DefaultFlags | NormalFormatting), Position(0),
+ NextRegistered(0), ArgStr(""), HelpStr(""), ValueStr("") {
+ assert(getNumOccurrencesFlag() != 0 &&
+ getOptionHiddenFlag() != 0 && "Not all default flags specified!");
+ }
+
+public:
+ // addArgument - Register this argument with the commandline system.
+ //
+ void addArgument();
+
+ Option *getNextRegisteredOption() const { return NextRegistered; }
+
+ // Return the width of the option tag for printing...
+ virtual unsigned getOptionWidth() const = 0;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(unsigned GlobalWidth) const = 0;
+
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {}
+
+ // addOccurrence - Wrapper around handleOccurrence that enforces Flags
+ //
+ bool addOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Value);
+
+ // Prints option name followed by message. Always returns true.
+ bool error(std::string Message, const char *ArgName = 0);
+
+public:
+ inline int getNumOccurrences() const { return NumOccurrences; }
+ virtual ~Option() {}
+};
+
+
+//===----------------------------------------------------------------------===//
+// Command line option modifiers that can be used to modify the behavior of
+// command line option parsers...
+//
+
+// desc - Modifier to set the description shown in the --help output...
+struct desc {
+ const char *Desc;
+ desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setDescription(Desc); }
+};
+
+// value_desc - Modifier to set the value description shown in the --help
+// output...
+struct value_desc {
+ const char *Desc;
+ value_desc(const char *Str) : Desc(Str) {}
+ void apply(Option &O) const { O.setValueStr(Desc); }
+};
+
+// init - Specify a default (initial) value for the command line argument, if
+// the default constructor for the argument type does not give you what you
+// want. This is only valid on "opt" arguments, not on "list" arguments.
+//
+template<class Ty>
+struct initializer {
+ const Ty &Init;
+ initializer(const Ty &Val) : Init(Val) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setInitialValue(Init); }
+};
+
+template<class Ty>
+initializer<Ty> init(const Ty &Val) {
+ return initializer<Ty>(Val);
+}
+
+
+// location - Allow the user to specify which external variable they want to
+// store the results of the command line argument processing into, if they don't
+// want to store it in the option itself.
+//
+template<class Ty>
+struct LocationClass {
+ Ty &Loc;
+ LocationClass(Ty &L) : Loc(L) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setLocation(O, Loc); }
+};
+
+template<class Ty>
+LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+
+
+//===----------------------------------------------------------------------===//
+// Enum valued command line option
+//
+#define clEnumVal(ENUMVAL, DESC) #ENUMVAL, int(ENUMVAL), DESC
+#define clEnumValN(ENUMVAL, FLAGNAME, DESC) FLAGNAME, int(ENUMVAL), DESC
+#define clEnumValEnd (reinterpret_cast<void*>(0))
+
+// values - For custom data types, allow specifying a group of values together
+// as the values that go into the mapping that the option handler uses. Note
+// that the values list must always have a 0 at the end of the list to indicate
+// that the list has ended.
+//
+template<class DataType>
+class ValuesClass {
+ // Use a vector instead of a map, because the lists should be short,
+ // the overhead is less, and most importantly, it keeps them in the order
+ // inserted so we can print our option out nicely.
+ SmallVector<std::pair<const char *, std::pair<int, const char *> >,4> Values;
+ void processValues(va_list Vals);
+public:
+ ValuesClass(const char *EnumName, DataType Val, const char *Desc,
+ va_list ValueArgs) {
+ // Insert the first value, which is required.
+ Values.push_back(std::make_pair(EnumName, std::make_pair(Val, Desc)));
+
+ // Process the varargs portion of the values...
+ while (const char *EnumName = va_arg(ValueArgs, const char *)) {
+ DataType EnumVal = static_cast<DataType>(va_arg(ValueArgs, int));
+ const char *EnumDesc = va_arg(ValueArgs, const char *);
+ Values.push_back(std::make_pair(EnumName, // Add value to value map
+ std::make_pair(EnumVal, EnumDesc)));
+ }
+ }
+
+ template<class Opt>
+ void apply(Opt &O) const {
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
+ Values[i].second.second);
+ }
+};
+
+template<class DataType>
+ValuesClass<DataType> END_WITH_NULL values(const char *Arg, DataType Val,
+ const char *Desc, ...) {
+ va_list ValueArgs;
+ va_start(ValueArgs, Desc);
+ ValuesClass<DataType> Vals(Arg, Val, Desc, ValueArgs);
+ va_end(ValueArgs);
+ return Vals;
+}
+
+
+//===----------------------------------------------------------------------===//
+// parser class - Parameterizable parser for different data types. By default,
+// known data types (string, int, bool) have specialized parsers, that do what
+// you would expect. The default parser, used for data types that are not
+// built-in, uses a mapping table to map specific options to values, which is
+// used, among other things, to handle enum types.
+
+//--------------------------------------------------
+// generic_parser_base - This class holds all the non-generic code that we do
+// not need replicated for every instance of the generic parser. This also
+// allows us to put stuff into CommandLine.cpp
+//
+struct generic_parser_base {
+ virtual ~generic_parser_base() {} // Base class should have virtual-dtor
+
+ // getNumOptions - Virtual function implemented by generic subclass to
+ // indicate how many entries are in Values.
+ //
+ virtual unsigned getNumOptions() const = 0;
+
+ // getOption - Return option name N.
+ virtual const char *getOption(unsigned N) const = 0;
+
+ // getDescription - Return description N
+ virtual const char *getDescription(unsigned N) const = 0;
+
+ // Return the width of the option tag for printing...
+ virtual unsigned getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ virtual void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
+
+ void initialize(Option &O) {
+ // All of the modifiers for the option have been processed by now, so the
+ // argstr field should be stable, copy it down now.
+ //
+ hasArgStr = O.hasArgStr();
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ // If there has been no argstr specified, that means that we need to add an
+ // argument for every possible option. This ensures that our options are
+ // vectored to us.
+ if (!hasArgStr)
+ for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
+ OptionNames.push_back(getOption(i));
+ }
+
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ // If there is an ArgStr specified, then we are of the form:
+ //
+ // -opt=O2 or -opt O2 or -optO2
+ //
+ // In which case, the value is required. Otherwise if an arg str has not
+ // been specified, we are of the form:
+ //
+ // -O2 or O2 or -la (where -l and -a are separate options)
+ //
+ // If this is the case, we cannot allow a value.
+ //
+ if (hasArgStr)
+ return ValueRequired;
+ else
+ return ValueDisallowed;
+ }
+
+ // findOption - Return the option number corresponding to the specified
+ // argument string. If the option is not found, getNumOptions() is returned.
+ //
+ unsigned findOption(const char *Name);
+
+protected:
+ bool hasArgStr;
+};
+
+// Default parser implementation - This implementation depends on having a
+// mapping of recognized options to values of some sort. In addition to this,
+// each entry in the mapping also tracks a help message that is printed with the
+// command line option for --help. Because this is a simple mapping parser, the
+// data type can be any unsupported type.
+//
+template <class DataType>
+class parser : public generic_parser_base {
+protected:
+ SmallVector<std::pair<const char *,
+ std::pair<DataType, const char *> >, 8> Values;
+public:
+ typedef DataType parser_data_type;
+
+ // Implement virtual functions needed by generic_parser_base
+ unsigned getNumOptions() const { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const { return Values[N].first; }
+ const char *getDescription(unsigned N) const {
+ return Values[N].second.second;
+ }
+
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ DataType &V) {
+ std::string ArgVal;
+ if (hasArgStr)
+ ArgVal = Arg;
+ else
+ ArgVal = ArgName;
+
+ for (unsigned i = 0, e = Values.size(); i != e; ++i)
+ if (ArgVal == Values[i].first) {
+ V = Values[i].second.first;
+ return false;
+ }
+
+ return O.error(": Cannot find option named '" + ArgVal + "'!");
+ }
+
+ /// addLiteralOption - Add an entry to the mapping table.
+ ///
+ template <class DT>
+ void addLiteralOption(const char *Name, const DT &V, const char *HelpStr) {
+ assert(findOption(Name) == Values.size() && "Option already exists!");
+ Values.push_back(std::make_pair(Name,
+ std::make_pair(static_cast<DataType>(V),HelpStr)));
+ MarkOptionsChanged();
+ }
+
+ /// removeLiteralOption - Remove the specified option.
+ ///
+ void removeLiteralOption(const char *Name) {
+ unsigned N = findOption(Name);
+ assert(N != Values.size() && "Option not found!");
+ Values.erase(Values.begin()+N);
+ }
+};
+
+//--------------------------------------------------
+// basic_parser - Super class of parsers to provide boilerplate code
+//
+struct basic_parser_impl { // non-template implementation of basic_parser<t>
+ virtual ~basic_parser_impl() {}
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueRequired;
+ }
+
+ void getExtraOptionNames(std::vector<const char*> &OptionNames) {}
+
+ void initialize(Option &O) {}
+
+ // Return the width of the option tag for printing...
+ unsigned getOptionWidth(const Option &O) const;
+
+ // printOptionInfo - Print out information about this option. The
+ // to-be-maintained width is specified.
+ //
+ void printOptionInfo(const Option &O, unsigned GlobalWidth) const;
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "value"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+// basic_parser - The real basic parser is just a template wrapper that provides
+// a typedef for the provided data type.
+//
+template<class DataType>
+struct basic_parser : public basic_parser_impl {
+ typedef DataType parser_data_type;
+};
+
+//--------------------------------------------------
+// parser<bool>
+//
+template<>
+class parser<bool> : public basic_parser<bool> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
+
+//--------------------------------------------------
+// parser<boolOrDefault>
+enum boolOrDefault { BOU_UNSET, BOU_TRUE, BOU_FALSE };
+template<>
+class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ boolOrDefault &Val);
+
+ enum ValueExpected getValueExpectedFlagDefault() const {
+ return ValueOptional;
+ }
+
+ // getValueName - Do not print =<value> at all.
+ virtual const char *getValueName() const { return 0; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
+
+//--------------------------------------------------
+// parser<int>
+//
+template<>
+class parser<int> : public basic_parser<int> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *ArgName, const std::string &Arg, int &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "int"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
+
+
+//--------------------------------------------------
+// parser<unsigned>
+//
+template<>
+class parser<unsigned> : public basic_parser<unsigned> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, unsigned &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "uint"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
+
+//--------------------------------------------------
+// parser<double>
+//
+template<>
+class parser<double> : public basic_parser<double> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, double &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
+
+//--------------------------------------------------
+// parser<float>
+//
+template<>
+class parser<float> : public basic_parser<float> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg, float &Val);
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "number"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
+
+//--------------------------------------------------
+// parser<std::string>
+//
+template<>
+class parser<std::string> : public basic_parser<std::string> {
+public:
+ // parse - Return true on error.
+ bool parse(Option &O, const char *AN, const std::string &Arg,
+ std::string &Value) {
+ Value = Arg;
+ return false;
+ }
+
+ // getValueName - Overload in subclass to provide a better default value.
+ virtual const char *getValueName() const { return "string"; }
+
+ // An out-of-line virtual method to provide a 'home' for this class.
+ virtual void anchor();
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
+
+//===----------------------------------------------------------------------===//
+// applicator class - This class is used because we must use partial
+// specialization to handle literal string arguments specially (const char* does
+// not correctly respond to the apply method). Because the syntax to use this
+// is a pain, we have the 'apply' method below to handle the nastiness...
+//
+template<class Mod> struct applicator {
+ template<class Opt>
+ static void opt(const Mod &M, Opt &O) { M.apply(O); }
+};
+
+// Handle const char* as a special case...
+template<unsigned n> struct applicator<char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<unsigned n> struct applicator<const char[n]> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+template<> struct applicator<const char*> {
+ template<class Opt>
+ static void opt(const char *Str, Opt &O) { O.setArgStr(Str); }
+};
+
+template<> struct applicator<NumOccurrences> {
+ static void opt(NumOccurrences NO, Option &O) { O.setNumOccurrencesFlag(NO); }
+};
+template<> struct applicator<ValueExpected> {
+ static void opt(ValueExpected VE, Option &O) { O.setValueExpectedFlag(VE); }
+};
+template<> struct applicator<OptionHidden> {
+ static void opt(OptionHidden OH, Option &O) { O.setHiddenFlag(OH); }
+};
+template<> struct applicator<FormattingFlags> {
+ static void opt(FormattingFlags FF, Option &O) { O.setFormattingFlag(FF); }
+};
+template<> struct applicator<MiscFlags> {
+ static void opt(MiscFlags MF, Option &O) { O.setMiscFlag(MF); }
+};
+
+// apply method - Apply a modifier to an option in a type safe way.
+template<class Mod, class Opt>
+void apply(const Mod &M, Opt *O) {
+ applicator<Mod>::opt(M, *O);
+}
+
+
+//===----------------------------------------------------------------------===//
+// opt_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, bool ExternalStorage, bool isClass>
+class opt_storage {
+ DataType *Location; // Where to store the object...
+
+ void check() {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage, "
+ "or cl::init specified before cl::location()!!");
+ }
+public:
+ opt_storage() : Location(0) {}
+
+ bool setLocation(Option &O, DataType &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void setValue(const T &V) {
+ check();
+ *Location = V;
+ }
+
+ DataType &getValue() { check(); return *Location; }
+ const DataType &getValue() const { check(); return *Location; }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class opt_storage<DataType,false,true> : public DataType {
+public:
+ template<class T>
+ void setValue(const T &V) { DataType::operator=(V); }
+
+ DataType &getValue() { return *this; }
+ const DataType &getValue() const { return *this; }
+};
+
+// Define a partial specialization to handle things we cannot inherit from. In
+// this case, we store an instance through containment, and overload operators
+// to get at the value.
+//
+template<class DataType>
+class opt_storage<DataType, false, false> {
+public:
+ DataType Value;
+
+ // Make sure we initialize the value with the default constructor for the
+ // type.
+ opt_storage() : Value(DataType()) {}
+
+ template<class T>
+ void setValue(const T &V) { Value = V; }
+ DataType &getValue() { return Value; }
+ DataType getValue() const { return Value; }
+
+ // If the datatype is a pointer, support -> on it.
+ DataType operator->() const { return Value; }
+};
+
+
+//===----------------------------------------------------------------------===//
+// opt - A scalar command line option.
+//
+template <class DataType, bool ExternalStorage = false,
+ class ParserClass = parser<DataType> >
+class opt : public Option,
+ public opt_storage<DataType, ExternalStorage,
+ is_class<DataType>::value> {
+ ParserClass Parser;
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse error!
+ setValue(Val);
+ setPosition(pos);
+ return false;
+ }
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ // setInitialValue - Used by the cl::init modifier...
+ void setInitialValue(const DataType &V) { this->setValue(V); }
+
+ ParserClass &getParser() { return Parser; }
+
+ operator DataType() const { return this->getValue(); }
+
+ template<class T>
+ DataType &operator=(const T &Val) {
+ this->setValue(Val);
+ return this->getValue();
+ }
+
+ // One option...
+ template<class M0t>
+ opt(const M0t &M0) : Option(Optional | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+
+ // Two options...
+ template<class M0t, class M1t>
+ opt(const M0t &M0, const M1t &M1) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ opt(const M0t &M0, const M1t &M1,
+ const M2t &M2) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2,
+ const M3t &M3) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5,
+ const M6t &M6) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ opt(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(Optional | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+EXTERN_TEMPLATE_INSTANTIATION(class opt<unsigned>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
+EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
+
+//===----------------------------------------------------------------------===//
+// list_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class list_storage {
+ StorageClass *Location; // Where to store the object...
+
+public:
+ list_storage() : Location(0) {}
+
+ bool setLocation(Option &O, StorageClass &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ Location->push_back(V);
+ }
+};
+
+
+// Define how to hold a class type object, such as a string. Since we can
+// inherit from a class, we do so. This makes us exactly compatible with the
+// object in all cases that it is used.
+//
+template<class DataType>
+class list_storage<DataType, bool> : public std::vector<DataType> {
+public:
+ template<class T>
+ void addValue(const T &V) { push_back(V); }
+};
+
+
+//===----------------------------------------------------------------------===//
+// list - A list of command line options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class list : public Option, public list_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ list(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ list(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ list(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// bits_storage class
+
+// Default storage class definition: external storage. This implementation
+// assumes the user will specify a variable to store the data into with the
+// cl::location(x) modifier.
+//
+template<class DataType, class StorageClass>
+class bits_storage {
+ unsigned *Location; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * 8 &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ bits_storage() : Location(0) {}
+
+ bool setLocation(Option &O, unsigned &L) {
+ if (Location)
+ return O.error(": cl::location(x) specified more than once!");
+ Location = &L;
+ return false;
+ }
+
+ template<class T>
+ void addValue(const T &V) {
+ assert(Location != 0 && "cl::location(...) not specified for a command "
+ "line option with external storage!");
+ *Location |= Bit(V);
+ }
+
+ unsigned getBits() { return *Location; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (*Location & Bit(V)) != 0;
+ }
+};
+
+
+// Define how to hold bits. Since we can inherit from a class, we do so.
+// This makes us exactly compatible with the bits in all cases that it is used.
+//
+template<class DataType>
+class bits_storage<DataType, bool> {
+ unsigned Bits; // Where to store the bits...
+
+ template<class T>
+ static unsigned Bit(const T &V) {
+ unsigned BitPos = reinterpret_cast<unsigned>(V);
+ assert(BitPos < sizeof(unsigned) * 8 &&
+ "enum exceeds width of bit vector!");
+ return 1 << BitPos;
+ }
+
+public:
+ template<class T>
+ void addValue(const T &V) {
+ Bits |= Bit(V);
+ }
+
+ unsigned getBits() { return Bits; }
+
+ template<class T>
+ bool isSet(const T &V) {
+ return (Bits & Bit(V)) != 0;
+ }
+};
+
+
+//===----------------------------------------------------------------------===//
+// bits - A bit vector of command options.
+//
+template <class DataType, class Storage = bool,
+ class ParserClass = parser<DataType> >
+class bits : public Option, public bits_storage<DataType, Storage> {
+ std::vector<unsigned> Positions;
+ ParserClass Parser;
+
+ virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ return Parser.getValueExpectedFlagDefault();
+ }
+ virtual void getExtraOptionNames(std::vector<const char*> &OptionNames) {
+ return Parser.getExtraOptionNames(OptionNames);
+ }
+
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ typename ParserClass::parser_data_type Val =
+ typename ParserClass::parser_data_type();
+ if (Parser.parse(*this, ArgName, Arg, Val))
+ return true; // Parse Error!
+ addValue(Val);
+ setPosition(pos);
+ Positions.push_back(pos);
+ return false;
+ }
+
+ // Forward printing stuff to the parser...
+ virtual unsigned getOptionWidth() const {return Parser.getOptionWidth(*this);}
+ virtual void printOptionInfo(unsigned GlobalWidth) const {
+ Parser.printOptionInfo(*this, GlobalWidth);
+ }
+
+ void done() {
+ addArgument();
+ Parser.initialize(*this);
+ }
+public:
+ ParserClass &getParser() { return Parser; }
+
+ unsigned getPosition(unsigned optnum) const {
+ assert(optnum < this->size() && "Invalid option index");
+ return Positions[optnum];
+ }
+
+ // One option...
+ template<class M0t>
+ bits(const M0t &M0) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ bits(const M0t &M0, const M1t &M1) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+ // Five options...
+ template<class M0t, class M1t, class M2t, class M3t, class M4t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this);
+ done();
+ }
+ // Six options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this);
+ done();
+ }
+ // Seven options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6)
+ : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this);
+ done();
+ }
+ // Eight options...
+ template<class M0t, class M1t, class M2t, class M3t,
+ class M4t, class M5t, class M6t, class M7t>
+ bits(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3,
+ const M4t &M4, const M5t &M5, const M6t &M6,
+ const M7t &M7) : Option(ZeroOrMore | NotHidden) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ apply(M4, this); apply(M5, this); apply(M6, this); apply(M7, this);
+ done();
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// Aliased command line option (alias this name to a preexisting name)
+//
+
+class alias : public Option {
+ Option *AliasFor;
+ virtual bool handleOccurrence(unsigned pos, const char *ArgName,
+ const std::string &Arg) {
+ return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
+ }
+ // Handle printing stuff...
+ virtual unsigned getOptionWidth() const;
+ virtual void printOptionInfo(unsigned GlobalWidth) const;
+
+ void done() {
+ if (!hasArgStr())
+ error(": cl::alias must have argument name specified!");
+ if (AliasFor == 0)
+ error(": cl::alias must have an cl::aliasopt(option) specified!");
+ addArgument();
+ }
+public:
+ void setAliasFor(Option &O) {
+ if (AliasFor)
+ error(": cl::alias must only have one cl::aliasopt(...) specified!");
+ AliasFor = &O;
+ }
+
+ // One option...
+ template<class M0t>
+ alias(const M0t &M0) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this);
+ done();
+ }
+ // Two options...
+ template<class M0t, class M1t>
+ alias(const M0t &M0, const M1t &M1) : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this);
+ done();
+ }
+ // Three options...
+ template<class M0t, class M1t, class M2t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this);
+ done();
+ }
+ // Four options...
+ template<class M0t, class M1t, class M2t, class M3t>
+ alias(const M0t &M0, const M1t &M1, const M2t &M2, const M3t &M3)
+ : Option(Optional | Hidden), AliasFor(0) {
+ apply(M0, this); apply(M1, this); apply(M2, this); apply(M3, this);
+ done();
+ }
+};
+
+// aliasfor - Modifier to set the option an alias aliases.
+struct aliasopt {
+ Option &Opt;
+ aliasopt(Option &O) : Opt(O) {}
+ void apply(alias &A) const { A.setAliasFor(Opt); }
+};
+
+// extrahelp - provide additional help at the end of the normal help
+// output. All occurrences of cl::extrahelp will be accumulated and
+// printed to std::cerr at the end of the regular help, just before
+// exit is called.
+struct extrahelp {
+ const char * morehelp;
+ extrahelp(const char* help);
+};
+
+void PrintVersionMessage();
+// This function just prints the help message, exactly the same way as if the
+// --help option had been given on the command line.
+// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+void PrintHelpMessage();
+
+} // End namespace cl
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Support/Compiler.h b/include/llvm/Support/Compiler.h
new file mode 100644
index 0000000..06be685
--- /dev/null
+++ b/include/llvm/Support/Compiler.h
@@ -0,0 +1,48 @@
+//===-- llvm/Support/Compiler.h - Compiler abstraction support --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines several macros, based on the current compiler. This allows
+// use of compiler-specific features in a way that remains portable.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_COMPILER_H
+#define LLVM_SUPPORT_COMPILER_H
+
+// The VISIBILITY_HIDDEN macro, used for marking classes with the GCC-specific
+// visibility("hidden") attribute.
+#if __GNUC__ >= 4
+#define VISIBILITY_HIDDEN __attribute__ ((visibility("hidden")))
+#else
+#define VISIBILITY_HIDDEN
+#endif
+
+
+// C++ doesn't support 'extern template' of template specializations. GCC does,
+// but requires __extension__ before it. In the header, use this:
+// EXTERN_TEMPLATE_INSTANTIATION(class foo<bar>);
+// in the .cpp file, use this:
+// TEMPLATE_INSTANTIATION(class foo<bar>);
+#ifdef __GNUC__
+#define EXTERN_TEMPLATE_INSTANTIATION(X) __extension__ extern template X
+#define TEMPLATE_INSTANTIATION(X) template X
+#else
+#define EXTERN_TEMPLATE_INSTANTIATION(X)
+#define TEMPLATE_INSTANTIATION(X)
+#endif
+
+// DISABLE_INLINE - On compilers where we have a directive to do so, mark a
+// method "not for inlining".
+#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+#define DISABLE_INLINE __attribute__((noinline))
+#else
+#define DISABLE_INLINE
+#endif
+
+#endif
diff --git a/include/llvm/Support/ConstantRange.h b/include/llvm/Support/ConstantRange.h
new file mode 100644
index 0000000..778827c
--- /dev/null
+++ b/include/llvm/Support/ConstantRange.h
@@ -0,0 +1,198 @@
+//===-- llvm/Support/ConstantRange.h - Represent a range --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Represent a range of possible values that may occur when the program is run
+// for an integral value. This keeps track of a lower and upper bound for the
+// constant, which MAY wrap around the end of the numeric range. To do this, it
+// keeps track of a [lower, upper) bound, which specifies an interval just like
+// STL iterators. When used with boolean values, the following are important
+// ranges: :
+//
+// [F, F) = {} = Empty set
+// [T, F) = {T}
+// [F, T) = {F}
+// [T, T) = {F, T} = Full set
+//
+// The other integral ranges use min/max values for special range values. For
+// example, for 8-bit types, it uses:
+// [0, 0) = {} = Empty set
+// [255, 255) = {0..255} = Full Set
+//
+// Note that ConstantRange always keeps unsigned values.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_CONSTANT_RANGE_H
+#define LLVM_SUPPORT_CONSTANT_RANGE_H
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include <iosfwd>
+
+namespace llvm {
+
+class ConstantRange {
+ APInt Lower, Upper;
+ static ConstantRange intersect1Wrapped(const ConstantRange &LHS,
+ const ConstantRange &RHS);
+ public:
+ /// Initialize a full (the default) or empty set for the specified bit width.
+ ///
+ ConstantRange(uint32_t BitWidth, bool isFullSet = true);
+
+ /// Initialize a range to hold the single specified value.
+ ///
+ ConstantRange(const APInt &Value);
+
+ /// @brief Initialize a range of values explicitly. This will assert out if
+ /// Lower==Upper and Lower != Min or Max value for its type. It will also
+ /// assert out if the two APInt's are not the same bit width.
+ ConstantRange(const APInt& Lower, const APInt& Upper);
+
+ /// getLower - Return the lower value for this range...
+ ///
+ const APInt &getLower() const { return Lower; }
+
+ /// getUpper - Return the upper value for this range...
+ ///
+ const APInt &getUpper() const { return Upper; }
+
+ /// getBitWidth - get the bit width of this ConstantRange
+ ///
+ uint32_t getBitWidth() const { return Lower.getBitWidth(); }
+
+ /// isFullSet - Return true if this set contains all of the elements possible
+ /// for this data-type
+ ///
+ bool isFullSet() const;
+
+ /// isEmptySet - Return true if this set contains no members.
+ ///
+ bool isEmptySet() const;
+
+ /// isWrappedSet - Return true if this set wraps around the top of the range,
+ /// for example: [100, 8)
+ ///
+ bool isWrappedSet() const;
+
+ /// contains - Return true if the specified value is in the set.
+ ///
+ bool contains(const APInt &Val) const;
+
+ /// getSingleElement - If this set contains a single element, return it,
+ /// otherwise return null.
+ ///
+ const APInt *getSingleElement() const {
+ if (Upper == Lower + 1)
+ return &Lower;
+ return 0;
+ }
+
+ /// isSingleElement - Return true if this set contains exactly one member.
+ ///
+ bool isSingleElement() const { return getSingleElement() != 0; }
+
+ /// getSetSize - Return the number of elements in this set.
+ ///
+ APInt getSetSize() const;
+
+ /// getUnsignedMax - Return the largest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMax() const;
+
+ /// getUnsignedMin - Return the smallest unsigned value contained in the
+ /// ConstantRange.
+ ///
+ APInt getUnsignedMin() const;
+
+ /// getSignedMax - Return the largest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMax() const;
+
+ /// getSignedMin - Return the smallest signed value contained in the
+ /// ConstantRange.
+ ///
+ APInt getSignedMin() const;
+
+ /// operator== - Return true if this range is equal to another range.
+ ///
+ bool operator==(const ConstantRange &CR) const {
+ return Lower == CR.Lower && Upper == CR.Upper;
+ }
+ bool operator!=(const ConstantRange &CR) const {
+ return !operator==(CR);
+ }
+
+ /// subtract - Subtract the specified constant from the endpoints of this
+ /// constant range.
+ ConstantRange subtract(const APInt &CI) const;
+
+ /// intersectWith - Return the range that results from the intersection of
+ /// this range with another range. The resultant range is pruned as much as
+ /// possible, but there may be cases where elements are included that are in
+ /// one of the sets but not the other. For example: [100, 8) intersect [3,
+ /// 120) yields [3, 120)
+ ///
+ ConstantRange intersectWith(const ConstantRange &CR) const;
+
+ /// maximalIntersectWith - Return the range that results from the intersection
+ /// of this range with another range. The resultant range is guaranteed to
+ /// include all elements contained in both input ranges, and to have the
+ /// smallest possible set size that does so. Because there may be two
+ /// intersections with the same set size, A.maximalIntersectWith(B) might not
+ /// be equal to B.maximalIntersectWith(A).
+ ///
+ ConstantRange maximalIntersectWith(const ConstantRange &CR) const;
+
+ /// unionWith - Return the range that results from the union of this range
+ /// with another range. The resultant range is guaranteed to include the
+ /// elements of both sets, but may contain more. For example, [3, 9) union
+ /// [12,15) is [3, 15), which includes 9, 10, and 11, which were not included
+ /// in either set before.
+ ///
+ ConstantRange unionWith(const ConstantRange &CR) const;
+
+ /// zeroExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// zero extended to BitWidth.
+ ConstantRange zeroExtend(uint32_t BitWidth) const;
+
+ /// signExtend - Return a new range in the specified integer type, which must
+ /// be strictly larger than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// sign extended to BitWidth.
+ ConstantRange signExtend(uint32_t BitWidth) const;
+
+ /// truncate - Return a new range in the specified integer type, which must be
+ /// strictly smaller than the current type. The returned range will
+ /// correspond to the possible range of values if the source range had been
+ /// truncated to the specified type.
+ ConstantRange truncate(uint32_t BitWidth) const;
+
+ /// print - Print out the bounds to a stream...
+ ///
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ /// dump - Allow printing from a debugger easily...
+ ///
+ void dump() const;
+};
+
+inline std::ostream &operator<<(std::ostream &OS, const ConstantRange &CR) {
+ CR.print(OS);
+ return OS;
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/DOTGraphTraits.h b/include/llvm/Support/DOTGraphTraits.h
new file mode 100644
index 0000000..ed59303
--- /dev/null
+++ b/include/llvm/Support/DOTGraphTraits.h
@@ -0,0 +1,122 @@
+//===-- llvm/Support/DotGraphTraits.h - Customize .dot output ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a template class that can be used to customize dot output
+// graphs generated by the GraphWriter.h file. The default implementation of
+// this file will produce a simple, but not very polished graph. By
+// specializing this template, lots of customization opportunities are possible.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DOTGRAPHTRAITS_H
+#define LLVM_SUPPORT_DOTGRAPHTRAITS_H
+
+#include <string>
+
+namespace llvm {
+
+/// DefaultDOTGraphTraits - This class provides the default implementations of
+/// all of the DOTGraphTraits methods. If a specialization does not need to
+/// override all methods here it should inherit so that it can get the default
+/// implementations.
+///
+struct DefaultDOTGraphTraits {
+ /// getGraphName - Return the label for the graph as a whole. Printed at the
+ /// top of the graph.
+ ///
+ template<typename GraphType>
+ static std::string getGraphName(GraphType Graph) { return ""; }
+
+ /// getGraphProperties - Return any custom properties that should be included
+ /// in the top level graph structure for dot.
+ ///
+ template<typename GraphType>
+ static std::string getGraphProperties(GraphType Graph) {
+ return "";
+ }
+
+ /// renderGraphFromBottomUp - If this function returns true, the graph is
+ /// emitted bottom-up instead of top-down. This requires graphviz 2.0 to work
+ /// though.
+ static bool renderGraphFromBottomUp() {
+ return false;
+ }
+
+ /// getNodeLabel - Given a node and a pointer to the top level graph, return
+ /// the label to print in the node.
+ template<typename GraphType>
+ static std::string getNodeLabel(const void *Node, GraphType Graph) {
+ return "";
+ }
+
+ /// hasNodeAddressLabel - If this method returns true, the address of the node
+ /// is added to the label of the node.
+ template<typename GraphType>
+ static bool hasNodeAddressLabel(const void *Node, GraphType Graph) {
+ return false;
+ }
+
+ /// If you want to specify custom node attributes, this is the place to do so
+ ///
+ template<typename GraphType>
+ static std::string getNodeAttributes(const void *Node, GraphType Graph) {
+ return "";
+ }
+
+ /// If you want to override the dot attributes printed for a particular edge,
+ /// override this method.
+ template<typename EdgeIter>
+ static std::string getEdgeAttributes(const void *Node, EdgeIter EI) {
+ return "";
+ }
+
+ /// getEdgeSourceLabel - If you want to label the edge source itself,
+ /// implement this method.
+ template<typename EdgeIter>
+ static std::string getEdgeSourceLabel(const void *Node, EdgeIter I) {
+ return "";
+ }
+
+ /// edgeTargetsEdgeSource - This method returns true if this outgoing edge
+ /// should actually target another edge source, not a node. If this method is
+ /// implemented, getEdgeTarget should be implemented.
+ template<typename EdgeIter>
+ static bool edgeTargetsEdgeSource(const void *Node, EdgeIter I) {
+ return false;
+ }
+
+ /// getEdgeTarget - If edgeTargetsEdgeSource returns true, this method is
+ /// called to determine which outgoing edge of Node is the target of this
+ /// edge.
+ template<typename EdgeIter>
+ static EdgeIter getEdgeTarget(const void *Node, EdgeIter I) {
+ return I;
+ }
+
+ /// addCustomGraphFeatures - If a graph is made up of more than just
+ /// straight-forward nodes and edges, this is the place to put all of the
+ /// custom stuff necessary. The GraphWriter object, instantiated with your
+ /// GraphType is passed in as an argument. You may call arbitrary methods on
+ /// it to add things to the output graph.
+ ///
+ template<typename GraphType, typename GraphWriter>
+ static void addCustomGraphFeatures(GraphType Graph, GraphWriter &GW) {}
+};
+
+
+/// DOTGraphTraits - Template class that can be specialized to customize how
+/// graphs are converted to 'dot' graphs. When specializing, you may inherit
+/// from DefaultDOTGraphTraits if you don't need to override everything.
+///
+template <typename Ty>
+struct DOTGraphTraits : public DefaultDOTGraphTraits {};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/DataTypes.h.in b/include/llvm/Support/DataTypes.h.in
new file mode 100644
index 0000000..dcf7bfc
--- /dev/null
+++ b/include/llvm/Support/DataTypes.h.in
@@ -0,0 +1,131 @@
+//===-- include/Support/DataTypes.h - Define fixed size types ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions to figure out the size of _HOST_ data types.
+// This file is important because different host OS's define different macros,
+// which makes portability tough. This file exports the following definitions:
+//
+// [u]int(32|64)_t : typedefs for signed and unsigned 32/64 bit system types
+// [U]INT(8|16|32|64)_(MIN|MAX) : Constants for the min and max values.
+//
+// No library is required when using these functinons.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SUPPORT_DATATYPES_H
+#define SUPPORT_DATATYPES_H
+
+#undef HAVE_SYS_TYPES_H
+#undef HAVE_INTTYPES_H
+#undef HAVE_STDINT_H
+#undef HAVE_UINT64_T
+#undef HAVE_U_INT64_T
+
+#ifndef _MSC_VER
+
+// Note that this header's correct operation depends on __STDC_LIMIT_MACROS
+// being defined. We would define it here, but in order to prevent Bad Things
+// happening when system headers or C++ STL headers include stdint.h before
+// we define it here, we define it on the g++ command line (in Makefile.rules).
+#if !defined(__STDC_LIMIT_MACROS)
+# error "Must #define __STDC_LIMIT_MACROS before #including Support/DataTypes.h"
+#endif
+
+// Note that <inttypes.h> includes <stdint.h>, if this is a C99 system.
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+#include <cmath>
+#else
+#include <math.h>
+#endif
+
+#ifdef _AIX
+#include "llvm/Support/AIXDataTypesFix.h"
+#endif
+
+// Handle incorrect definition of uint64_t as u_int64_t
+#ifndef HAVE_UINT64_T
+#ifdef HAVE_U_INT64_T
+typedef u_int64_t uint64_t;
+#else
+# error "Don't have a definition for uint64_t on this platform"
+#endif
+#endif
+
+#ifdef _OpenBSD_
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif
+
+#else /* _MSC_VER */
+// Visual C++ doesn't provide standard integer headers, but it does provide
+// built-in data types.
+#include <stdlib.h>
+#include <stddef.h>
+#include <sys/types.h>
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+typedef short int16_t;
+typedef unsigned short uint16_t;
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed int ssize_t;
+#define INT8_MAX 127
+#define INT8_MIN -128
+#define UINT8_MAX 255
+#define INT16_MAX 32767
+#define INT16_MIN -32768
+#define UINT16_MAX 65535
+#define INT32_MAX 2147483647
+#define INT32_MIN -2147483648
+#define UINT32_MAX 4294967295U
+#endif /* _MSC_VER */
+
+/* Set defaults for constants which we cannot find. */
+#if !defined(INT64_MAX)
+# define INT64_MAX 9223372036854775807LL
+#endif
+#if !defined(INT64_MIN)
+# define INT64_MIN ((-INT64_MAX)-1)
+#endif
+#if !defined(UINT64_MAX)
+# define UINT64_MAX 0xffffffffffffffffULL
+#endif
+
+#if __GNUC__ > 3
+#define END_WITH_NULL __attribute__((sentinel))
+#else
+#define END_WITH_NULL
+#endif
+
+#ifndef HUGE_VALF
+#define HUGE_VALF (float)HUGE_VAL
+#endif
+
+#endif /* SUPPORT_DATATYPES_H */
diff --git a/include/llvm/Support/Debug.h b/include/llvm/Support/Debug.h
new file mode 100644
index 0000000..cbfaf15
--- /dev/null
+++ b/include/llvm/Support/Debug.h
@@ -0,0 +1,78 @@
+//===- llvm/Support/Debug.h - Easy way to add debug output ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a handy way of adding debugging information to your
+// code, without it being enabled all of the time, and without having to add
+// command line options to enable it.
+//
+// In particular, just wrap your code with the DEBUG() macro, and it will be
+// enabled automatically if you specify '-debug' on the command-line.
+// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
+// that your debug code belongs to class "foo". Then, on the command line, you
+// can specify '-debug-only=foo' to enable JUST the debug information for the
+// foo class.
+//
+// When compiling in release mode, the -debug-* options and all code in DEBUG()
+// statements disappears, so it does not effect the runtime of the code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DEBUG_H
+#define LLVM_SUPPORT_DEBUG_H
+
+#include "llvm/Support/Streams.h"
+
+namespace llvm {
+
+// DebugFlag - This boolean is set to true if the '-debug' command line option
+// is specified. This should probably not be referenced directly, instead, use
+// the DEBUG macro below.
+//
+extern bool DebugFlag;
+
+// isCurrentDebugType - Return true if the specified string is the debug type
+// specified on the command line, or if none was specified on the command line
+// with the -debug-only=X option.
+//
+bool isCurrentDebugType(const char *Type);
+
+// DEBUG macro - This macro should be used by passes to emit debug information.
+// In the '-debug' option is specified on the commandline, and if this is a
+// debug build, then the code specified as the option to the macro will be
+// executed. Otherwise it will not be. Example:
+//
+// DEBUG(cerr << "Bitset contains: " << Bitset << "\n");
+//
+
+#ifndef DEBUG_TYPE
+#define DEBUG_TYPE ""
+#endif
+
+#ifdef NDEBUG
+#define DEBUG(X)
+#else
+#define DEBUG(X) \
+ do { if (DebugFlag && isCurrentDebugType(DEBUG_TYPE)) { X; } } while (0)
+#endif
+
+/// getErrorOutputStream - Returns the error output stream (std::cerr). This
+/// places the std::c* I/O streams into one .cpp file and relieves the whole
+/// program from having to have hundreds of static c'tor/d'tors for them.
+///
+OStream &getErrorOutputStream(const char *DebugType);
+
+#ifdef NDEBUG
+#define DOUT llvm::OStream(0)
+#else
+#define DOUT llvm::getErrorOutputStream(DEBUG_TYPE)
+#endif
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Dwarf.h b/include/llvm/Support/Dwarf.h
new file mode 100644
index 0000000..21f49f6
--- /dev/null
+++ b/include/llvm/Support/Dwarf.h
@@ -0,0 +1,572 @@
+//===-- llvm/Support/Dwarf.h ---Dwarf Constants------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains constants used for implementing Dwarf debug support. For
+// Details on the Dwarf 3 specfication see DWARF Debugging Information Format
+// V.3 reference manual http://dwarf.freestandards.org ,
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DWARF_H
+#define LLVM_SUPPORT_DWARF_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+
+namespace dwarf {
+
+//===----------------------------------------------------------------------===//
+// Dwarf constants as gleaned from the DWARF Debugging Information Format V.3
+// reference manual http://dwarf.freestandards.org .
+//
+
+// Do not mix the following two enumerations sets. DW_TAG_invalid changes the
+// enumeration base type.
+
+enum llvm_dwarf_constants {
+ // llvm mock tags
+ DW_TAG_invalid = ~0U, // Tag for invalid results.
+
+ DW_TAG_anchor = 0, // Tag for descriptor anchors.
+ DW_TAG_auto_variable = 0x100, // Tag for local (auto) variables.
+ DW_TAG_arg_variable = 0x101, // Tag for argument variables.
+ DW_TAG_return_variable = 0x102, // Tag for return variables.
+
+ DW_TAG_vector_type = 0x103, // Tag for vector types.
+
+ DW_TAG_user_base = 0x1000, // Recommended base for user tags.
+
+ DW_CIE_VERSION = 1, // Common frame information version.
+ DW_CIE_ID = 0xffffffff // Common frame information mark.
+};
+
+enum dwarf_constants {
+ DWARF_VERSION = 2,
+
+ // Tags
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_parameter = 0x2f,
+ DW_TAG_template_value_parameter = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ DW_TAG_dwarf_procedure = 0x36,
+ DW_TAG_restrict_type = 0x37,
+ DW_TAG_interface_type = 0x38,
+ DW_TAG_namespace = 0x39,
+ DW_TAG_imported_module = 0x3a,
+ DW_TAG_unspecified_type = 0x3b,
+ DW_TAG_partial_unit = 0x3c,
+ DW_TAG_imported_unit = 0x3d,
+ DW_TAG_condition = 0x3f,
+ DW_TAG_shared_type = 0x40,
+ DW_TAG_lo_user = 0x4080,
+ DW_TAG_hi_user = 0xffff,
+
+ // Children flag
+ DW_CHILDREN_no = 0x00,
+ DW_CHILDREN_yes = 0x01,
+
+ // Attributes
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_bit_stride = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_item = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_allocated = 0x4e,
+ DW_AT_associated = 0x4f,
+ DW_AT_data_location = 0x50,
+ DW_AT_byte_stride = 0x51,
+ DW_AT_entry_pc = 0x52,
+ DW_AT_use_UTF8 = 0x53,
+ DW_AT_extension = 0x54,
+ DW_AT_ranges = 0x55,
+ DW_AT_trampoline = 0x56,
+ DW_AT_call_column = 0x57,
+ DW_AT_call_file = 0x58,
+ DW_AT_call_line = 0x59,
+ DW_AT_description = 0x5a,
+ DW_AT_binary_scale = 0x5b,
+ DW_AT_decimal_scale = 0x5c,
+ DW_AT_small = 0x5d,
+ DW_AT_decimal_sign = 0x5e,
+ DW_AT_digit_count = 0x5f,
+ DW_AT_picture_string = 0x60,
+ DW_AT_mutable = 0x61,
+ DW_AT_threads_scaled = 0x62,
+ DW_AT_explicit = 0x63,
+ DW_AT_object_pointer = 0x64,
+ DW_AT_endianity = 0x65,
+ DW_AT_elemental = 0x66,
+ DW_AT_pure = 0x67,
+ DW_AT_recursive = 0x68,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106,
+ DW_AT_GNU_vector = 0x2107,
+ DW_AT_lo_user = 0x2000,
+ DW_AT_hi_user = 0x3fff,
+
+ // Attribute form encodings
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16,
+
+ // Operation encodings
+ DW_OP_addr = 0x03,
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08,
+ DW_OP_const1s = 0x09,
+ DW_OP_const2u = 0x0a,
+ DW_OP_const2s = 0x0b,
+ DW_OP_const4u = 0x0c,
+ DW_OP_const4s = 0x0d,
+ DW_OP_const8u = 0x0e,
+ DW_OP_const8s = 0x0f,
+ DW_OP_constu = 0x10,
+ DW_OP_consts = 0x11,
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15,
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23,
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_skip = 0x2f,
+ DW_OP_bra = 0x28,
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_lit0 = 0x30,
+ DW_OP_lit1 = 0x31,
+ DW_OP_lit31 = 0x4f,
+ DW_OP_reg0 = 0x50,
+ DW_OP_reg1 = 0x51,
+ DW_OP_reg31 = 0x6f,
+ DW_OP_breg0 = 0x70,
+ DW_OP_breg1 = 0x71,
+ DW_OP_breg31 = 0x8f,
+ DW_OP_regx = 0x90,
+ DW_OP_fbreg = 0x91,
+ DW_OP_bregx = 0x92,
+ DW_OP_piece = 0x93,
+ DW_OP_deref_size = 0x94,
+ DW_OP_xderef_size = 0x95,
+ DW_OP_nop = 0x96,
+ DW_OP_push_object_address = 0x97,
+ DW_OP_call2 = 0x98,
+ DW_OP_call4 = 0x99,
+ DW_OP_call_ref = 0x9a,
+ DW_OP_form_tls_address = 0x9b,
+ DW_OP_call_frame_cfa = 0x9c,
+ DW_OP_lo_user = 0xe0,
+ DW_OP_hi_user = 0xff,
+
+ // Encoding attribute values
+ DW_ATE_address = 0x01,
+ DW_ATE_boolean = 0x02,
+ DW_ATE_complex_float = 0x03,
+ DW_ATE_float = 0x04,
+ DW_ATE_signed = 0x05,
+ DW_ATE_signed_char = 0x06,
+ DW_ATE_unsigned = 0x07,
+ DW_ATE_unsigned_char = 0x08,
+ DW_ATE_imaginary_float = 0x09,
+ DW_ATE_packed_decimal = 0x0a,
+ DW_ATE_numeric_string = 0x0b,
+ DW_ATE_edited = 0x0c,
+ DW_ATE_signed_fixed = 0x0d,
+ DW_ATE_unsigned_fixed = 0x0e,
+ DW_ATE_decimal_float = 0x0f,
+ DW_ATE_lo_user = 0x80,
+ DW_ATE_hi_user = 0xff,
+
+ // Decimal sign attribute values
+ DW_DS_unsigned = 0x01,
+ DW_DS_leading_overpunch = 0x02,
+ DW_DS_trailing_overpunch = 0x03,
+ DW_DS_leading_separate = 0x04,
+ DW_DS_trailing_separate = 0x05,
+
+ // Endianity attribute values
+ DW_END_default = 0x00,
+ DW_END_big = 0x01,
+ DW_END_little = 0x02,
+ DW_END_lo_user = 0x40,
+ DW_END_hi_user = 0xff,
+
+ // Accessibility codes
+ DW_ACCESS_public = 0x01,
+ DW_ACCESS_protected = 0x02,
+ DW_ACCESS_private = 0x03,
+
+ // Visibility codes
+ DW_VIS_local = 0x01,
+ DW_VIS_exported = 0x02,
+ DW_VIS_qualified = 0x03,
+
+ // Virtuality codes
+ DW_VIRTUALITY_none = 0x00,
+ DW_VIRTUALITY_virtual = 0x01,
+ DW_VIRTUALITY_pure_virtual = 0x02,
+
+ // Language names
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_C99 = 0x000c,
+ DW_LANG_Ada95 = 0x000d,
+ DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_PLI = 0x000f,
+ DW_LANG_ObjC = 0x0010,
+ DW_LANG_ObjC_plus_plus = 0x0011,
+ DW_LANG_UPC = 0x0012,
+ DW_LANG_D = 0x0013,
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_hi_user = 0xffff,
+
+ // Identifier case codes
+ DW_ID_case_sensitive = 0x00,
+ DW_ID_up_case = 0x01,
+ DW_ID_down_case = 0x02,
+ DW_ID_case_insensitive = 0x03,
+
+ // Calling convention codes
+ DW_CC_normal = 0x01,
+ DW_CC_program = 0x02,
+ DW_CC_nocall = 0x03,
+ DW_CC_lo_user = 0x40,
+ DW_CC_hi_user = 0xff,
+
+ // Inline codes
+ DW_INL_not_inlined = 0x00,
+ DW_INL_inlined = 0x01,
+ DW_INL_declared_not_inlined = 0x02,
+ DW_INL_declared_inlined = 0x03,
+
+ // Array ordering
+ DW_ORD_row_major = 0x00,
+ DW_ORD_col_major = 0x01,
+
+ // Discriminant descriptor values
+ DW_DSC_label = 0x00,
+ DW_DSC_range = 0x01,
+
+ // Line Number Standard Opcode Encodings
+ DW_LNS_copy = 0x01,
+ DW_LNS_advance_pc = 0x02,
+ DW_LNS_advance_line = 0x03,
+ DW_LNS_set_file = 0x04,
+ DW_LNS_set_column = 0x05,
+ DW_LNS_negate_stmt = 0x06,
+ DW_LNS_set_basic_block = 0x07,
+ DW_LNS_const_add_pc = 0x08,
+ DW_LNS_fixed_advance_pc = 0x09,
+ DW_LNS_set_prologue_end = 0x0a,
+ DW_LNS_set_epilogue_begin = 0x0b,
+ DW_LNS_set_isa = 0x0c,
+
+ // Line Number Extended Opcode Encodings
+ DW_LNE_end_sequence = 0x01,
+ DW_LNE_set_address = 0x02,
+ DW_LNE_define_file = 0x03,
+ DW_LNE_lo_user = 0x80,
+ DW_LNE_hi_user = 0xff,
+
+ // Macinfo Type Encodings
+ DW_MACINFO_define = 0x01,
+ DW_MACINFO_undef = 0x02,
+ DW_MACINFO_start_file = 0x03,
+ DW_MACINFO_end_file = 0x04,
+ DW_MACINFO_vendor_ext = 0xff,
+
+ // Call frame instruction encodings
+ DW_CFA_extended = 0x00,
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_def_cfa_expression = 0x0f,
+ DW_CFA_expression = 0x10,
+ DW_CFA_offset_extended_sf = 0x11,
+ DW_CFA_def_cfa_sf = 0x12,
+ DW_CFA_def_cfa_offset_sf = 0x13,
+ DW_CFA_val_offset = 0x14,
+ DW_CFA_val_offset_sf = 0x15,
+ DW_CFA_val_expression = 0x16,
+ DW_CFA_lo_user = 0x1c,
+ DW_CFA_hi_user = 0x3f,
+
+ DW_EH_PE_absptr = 0x00,
+ DW_EH_PE_omit = 0xff,
+ DW_EH_PE_uleb128 = 0x01,
+ DW_EH_PE_udata2 = 0x02,
+ DW_EH_PE_udata4 = 0x03,
+ DW_EH_PE_udata8 = 0x04,
+ DW_EH_PE_sleb128 = 0x09,
+ DW_EH_PE_sdata2 = 0x0A,
+ DW_EH_PE_sdata4 = 0x0B,
+ DW_EH_PE_sdata8 = 0x0C,
+ DW_EH_PE_signed = 0x08,
+ DW_EH_PE_pcrel = 0x10,
+ DW_EH_PE_textrel = 0x20,
+ DW_EH_PE_datarel = 0x30,
+ DW_EH_PE_funcrel = 0x40,
+ DW_EH_PE_aligned = 0x50,
+ DW_EH_PE_indirect = 0x80
+};
+
+/// TagString - Return the string for the specified tag.
+///
+const char *TagString(unsigned Tag);
+
+/// ChildrenString - Return the string for the specified children flag.
+///
+const char *ChildrenString(unsigned Children);
+
+/// AttributeString - Return the string for the specified attribute.
+///
+const char *AttributeString(unsigned Attribute);
+
+/// FormEncodingString - Return the string for the specified form encoding.
+///
+const char *FormEncodingString(unsigned Encoding);
+
+/// OperationEncodingString - Return the string for the specified operation
+/// encoding.
+const char *OperationEncodingString(unsigned Encoding);
+
+/// AttributeEncodingString - Return the string for the specified attribute
+/// encoding.
+const char *AttributeEncodingString(unsigned Encoding);
+
+/// DecimalSignString - Return the string for the specified decimal sign
+/// attribute.
+const char *DecimalSignString(unsigned Sign);
+
+/// EndianityString - Return the string for the specified endianity.
+///
+const char *EndianityString(unsigned Endian);
+
+/// AccessibilityString - Return the string for the specified accessibility.
+///
+const char *AccessibilityString(unsigned Access);
+
+/// VisibilityString - Return the string for the specified visibility.
+///
+const char *VisibilityString(unsigned Visibility);
+
+/// VirtualityString - Return the string for the specified virtuality.
+///
+const char *VirtualityString(unsigned Virtuality);
+
+/// LanguageString - Return the string for the specified language.
+///
+const char *LanguageString(unsigned Language);
+
+/// CaseString - Return the string for the specified identifier case.
+///
+const char *CaseString(unsigned Case);
+
+/// ConventionString - Return the string for the specified calling convention.
+///
+const char *ConventionString(unsigned Convention);
+
+/// InlineCodeString - Return the string for the specified inline code.
+///
+const char *InlineCodeString(unsigned Code);
+
+/// ArrayOrderString - Return the string for the specified array order.
+///
+const char *ArrayOrderString(unsigned Order);
+
+/// DiscriminantString - Return the string for the specified discriminant
+/// descriptor.
+const char *DiscriminantString(unsigned Discriminant);
+
+/// LNStandardString - Return the string for the specified line number standard.
+///
+const char *LNStandardString(unsigned Standard);
+
+/// LNExtendedString - Return the string for the specified line number extended
+/// opcode encodings.
+const char *LNExtendedString(unsigned Encoding);
+
+/// MacinfoString - Return the string for the specified macinfo type encodings.
+///
+const char *MacinfoString(unsigned Encoding);
+
+/// CallFrameString - Return the string for the specified call frame instruction
+/// encodings.
+const char *CallFrameString(unsigned Encoding);
+
+} // End of namespace dwarf
+
+} // End of namespace llvm
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SupportDwarf)
+
+#endif
diff --git a/include/llvm/Support/DynamicLinker.h b/include/llvm/Support/DynamicLinker.h
new file mode 100644
index 0000000..e996b0f
--- /dev/null
+++ b/include/llvm/Support/DynamicLinker.h
@@ -0,0 +1,40 @@
+//===-- llvm/Support/DynamicLinker.h - Portable Dynamic Linker --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Lightweight interface to dynamic library linking and loading, and dynamic
+// symbol lookup functionality, in whatever form the operating system
+// provides it.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_DYNAMICLINKER_H
+#define LLVM_SUPPORT_DYNAMICLINKER_H
+
+#include <string>
+
+namespace llvm {
+
+/// LinkDynamicObject - Load the named file as a dynamic library
+/// and link it with the currently running process. Returns false
+/// on success, true if there is an error (and sets ErrorMessage
+/// if it is not NULL). Analogous to dlopen().
+///
+bool LinkDynamicObject (const char *filename, std::string *ErrorMessage);
+
+/// GetAddressOfSymbol - Returns the address of the named symbol in
+/// the currently running process, as reported by the dynamic linker,
+/// or NULL if the symbol does not exist or some other error has
+/// occurred.
+///
+void *GetAddressOfSymbol (const char *symbolName);
+void *GetAddressOfSymbol (const std::string &symbolName);
+
+} // End llvm namespace
+
+#endif // SUPPORT_DYNAMICLINKER_H
diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h
new file mode 100644
index 0000000..cd811f2
--- /dev/null
+++ b/include/llvm/Support/ELF.h
@@ -0,0 +1,300 @@
+//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header contains common, non-processor-specific data structures and
+// constants for the ELF file format.
+//
+// The details of the ELF32 bits in this file are largely based on
+// the Tool Interface Standard (TIS) Executable and Linking Format
+// (ELF) Specification Version 1.2, May 1995. The ELF64 stuff is not
+// standardized, as far as I can tell. It was largely based on information
+// I found in OpenBSD header files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_ELF_H
+#define LLVM_SUPPORT_ELF_H
+
+#include "llvm/Support/DataTypes.h"
+#include <cstring>
+#include <cstdlib>
+
+namespace llvm {
+
+namespace ELF {
+
+typedef uint32_t Elf32_Addr; // Program address
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off; // File offset
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+typedef uint64_t Elf64_Addr;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Shalf;
+typedef int32_t Elf64_Sword;
+typedef uint32_t Elf64_Word;
+typedef int64_t Elf64_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef uint32_t Elf64_Half;
+typedef uint16_t Elf64_Quarter;
+
+// Object file magic string.
+static const char ElfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
+
+struct Elf32_Ehdr {
+ unsigned char e_ident[16]; // ELF Identification bytes
+ Elf32_Half e_type; // Type of file (see ET_* below)
+ Elf32_Half e_machine; // Required architecture for this file (see EM_*)
+ Elf32_Word e_version; // Must be equal to 1
+ Elf32_Addr e_entry; // Address to jump to in order to start program
+ Elf32_Off e_phoff; // Program header table's file offset, in bytes
+ Elf32_Off e_shoff; // Section header table's file offset, in bytes
+ Elf32_Word e_flags; // Processor-specific flags
+ Elf32_Half e_ehsize; // Size of ELF header, in bytes
+ Elf32_Half e_phentsize; // Size of an entry in the program header table
+ Elf32_Half e_phnum; // Number of entries in the program header table
+ Elf32_Half e_shentsize; // Size of an entry in the section header table
+ Elf32_Half e_shnum; // Number of entries in the section header table
+ Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
+ bool checkMagic () const {
+ return (memcmp (e_ident, ElfMagic, strlen (ElfMagic))) == 0;
+ }
+ unsigned char getFileClass () const { return e_ident[4]; }
+ unsigned char getDataEncoding () { return e_ident[5]; }
+};
+
+// 64-bit ELF header. Fields are the same as for ELF32, but with different
+// types (see above).
+struct Elf64_Ehdr {
+ unsigned char e_ident[16];
+ Elf64_Quarter e_type;
+ Elf64_Quarter e_machine;
+ Elf64_Half e_version;
+ Elf64_Addr e_entry;
+ Elf64_Off e_phoff;
+ Elf64_Off e_shoff;
+ Elf64_Half e_flags;
+ Elf64_Quarter e_ehsize;
+ Elf64_Quarter e_phentsize;
+ Elf64_Quarter e_phnum;
+ Elf64_Quarter e_shentsize;
+ Elf64_Quarter e_shnum;
+ Elf64_Quarter e_shstrndx;
+};
+
+// File types
+enum {
+ ET_NONE = 0, // No file type
+ ET_REL = 1, // Relocatable file
+ ET_EXEC = 2, // Executable file
+ ET_DYN = 3, // Shared object file
+ ET_CORE = 4, // Core file
+ ET_LOPROC = 0xff00, // Beginning of processor-specific codes
+ ET_HIPROC = 0xffff // Processor-specific
+};
+
+// Machine architectures
+enum {
+ EM_NONE = 0, // No machine
+ EM_M32 = 1, // AT&T WE 32100
+ EM_SPARC = 2, // SPARC
+ EM_386 = 3, // Intel 386
+ EM_68K = 4, // Motorola 68000
+ EM_88K = 5, // Motorola 88000
+ EM_486 = 6, // Intel 486 (deprecated)
+ EM_860 = 7, // Intel 80860
+ EM_MIPS = 8, // MIPS R3000
+ EM_PPC = 20, // PowerPC
+ EM_ARM = 40, // ARM
+ EM_ALPHA = 41, // DEC Alpha
+ EM_SPARCV9 = 43 // SPARC V9
+};
+
+// Object file classes.
+enum {
+ ELFCLASS32 = 1, // 32-bit object file
+ ELFCLASS64 = 2 // 64-bit object file
+};
+
+// Object file byte orderings.
+enum {
+ ELFDATA2LSB = 1, // Little-endian object file
+ ELFDATA2MSB = 2 // Big-endian object file
+};
+
+// Section header.
+struct Elf32_Shdr {
+ Elf32_Word sh_name; // Section name (index into string table)
+ Elf32_Word sh_type; // Section type (SHT_*)
+ Elf32_Word sh_flags; // Section flags (SHF_*)
+ Elf32_Addr sh_addr; // Address where section is to be loaded
+ Elf32_Off sh_offset; // File offset of section data, in bytes
+ Elf32_Word sh_size; // Size of section, in bytes
+ Elf32_Word sh_link; // Section type-specific header table index link
+ Elf32_Word sh_info; // Section type-specific extra information
+ Elf32_Word sh_addralign; // Section address alignment
+ Elf32_Word sh_entsize; // Size of records contained within the section
+};
+
+// Section header for ELF64 - same fields as ELF32, different types.
+struct Elf64_Shdr {
+ Elf64_Half sh_name;
+ Elf64_Half sh_type;
+ Elf64_Xword sh_flags;
+ Elf64_Addr sh_addr;
+ Elf64_Off sh_offset;
+ Elf64_Xword sh_size;
+ Elf64_Half sh_link;
+ Elf64_Half sh_info;
+ Elf64_Xword sh_addralign;
+ Elf64_Xword sh_entsize;
+};
+
+// Special section indices.
+enum {
+ SHN_UNDEF = 0, // Undefined, missing, irrelevant, or meaningless
+ SHN_LORESERVE = 0xff00, // Lowest reserved index
+ SHN_LOPROC = 0xff00, // Lowest processor-specific index
+ SHN_HIPROC = 0xff1f, // Highest processor-specific index
+ SHN_ABS = 0xfff1, // Symbol has absolute value; does not need relocation
+ SHN_COMMON = 0xfff2, // FORTRAN COMMON or C external global variables
+ SHN_HIRESERVE = 0xffff // Highest reserved index
+};
+
+// Section types.
+enum {
+ SHT_NULL = 0, // No associated section (inactive entry).
+ SHT_PROGBITS = 1, // Program-defined contents.
+ SHT_SYMTAB = 2, // Symbol table.
+ SHT_STRTAB = 3, // String table.
+ SHT_RELA = 4, // Relocation entries; explicit addends.
+ SHT_HASH = 5, // Symbol hash table.
+ SHT_DYNAMIC = 6, // Information for dynamic linking.
+ SHT_NOTE = 7, // Information about the file.
+ SHT_NOBITS = 8, // Data occupies no space in the file.
+ SHT_REL = 9, // Relocation entries; no explicit addends.
+ SHT_SHLIB = 10, // Reserved.
+ SHT_DYNSYM = 11, // Symbol table.
+ SHT_LOPROC = 0x70000000, // Lowest processor architecture-specific type.
+ SHT_HIPROC = 0x7fffffff, // Highest processor architecture-specific type.
+ SHT_LOUSER = 0x80000000, // Lowest type reserved for applications.
+ SHT_HIUSER = 0xffffffff // Highest type reserved for applications.
+};
+
+// Section flags.
+enum {
+ SHF_WRITE = 0x1, // Section data should be writable during execution.
+ SHF_ALLOC = 0x2, // Section occupies memory during program execution.
+ SHF_EXECINSTR = 0x4, // Section contains executable machine instructions.
+ SHF_MASKPROC = 0xf0000000 // Bits indicating processor-specific flags.
+};
+
+// Symbol table entries.
+struct Elf32_Sym {
+ Elf32_Word st_name; // Symbol name (index into string table)
+ Elf32_Addr st_value; // Value or address associated with the symbol
+ Elf32_Word st_size; // Size of the symbol
+ unsigned char st_info; // Symbol's type and binding attributes
+ unsigned char st_other; // Must be zero; reserved
+ Elf32_Half st_shndx; // Which section (header table index) it's defined in
+
+ // These accessors and mutators correspond to the ELF32_ST_BIND,
+ // ELF32_ST_TYPE, and ELF32_ST_INFO macros defined in the ELF specification:
+ unsigned char getBinding () const { return st_info >> 4; }
+ unsigned char getType () const { return st_info & 0x0f; }
+ void setBinding (unsigned char b) { setBindingAndType (b, getType ()); }
+ void setType (unsigned char t) { setBindingAndType (getBinding (), t); }
+ void setBindingAndType (unsigned char b, unsigned char t) {
+ st_info = (b << 4) + (t & 0x0f);
+ }
+};
+
+// Symbol bindings.
+enum {
+ STB_LOCAL = 0, // Local symbol, not visible outside obj file containing def
+ STB_GLOBAL = 1, // Global symbol, visible to all object files being combined
+ STB_WEAK = 2, // Weak symbol, like global but lower-precedence
+ STB_LOPROC = 13, // Lowest processor-specific binding type
+ STB_HIPROC = 15 // Highest processor-specific binding type
+};
+
+// Symbol types.
+enum {
+ STT_NOTYPE = 0, // Symbol's type is not specified
+ STT_OBJECT = 1, // Symbol is a data object (variable, array, etc.)
+ STT_FUNC = 2, // Symbol is executable code (function, etc.)
+ STT_SECTION = 3, // Symbol refers to a section
+ STT_FILE = 4, // Local, absolute symbol that refers to a file
+ STT_LOPROC = 13, // Lowest processor-specific symbol type
+ STT_HIPROC = 15 // Highest processor-specific symbol type
+};
+
+// Relocation entry, without explicit addend.
+struct Elf32_Rel {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Relocation entry with explicit addend.
+struct Elf32_Rela {
+ Elf32_Addr r_offset; // Location (file byte offset, or program virtual addr)
+ Elf32_Word r_info; // Symbol table index and type of relocation to apply
+ Elf32_Sword r_addend; // Compute value for relocatable field by adding this
+
+ // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE,
+ // and ELF32_R_INFO macros defined in the ELF specification:
+ Elf32_Word getSymbol () const { return (r_info >> 8); }
+ unsigned char getType () const { return (unsigned char) (r_info & 0x0ff); }
+ void setSymbol (Elf32_Word s) { setSymbolAndType (s, getType ()); }
+ void setType (unsigned char t) { setSymbolAndType (getSymbol(), t); }
+ void setSymbolAndType (Elf32_Word s, unsigned char t) {
+ r_info = (s << 8) + t;
+ };
+};
+
+// Program header.
+struct Elf32_Phdr {
+ Elf32_Word p_type; // Type of segment
+ Elf32_Off p_offset; // File offset where segment is located, in bytes
+ Elf32_Addr p_vaddr; // Virtual address of beginning of segment
+ Elf32_Addr p_paddr; // Physical address of beginning of segment (OS-specific)
+ Elf32_Word p_filesz; // Num. of bytes in file image of segment (may be zero)
+ Elf32_Word p_memsz; // Num. of bytes in mem image of segment (may be zero)
+ Elf32_Word p_flags; // Segment flags
+ Elf32_Word p_align; // Segment alignment constraint
+};
+
+enum {
+ PT_NULL = 0, // Unused segment.
+ PT_LOAD = 1, // Loadable segment.
+ PT_DYNAMIC = 2, // Dynamic linking information.
+ PT_INTERP = 3, // Interpreter pathname.
+ PT_NOTE = 4, // Auxiliary information.
+ PT_SHLIB = 5, // Reserved.
+ PT_PHDR = 6, // The program header table itself.
+ PT_LOPROC = 0x70000000, // Lowest processor-specific program hdr entry type.
+ PT_HIPROC = 0x7fffffff // Highest processor-specific program hdr entry type.
+};
+
+} // end namespace ELF
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/FileUtilities.h b/include/llvm/Support/FileUtilities.h
new file mode 100644
index 0000000..9cebe23
--- /dev/null
+++ b/include/llvm/Support/FileUtilities.h
@@ -0,0 +1,59 @@
+//===- llvm/Support/FileUtilities.h - File System Utilities -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a family of utility functions which are useful for doing
+// various things with files.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_FILEUTILITIES_H
+#define LLVM_SUPPORT_FILEUTILITIES_H
+
+#include "llvm/System/Path.h"
+
+namespace llvm {
+
+ /// DiffFilesWithTolerance - Compare the two files specified, returning 0 if
+ /// the files match, 1 if they are different, and 2 if there is a file error.
+ /// This function allows you to specify an absolete and relative FP error that
+ /// is allowed to exist. If you specify a string to fill in for the error
+ /// option, it will set the string to an error message if an error occurs, or
+ /// if the files are different.
+ ///
+ int DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
+ const sys::PathWithStatus &FileB,
+ double AbsTol, double RelTol,
+ std::string *Error = 0);
+
+
+ /// FileRemover - This class is a simple object meant to be stack allocated.
+ /// If an exception is thrown from a region, the object removes the filename
+ /// specified (if deleteIt is true).
+ ///
+ class FileRemover {
+ sys::Path Filename;
+ bool DeleteIt;
+ public:
+ FileRemover(const sys::Path &filename, bool deleteIt = true)
+ : Filename(filename), DeleteIt(deleteIt) {}
+
+ ~FileRemover() {
+ if (DeleteIt) {
+ // Ignore problems deleting the file.
+ Filename.eraseFromDisk();
+ }
+ }
+
+ /// releaseFile - Take ownership of the file away from the FileRemover so it
+ /// will not be removed when the object is destroyed.
+ void releaseFile() { DeleteIt = false; }
+ };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/GetElementPtrTypeIterator.h b/include/llvm/Support/GetElementPtrTypeIterator.h
new file mode 100644
index 0000000..846332e
--- /dev/null
+++ b/include/llvm/Support/GetElementPtrTypeIterator.h
@@ -0,0 +1,112 @@
+//===- llvm/Support/GetElementPtrTypeIterator.h -----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an iterator for walking through the types indexed by
+// getelementptr instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+#define LLVM_SUPPORT_GETELEMENTPTRTYPE_H
+
+#include "llvm/User.h"
+#include "llvm/DerivedTypes.h"
+
+namespace llvm {
+ template<typename ItTy = User::const_op_iterator>
+ class generic_gep_type_iterator
+ : public forward_iterator<const Type *, ptrdiff_t> {
+ typedef forward_iterator<const Type*, ptrdiff_t> super;
+
+ ItTy OpIt;
+ const Type *CurTy;
+ generic_gep_type_iterator() {}
+ public:
+
+ static generic_gep_type_iterator begin(const Type *Ty, ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = Ty;
+ I.OpIt = It;
+ return I;
+ }
+ static generic_gep_type_iterator end(ItTy It) {
+ generic_gep_type_iterator I;
+ I.CurTy = 0;
+ I.OpIt = It;
+ return I;
+ }
+
+ bool operator==(const generic_gep_type_iterator& x) const {
+ return OpIt == x.OpIt;
+ }
+ bool operator!=(const generic_gep_type_iterator& x) const {
+ return !operator==(x);
+ }
+
+ const Type *operator*() const {
+ return CurTy;
+ }
+
+ const Type *getIndexedType() const {
+ const CompositeType *CT = cast<CompositeType>(CurTy);
+ return CT->getTypeAtIndex(getOperand());
+ }
+
+ // This is a non-standard operator->. It allows you to call methods on the
+ // current type directly.
+ const Type *operator->() const { return operator*(); }
+
+ Value *getOperand() const { return *OpIt; }
+
+ generic_gep_type_iterator& operator++() { // Preincrement
+ if (const CompositeType *CT = dyn_cast<CompositeType>(CurTy)) {
+ CurTy = CT->getTypeAtIndex(getOperand());
+ } else {
+ CurTy = 0;
+ }
+ ++OpIt;
+ return *this;
+ }
+
+ generic_gep_type_iterator operator++(int) { // Postincrement
+ generic_gep_type_iterator tmp = *this; ++*this; return tmp;
+ }
+ };
+
+ typedef generic_gep_type_iterator<> gep_type_iterator;
+
+ inline gep_type_iterator gep_type_begin(const User *GEP) {
+ return gep_type_iterator::begin(GEP->getOperand(0)->getType(),
+ GEP->op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User *GEP) {
+ return gep_type_iterator::end(GEP->op_end());
+ }
+ inline gep_type_iterator gep_type_begin(const User &GEP) {
+ return gep_type_iterator::begin(GEP.getOperand(0)->getType(),
+ GEP.op_begin()+1);
+ }
+ inline gep_type_iterator gep_type_end(const User &GEP) {
+ return gep_type_iterator::end(GEP.op_end());
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_begin(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::begin(Op0, I);
+ }
+
+ template<typename ItTy>
+ inline generic_gep_type_iterator<ItTy>
+ gep_type_end(const Type *Op0, ItTy I, ItTy E) {
+ return generic_gep_type_iterator<ItTy>::end(E);
+ }
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/GraphWriter.h b/include/llvm/Support/GraphWriter.h
new file mode 100644
index 0000000..b9566b8
--- /dev/null
+++ b/include/llvm/Support/GraphWriter.h
@@ -0,0 +1,308 @@
+//===-- llvm/Support/GraphWriter.h - Write graph to a .dot file -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple interface that can be used to print out generic
+// LLVM graphs to ".dot" files. "dot" is a tool that is part of the AT&T
+// graphviz package (http://www.research.att.com/sw/tools/graphviz/) which can
+// be used to turn the files output by this interface into a variety of
+// different graphics formats.
+//
+// Graphs do not need to implement any interface past what is already required
+// by the GraphTraits template, but they can choose to implement specializations
+// of the DOTGraphTraits template if they want to customize the graphs output in
+// any way.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_GRAPHWRITER_H
+#define LLVM_SUPPORT_GRAPHWRITER_H
+
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/System/Path.h"
+#include <fstream>
+#include <vector>
+
+namespace llvm {
+
+namespace DOT { // Private functions...
+ inline std::string EscapeString(const std::string &Label) {
+ std::string Str(Label);
+ for (unsigned i = 0; i != Str.length(); ++i)
+ switch (Str[i]) {
+ case '\n':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i;
+ Str[i] = 'n';
+ break;
+ case '\t':
+ Str.insert(Str.begin()+i, ' '); // Convert to two spaces
+ ++i;
+ Str[i] = ' ';
+ break;
+ case '\\':
+ if (i+1 != Str.length() && Str[i+1] == 'l')
+ break; // don't disturb \l
+ case '{': case '}':
+ case '<': case '>':
+ case '"':
+ Str.insert(Str.begin()+i, '\\'); // Escape character...
+ ++i; // don't infinite loop
+ break;
+ }
+ return Str;
+ }
+}
+
+void DisplayGraph(const sys::Path& Filename);
+
+template<typename GraphType>
+class GraphWriter {
+ std::ostream &O;
+ const GraphType &G;
+
+ typedef DOTGraphTraits<GraphType> DOTTraits;
+ typedef GraphTraits<GraphType> GTraits;
+ typedef typename GTraits::NodeType NodeType;
+ typedef typename GTraits::nodes_iterator node_iterator;
+ typedef typename GTraits::ChildIteratorType child_iterator;
+public:
+ GraphWriter(std::ostream &o, const GraphType &g) : O(o), G(g) {}
+
+ void writeHeader(const std::string &Name) {
+ if (Name.empty())
+ O << "digraph foo {\n"; // Graph name doesn't matter
+ else
+ O << "digraph " << Name << " {\n";
+
+ if (DOTTraits::renderGraphFromBottomUp())
+ O << "\trankdir=\"BT\";\n";
+
+ std::string GraphName = DOTTraits::getGraphName(G);
+ if (!GraphName.empty())
+ O << "\tlabel=\"" << DOT::EscapeString(GraphName) << "\";\n";
+ O << DOTTraits::getGraphProperties(G);
+ O << "\n";
+ }
+
+ void writeFooter() {
+ // Finish off the graph
+ O << "}\n";
+ }
+
+ void writeNodes() {
+ // Loop over the graph, printing it out...
+ for (node_iterator I = GTraits::nodes_begin(G), E = GTraits::nodes_end(G);
+ I != E; ++I)
+ writeNode(&*I);
+ }
+
+ void writeNode(NodeType *const *Node) {
+ writeNode(*Node);
+ }
+
+ void writeNode(NodeType *Node) {
+ std::string NodeAttributes = DOTTraits::getNodeAttributes(Node, G);
+
+ O << "\tNode" << reinterpret_cast<const void*>(Node) << " [shape=record,";
+ if (!NodeAttributes.empty()) O << NodeAttributes << ",";
+ O << "label=\"{";
+
+ if (!DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ // Print out the fields of the current node...
+ child_iterator EI = GTraits::child_begin(Node);
+ child_iterator EE = GTraits::child_end(Node);
+ if (EI != EE) {
+ if (!DOTTraits::renderGraphFromBottomUp()) O << "|";
+ O << "{";
+
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i) {
+ if (i) O << "|";
+ O << "<g" << i << ">" << DOTTraits::getEdgeSourceLabel(Node, EI);
+ }
+
+ if (EI != EE)
+ O << "|<g64>truncated...";
+ O << "}";
+ if (DOTTraits::renderGraphFromBottomUp()) O << "|";
+ }
+
+ if (DOTTraits::renderGraphFromBottomUp()) {
+ O << DOT::EscapeString(DOTTraits::getNodeLabel(Node, G));
+
+ // If we should include the address of the node in the label, do so now.
+ if (DOTTraits::hasNodeAddressLabel(Node, G))
+ O << "|" << (void*)Node;
+ }
+
+ O << "}\"];\n"; // Finish printing the "node" line
+
+ // Output all of the edges now
+ EI = GTraits::child_begin(Node);
+ for (unsigned i = 0; EI != EE && i != 64; ++EI, ++i)
+ writeEdge(Node, i, EI);
+ for (; EI != EE; ++EI)
+ writeEdge(Node, 64, EI);
+ }
+
+ void writeEdge(NodeType *Node, unsigned edgeidx, child_iterator EI) {
+ if (NodeType *TargetNode = *EI) {
+ int DestPort = -1;
+ if (DOTTraits::edgeTargetsEdgeSource(Node, EI)) {
+ child_iterator TargetIt = DOTTraits::getEdgeTarget(Node, EI);
+
+ // Figure out which edge this targets...
+ unsigned Offset = std::distance(GTraits::child_begin(TargetNode),
+ TargetIt);
+ DestPort = static_cast<int>(Offset);
+ }
+
+ emitEdge(reinterpret_cast<const void*>(Node), edgeidx,
+ reinterpret_cast<const void*>(TargetNode), DestPort,
+ DOTTraits::getEdgeAttributes(Node, EI));
+ }
+ }
+
+ /// emitSimpleNode - Outputs a simple (non-record) node
+ void emitSimpleNode(const void *ID, const std::string &Attr,
+ const std::string &Label, unsigned NumEdgeSources = 0,
+ const std::vector<std::string> *EdgeSourceLabels = 0) {
+ O << "\tNode" << ID << "[ ";
+ if (!Attr.empty())
+ O << Attr << ",";
+ O << " label =\"";
+ if (NumEdgeSources) O << "{";
+ O << DOT::EscapeString(Label);
+ if (NumEdgeSources) {
+ O << "|{";
+
+ for (unsigned i = 0; i != NumEdgeSources; ++i) {
+ if (i) O << "|";
+ O << "<g" << i << ">";
+ if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i];
+ }
+ O << "}}";
+ }
+ O << "\"];\n";
+ }
+
+ /// emitEdge - Output an edge from a simple node into the graph...
+ void emitEdge(const void *SrcNodeID, int SrcNodePort,
+ const void *DestNodeID, int DestNodePort,
+ const std::string &Attrs) {
+ if (SrcNodePort > 64) return; // Eminating from truncated part?
+ if (DestNodePort > 64) DestNodePort = 64; // Targetting the truncated part?
+
+ O << "\tNode" << SrcNodeID;
+ if (SrcNodePort >= 0)
+ O << ":g" << SrcNodePort;
+ O << " -> Node" << reinterpret_cast<const void*>(DestNodeID);
+ if (DestNodePort >= 0)
+ O << ":g" << DestNodePort;
+
+ if (!Attrs.empty())
+ O << "[" << Attrs << "]";
+ O << ";\n";
+ }
+};
+
+template<typename GraphType>
+std::ostream &WriteGraph(std::ostream &O, const GraphType &G,
+ const std::string &Name = "") {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G);
+
+ // Output the header for the graph...
+ W.writeHeader(Name);
+
+ // Emit all of the nodes in the graph...
+ W.writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, W);
+
+ // Output the end of the graph
+ W.writeFooter();
+ return O;
+}
+
+template<typename GraphType>
+sys::Path WriteGraph(const GraphType &G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ std::string ErrMsg;
+ sys::Path Filename = sys::Path::GetTemporaryDirectory(&ErrMsg);
+ if (Filename.isEmpty()) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return Filename;
+ }
+ Filename.appendComponent(Name + ".dot");
+ if (Filename.makeUnique(true,&ErrMsg)) {
+ cerr << "Error: " << ErrMsg << "\n";
+ return sys::Path();
+ }
+
+ cerr << "Writing '" << Filename << "'... ";
+
+ std::ofstream O(Filename.c_str());
+
+ if (O.good()) {
+ // Start the graph emission process...
+ GraphWriter<GraphType> W(O, G);
+
+ // Output the header for the graph...
+ W.writeHeader(Title);
+
+ // Emit all of the nodes in the graph...
+ W.writeNodes();
+
+ // Output any customizations on the graph
+ DOTGraphTraits<GraphType>::addCustomGraphFeatures(G, W);
+
+ // Output the end of the graph
+ W.writeFooter();
+ cerr << " done. \n";
+
+ O.close();
+
+ } else {
+ cerr << "error opening file for writing!\n";
+ Filename.clear();
+ }
+
+ return Filename;
+}
+
+/// ViewGraph - Emit a dot graph, run 'dot', run gv on the postscript file,
+/// then cleanup. For use from the debugger.
+///
+template<typename GraphType>
+void ViewGraph(const GraphType& G,
+ const std::string& Name,
+ const std::string& Title = "") {
+ sys::Path Filename = WriteGraph(G, Name, Title);
+
+ if (Filename.isEmpty()) {
+ return;
+ }
+
+ DisplayGraph(Filename);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/InstIterator.h b/include/llvm/Support/InstIterator.h
new file mode 100644
index 0000000..6f3a45e
--- /dev/null
+++ b/include/llvm/Support/InstIterator.h
@@ -0,0 +1,147 @@
+//===- llvm/Support/InstIterator.h - Classes for inst iteration -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains definitions of two iterators for iterating over the
+// instructions in a function. This is effectively a wrapper around a two level
+// iterator that can probably be genericized later.
+//
+// Note that this iterator gets invalidated any time that basic blocks or
+// instructions are moved around.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_INSTITERATOR_H
+#define LLVM_SUPPORT_INSTITERATOR_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Function.h"
+
+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
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef IIty value_type;
+ typedef signed difference_type;
+ typedef IIty* pointer;
+ typedef IIty& reference;
+
+ // Default constructor
+ InstIterator() {}
+
+ // Copy constructor...
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(const InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<typename A, typename B, typename C, typename D>
+ InstIterator(InstIterator<A,B,C,D> &II)
+ : BBs(II.BBs), BB(II.BB), BI(II.BI) {}
+
+ template<class M> InstIterator(M &m)
+ : BBs(&m.getBasicBlockList()), BB(BBs->begin()) { // begin ctor
+ if (BB != BBs->end()) {
+ BI = BB->begin();
+ advanceToNextBB();
+ }
+ }
+
+ template<class M> InstIterator(M &m, bool)
+ : BBs(&m.getBasicBlockList()), BB(BBs->end()) { // end ctor
+ }
+
+ // Accessors to get at the underlying iterators...
+ inline BBIty &getBasicBlockIterator() { return BB; }
+ inline BIty &getInstructionIterator() { return BI; }
+
+ inline reference operator*() const { return *BI; }
+ inline pointer operator->() const { return &operator*(); }
+
+ inline bool operator==(const InstIterator &y) const {
+ return BB == y.BB && (BB == BBs->end() || BI == y.BI);
+ }
+ inline bool operator!=(const InstIterator& y) const {
+ return !operator==(y);
+ }
+
+ InstIterator& operator++() {
+ ++BI;
+ advanceToNextBB();
+ return *this;
+ }
+ inline InstIterator operator++(int) {
+ InstIterator tmp = *this; ++*this; return tmp;
+ }
+
+ InstIterator& operator--() {
+ while (BB == BBs->end() || BI == BB->begin()) {
+ --BB;
+ BI = BB->end();
+ }
+ --BI;
+ return *this;
+ }
+ inline InstIterator operator--(int) {
+ InstIterator tmp = *this; --*this; return tmp;
+ }
+
+ inline bool atEnd() const { return BB == BBs->end(); }
+
+private:
+ inline void advanceToNextBB() {
+ // The only way that the II could be broken is if it is now pointing to
+ // the end() of the current BasicBlock and there are successor BBs.
+ while (BI == BB->end()) {
+ ++BB;
+ if (BB == BBs->end()) break;
+ BI = BB->begin();
+ }
+ }
+};
+
+
+typedef InstIterator<iplist<BasicBlock>,
+ Function::iterator, BasicBlock::iterator,
+ Instruction> inst_iterator;
+typedef InstIterator<const iplist<BasicBlock>,
+ Function::const_iterator,
+ BasicBlock::const_iterator,
+ const Instruction> const_inst_iterator;
+
+inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
+inline inst_iterator inst_end(Function *F) { return inst_iterator(*F, true); }
+inline const_inst_iterator inst_begin(const Function *F) {
+ return const_inst_iterator(*F);
+}
+inline const_inst_iterator inst_end(const Function *F) {
+ return const_inst_iterator(*F, true);
+}
+inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
+inline inst_iterator inst_end(Function &F) { return inst_iterator(F, true); }
+inline const_inst_iterator inst_begin(const Function &F) {
+ return const_inst_iterator(F);
+}
+inline const_inst_iterator inst_end(const Function &F) {
+ return const_inst_iterator(F, true);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
new file mode 100644
index 0000000..e848c9b
--- /dev/null
+++ b/include/llvm/Support/InstVisitor.h
@@ -0,0 +1,221 @@
+//===- llvm/Support/InstVisitor.h - Define instruction visitors -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_SUPPORT_INSTVISITOR_H
+#define LLVM_SUPPORT_INSTVISITOR_H
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+
+namespace llvm {
+
+// We operate on opaque instruction classes, so forward declare all instruction
+// types now...
+//
+#define HANDLE_INST(NUM, OPCODE, CLASS) class CLASS;
+#include "llvm/Instruction.def"
+
+// Forward declare the intermediate types...
+class TerminatorInst; class BinaryOperator;
+class AllocationInst;
+
+#define DELEGATE(CLASS_TO_VISIT) \
+ return static_cast<SubClass*>(this)-> \
+ visit##CLASS_TO_VISIT(static_cast<CLASS_TO_VISIT&>(I))
+
+
+/// @brief Base class for instruction visitors
+///
+/// Instruction visitors are used when you want to perform different action for
+/// different kinds of instruction without without having to use lots of casts
+/// and a big switch statement (in your code that is).
+///
+/// To define your own visitor, inherit from this class, specifying your
+/// new type for the 'SubClass' template parameter, and "override" visitXXX
+/// functions in your class. I say "overriding" because this class is defined
+/// in terms of statically resolved overloading, not virtual functions.
+///
+/// For example, here is a visitor that counts the number of malloc
+/// instructions processed:
+///
+/// /// Declare the class. Note that we derive from InstVisitor instantiated
+/// /// with _our new subclasses_ type.
+/// ///
+/// struct CountMallocVisitor : public InstVisitor<CountMallocVisitor> {
+/// unsigned Count;
+/// CountMallocVisitor() : Count(0) {}
+///
+/// void visitMallocInst(MallocInst &MI) { ++Count; }
+/// };
+///
+/// And this class would be used like this:
+/// CountMallocVistor CMV;
+/// CMV.visit(function);
+/// NumMallocs = CMV.Count;
+///
+/// The defined has 'visit' methods for Instruction, and also for BasicBlock,
+/// Function, and Module, which recursively process all conained instructions.
+///
+/// Note that if you don't implement visitXXX for some instruction type,
+/// the visitXXX method for instruction superclass will be invoked. So
+/// if instructions are added in the future, they will be automatically
+/// supported, if you handle on of their superclasses.
+///
+/// The optional second template argument specifies the type that instruction
+/// visitation functions should return. If you specify this, you *MUST* provide
+/// an implementation of visitInstruction though!.
+///
+/// Note that this class is specifically designed as a template to avoid
+/// virtual function call overhead. Defining and using an InstVisitor is just
+/// as efficient as having your own switch statement over the instruction
+/// opcode.
+template<typename SubClass, typename RetTy=void>
+class InstVisitor {
+ //===--------------------------------------------------------------------===//
+ // Interface code - This is the public interface of the InstVisitor that you
+ // use to visit instructions...
+ //
+
+public:
+ // Generic visit method - Allow visitation to all instructions in a range
+ template<class Iterator>
+ void visit(Iterator Start, Iterator End) {
+ while (Start != End)
+ static_cast<SubClass*>(this)->visit(*Start++);
+ }
+
+ // Define visitors for functions and basic blocks...
+ //
+ void visit(Module &M) {
+ static_cast<SubClass*>(this)->visitModule(M);
+ visit(M.begin(), M.end());
+ }
+ void visit(Function &F) {
+ static_cast<SubClass*>(this)->visitFunction(F);
+ visit(F.begin(), F.end());
+ }
+ void visit(BasicBlock &BB) {
+ static_cast<SubClass*>(this)->visitBasicBlock(BB);
+ visit(BB.begin(), BB.end());
+ }
+
+ // Forwarding functions so that the user can visit with pointers AND refs.
+ void visit(Module *M) { visit(*M); }
+ void visit(Function *F) { visit(*F); }
+ void visit(BasicBlock *BB) { visit(*BB); }
+ RetTy visit(Instruction *I) { return visit(*I); }
+
+ // visit - Finally, code to visit an instruction...
+ //
+ RetTy visit(Instruction &I) {
+ switch (I.getOpcode()) {
+ default: assert(0 && "Unknown instruction type encountered!");
+ abort();
+ // Build the switch statement using the Instruction.def file...
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ case Instruction::OPCODE: return \
+ static_cast<SubClass*>(this)-> \
+ visit##OPCODE(static_cast<CLASS&>(I));
+#include "llvm/Instruction.def"
+ }
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Visitation functions... these functions provide default fallbacks in case
+ // the user does not specify what to do for a particular instruction type.
+ // The default behavior is to generalize the instruction type to its subtype
+ // and try visiting the subtype. All of this should be inlined perfectly,
+ // because there are no virtual functions to get in the way.
+ //
+
+ // When visiting a module, function or basic block directly, these methods get
+ // called to indicate when transitioning into a new unit.
+ //
+ void visitModule (Module &M) {}
+ void visitFunction (Function &F) {}
+ void visitBasicBlock(BasicBlock &BB) {}
+
+ // Define instruction specific visitor functions that can be overridden to
+ // handle SPECIFIC instructions. These functions automatically define
+ // visitMul to proxy to visitBinaryOperator for instance in case the user does
+ // not need this generality.
+ //
+ // The one problem case we have to handle here though is that the PHINode
+ // class and opcode name are the exact same. Because of this, we cannot
+ // define visitPHINode (the inst version) to forward to visitPHINode (the
+ // generic version) without multiply defined symbols and recursion. To handle
+ // this, we do not autoexpand "Other" instructions, we do it manually.
+ //
+#define HANDLE_INST(NUM, OPCODE, CLASS) \
+ RetTy visit##OPCODE(CLASS &I) { DELEGATE(CLASS); }
+#include "llvm/Instruction.def"
+
+ // Specific Instruction type classes... note that all of the casts are
+ // necessary because we use the instruction classes as opaque types...
+ //
+ RetTy visitReturnInst(ReturnInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitBranchInst(BranchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitSwitchInst(SwitchInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
+ RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
+ RetTy visitLoadInst(LoadInst &I) { DELEGATE(Instruction); }
+ RetTy visitStoreInst(StoreInst &I) { DELEGATE(Instruction); }
+ RetTy visitGetElementPtrInst(GetElementPtrInst &I){ DELEGATE(Instruction); }
+ RetTy visitPHINode(PHINode &I) { DELEGATE(Instruction); }
+ RetTy visitTruncInst(TruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitZExtInst(ZExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitSExtInst(SExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPTruncInst(FPTruncInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPExtInst(FPExtInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToUIInst(FPToUIInst &I) { DELEGATE(CastInst); }
+ RetTy visitFPToSIInst(FPToSIInst &I) { DELEGATE(CastInst); }
+ RetTy visitUIToFPInst(UIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitSIToFPInst(SIToFPInst &I) { DELEGATE(CastInst); }
+ RetTy visitPtrToIntInst(PtrToIntInst &I) { DELEGATE(CastInst); }
+ RetTy visitIntToPtrInst(IntToPtrInst &I) { DELEGATE(CastInst); }
+ RetTy visitBitCastInst(BitCastInst &I) { DELEGATE(CastInst); }
+ RetTy visitSelectInst(SelectInst &I) { DELEGATE(Instruction); }
+ RetTy visitCallInst(CallInst &I) { DELEGATE(Instruction); }
+ RetTy visitVAArgInst(VAArgInst &I) { DELEGATE(Instruction); }
+ RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
+ RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
+ RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
+
+ // Next level propagators... if the user does not overload a specific
+ // instruction type, they can overload one of these to get the whole class
+ // of instructions...
+ //
+ RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
+ RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
+ RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
+ RetTy visitCastInst(CastInst &I) { DELEGATE(Instruction); }
+
+ // If the user wants a 'default' case, they can choose to override this
+ // function. If this function is not overloaded in the users subclass, then
+ // this instruction just gets ignored.
+ //
+ // Note that you MUST override this function if your return type is not void.
+ //
+ void visitInstruction(Instruction &I) {} // Ignore unhandled instructions
+};
+
+#undef DELEGATE
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/LLVMBuilder.h b/include/llvm/Support/LLVMBuilder.h
new file mode 100644
index 0000000..5a80e41
--- /dev/null
+++ b/include/llvm/Support/LLVMBuilder.h
@@ -0,0 +1,431 @@
+//===-- llvm/Support/LLVMBuilder.h - Builder for LLVM Instrs ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LLVMBuilder class, which is used as a convenient way
+// to create LLVM instructions with a consistent and simplified interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LLVMBUILDER_H
+#define LLVM_SUPPORT_LLVMBUILDER_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+
+/// LLVMBuilder - This provides a uniform API for creating instructions and
+/// inserting them into a basic block: either at the end of a BasicBlock, or
+/// at a specific iterator location in a block.
+///
+/// Note that the builder does not expose the full generality of LLVM
+/// instructions. For example, it cannot be used to create instructions with
+/// arbitrary names (specifically, names with nul characters in them) - It only
+/// supports nul-terminated C strings. For fully generic names, use
+/// I->setName(). For access to extra instruction properties, use the mutators
+/// (e.g. setVolatile) on the instructions after they have been created.
+class LLVMBuilder {
+ BasicBlock *BB;
+ BasicBlock::iterator InsertPt;
+public:
+ LLVMBuilder() { ClearInsertionPoint(); }
+ explicit LLVMBuilder(BasicBlock *TheBB) { SetInsertPoint(TheBB); }
+ LLVMBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ SetInsertPoint(TheBB, IP);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Builder configuration methods
+ //===--------------------------------------------------------------------===//
+
+ /// ClearInsertionPoint - Clear the insertion point: created instructions will
+ /// not be inserted into a block.
+ void ClearInsertionPoint() {
+ BB = 0;
+ }
+
+ BasicBlock *GetInsertBlock() const { return BB; }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// appended to the end of the specified block.
+ void SetInsertPoint(BasicBlock *TheBB) {
+ BB = TheBB;
+ InsertPt = BB->end();
+ }
+
+ /// SetInsertPoint - This specifies that created instructions should be
+ /// inserted at the specified point.
+ void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
+ BB = TheBB;
+ InsertPt = IP;
+ }
+
+ /// Insert - Insert and return the specified instruction.
+ template<typename InstTy>
+ InstTy *Insert(InstTy *I) const {
+ InsertHelper(I);
+ return I;
+ }
+
+ /// InsertHelper - Insert the specified instruction at the specified insertion
+ /// point. This is split out of Insert so that it isn't duplicated for every
+ /// template instantiation.
+ void InsertHelper(Instruction *I) const {
+ if (BB) BB->getInstList().insert(InsertPt, I);
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Terminators
+ //===--------------------------------------------------------------------===//
+
+ /// CreateRetVoid - Create a 'ret void' instruction.
+ ReturnInst *CreateRetVoid() {
+ return Insert(new ReturnInst());
+ }
+
+ /// CreateRet - Create a 'ret <val>' instruction.
+ ReturnInst *CreateRet(Value *V) {
+ return Insert(new ReturnInst(V));
+ }
+
+ /// CreateBr - Create an unconditional 'br label X' instruction.
+ BranchInst *CreateBr(BasicBlock *Dest) {
+ return Insert(new BranchInst(Dest));
+ }
+
+ /// CreateCondBr - Create a conditional 'br Cond, TrueDest, FalseDest'
+ /// instruction.
+ BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
+ return Insert(new BranchInst(True, False, Cond));
+ }
+
+ /// CreateSwitch - Create a switch instruction with the specified value,
+ /// default dest, and with a hint for the number of cases that will be added
+ /// (for efficient allocation).
+ SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
+ return Insert(new SwitchInst(V, Dest, NumCases));
+ }
+
+ /// CreateInvoke - Create an invoke instruction.
+ InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+ BasicBlock *UnwindDest,
+ Value *const* Args, unsigned NumArgs,
+ const char *Name = "") {
+ return Insert(new InvokeInst(Callee, NormalDest, UnwindDest, Args, NumArgs,
+ Name));
+ }
+
+ UnwindInst *CreateUnwind() {
+ return Insert(new UnwindInst());
+ }
+
+ UnreachableInst *CreateUnreachable() {
+ return Insert(new UnreachableInst());
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Binary Operators
+ //===--------------------------------------------------------------------===//
+
+ BinaryOperator *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAdd(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSub(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createMul(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createUDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createFDiv(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createURem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createSRem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createFRem(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createShl(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createLShr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAShr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createAnd(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createOr(LHS, RHS, Name));
+ }
+ BinaryOperator *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::createXor(LHS, RHS, Name));
+ }
+
+ BinaryOperator *CreateBinOp(Instruction::BinaryOps Opc,
+ Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(BinaryOperator::create(Opc, LHS, RHS, Name));
+ }
+
+ BinaryOperator *CreateNeg(Value *V, const char *Name = "") {
+ return Insert(BinaryOperator::createNeg(V, Name));
+ }
+ BinaryOperator *CreateNot(Value *V, const char *Name = "") {
+ return Insert(BinaryOperator::createNot(V, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Memory Instructions
+ //===--------------------------------------------------------------------===//
+
+ MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new MallocInst(Ty, ArraySize, Name));
+ }
+ AllocaInst *CreateAlloca(const Type *Ty, Value *ArraySize = 0,
+ const char *Name = "") {
+ return Insert(new AllocaInst(Ty, ArraySize, Name));
+ }
+ FreeInst *CreateFree(Value *Ptr) {
+ return Insert(new FreeInst(Ptr));
+ }
+ LoadInst *CreateLoad(Value *Ptr, const char *Name = 0) {
+ return Insert(new LoadInst(Ptr, Name));
+ }
+ LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = 0) {
+ return Insert(new LoadInst(Ptr, Name, isVolatile));
+ }
+ StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
+ return Insert(new StoreInst(Val, Ptr, isVolatile));
+ }
+ GetElementPtrInst *CreateGEP(Value *Ptr, Value* const *Idx, unsigned NumIdx,
+ const char *Name = "") {
+ return Insert(new GetElementPtrInst(Ptr, Idx, NumIdx, Name));
+ }
+ GetElementPtrInst *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+ return Insert(new GetElementPtrInst(Ptr, &Idx, 1, Name));
+ }
+ GetElementPtrInst *CreateGEP(Value *Ptr, Value *Idx0, Value *Idx1,
+ const char *Name = "") {
+ return Insert(new GetElementPtrInst(Ptr, Idx0, Idx1, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Cast/Conversion Operators
+ //===--------------------------------------------------------------------===//
+
+ TruncInst *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new TruncInst(V, DestTy, Name));
+ }
+ ZExtInst *CreateZExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new ZExtInst(V, DestTy, Name));
+ }
+ SExtInst *CreateSExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new SExtInst(V, DestTy, Name));
+ }
+ FPToUIInst *CreateFPToUI(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new FPToUIInst(V, DestTy, Name));
+ }
+ FPToSIInst *CreateFPToSI(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new FPToSIInst(V, DestTy, Name));
+ }
+ UIToFPInst *CreateUIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new UIToFPInst(V, DestTy, Name));
+ }
+ SIToFPInst *CreateSIToFP(Value *V, const Type *DestTy, const char *Name = ""){
+ return Insert(new SIToFPInst(V, DestTy, Name));
+ }
+ FPTruncInst *CreateFPTrunc(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new FPTruncInst(V, DestTy, Name));
+ }
+ FPExtInst *CreateFPExt(Value *V, const Type *DestTy, const char *Name = "") {
+ return Insert(new FPExtInst(V, DestTy, Name));
+ }
+ PtrToIntInst *CreatePtrToInt(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new PtrToIntInst(V, DestTy, Name));
+ }
+ IntToPtrInst *CreateIntToPtr(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new IntToPtrInst(V, DestTy, Name));
+ }
+ BitCastInst *CreateBitCast(Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(new BitCastInst(V, DestTy, Name));
+ }
+
+ CastInst *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
+ const char *Name = "") {
+ return Insert(CastInst::create(Op, V, DestTy, Name));
+ }
+ CastInst *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
+ const char *Name = "") {
+ return Insert(CastInst::createIntegerCast(V, DestTy, isSigned, Name));
+ }
+
+
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Compare Instructions
+ //===--------------------------------------------------------------------===//
+
+ ICmpInst *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS, Name));
+ }
+ ICmpInst *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS, Name));
+ }
+
+ FCmpInst *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OEQ, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OGT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OGE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOLT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OLT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpOLE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_OLE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpONE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ONE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpORD(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ORD, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUNO(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UNO, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUEQ(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UEQ, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUGT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UGT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUGE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UGE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpULT(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ULT, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpULE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_ULE, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmpUNE(Value *LHS, Value *RHS, const char *Name = "") {
+ return Insert(new FCmpInst(FCmpInst::FCMP_UNE, LHS, RHS, Name));
+ }
+
+
+ ICmpInst *CreateICmp(ICmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ return Insert(new ICmpInst(P, LHS, RHS, Name));
+ }
+ FCmpInst *CreateFCmp(FCmpInst::Predicate P, Value *LHS, Value *RHS,
+ const char *Name = "") {
+ return Insert(new FCmpInst(P, LHS, RHS, Name));
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Instruction creation methods: Other Instructions
+ //===--------------------------------------------------------------------===//
+
+ PHINode *CreatePHI(const Type *Ty, const char *Name = "") {
+ return Insert(new PHINode(Ty, Name));
+ }
+
+ CallInst *CreateCall(Value *Callee, const char *Name = "") {
+ return Insert(new CallInst(Callee, (Value**)0, 0, Name));
+ }
+ CallInst *CreateCall(Value *Callee, Value *Arg, const char *Name = "") {
+ return Insert(new CallInst(Callee, &Arg, 1, Name));
+ }
+ CallInst *CreateCall(Value *Callee, Value *Arg0, Value *Arg1,
+ const char *Name = "") {
+ Value *Args[] = { Arg0, Arg1 };
+ return Insert(new CallInst(Callee, Args, 2, Name));
+ }
+
+
+ CallInst *CreateCall(Value *Callee, Value* const *Args, unsigned NumArgs,
+ const char *Name = "") {
+ return Insert(new CallInst(Callee, Args, NumArgs, Name));
+ }
+
+ SelectInst *CreateSelect(Value *C, Value *True, Value *False,
+ const char *Name = "") {
+ return Insert(new SelectInst(C, True, False, Name));
+ }
+
+ VAArgInst *CreateVAArg(Value *List, const Type *Ty, const char *Name = "") {
+ return Insert(new VAArgInst(List, Ty, Name));
+ }
+
+ ExtractElementInst *CreateExtractElement(Value *Vec, Value *Idx,
+ const char *Name = "") {
+ return Insert(new ExtractElementInst(Vec, Idx, Name));
+ }
+
+ InsertElementInst *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
+ const char *Name = "") {
+ return Insert(new InsertElementInst(Vec, NewElt, Idx, Name));
+ }
+
+ ShuffleVectorInst *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
+ const char *Name = "") {
+ return Insert(new ShuffleVectorInst(V1, V2, Mask, Name));
+ }
+};
+
+// TODO: A version of LLVMBuilder that constant folds operands as they come in.
+//class LLVMFoldingBuilder {
+//};
+
+}
+
+#endif
diff --git a/include/llvm/Support/LeakDetector.h b/include/llvm/Support/LeakDetector.h
new file mode 100644
index 0000000..92784ee
--- /dev/null
+++ b/include/llvm/Support/LeakDetector.h
@@ -0,0 +1,91 @@
+//===-- llvm/Support/LeakDetector.h - Provide leak detection ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a class that can be used to provide very simple memory leak
+// checks for an API. Basically LLVM uses this to make sure that Instructions,
+// for example, are deleted when they are supposed to be, and not leaked away.
+//
+// When compiling with NDEBUG (Release build), this class does nothing, thus
+// adding no checking overhead to release builds. Note that this class is
+// implemented in a very simple way, requiring completely manual manipulation
+// and checking for garbage, but this is intentional: users should not be using
+// this API, only other APIs should.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_LEAKDETECTOR_H
+#define LLVM_SUPPORT_LEAKDETECTOR_H
+
+#include <string>
+
+namespace llvm {
+
+class Value;
+
+struct LeakDetector {
+ /// addGarbageObject - Add a pointer to the internal set of "garbage" object
+ /// pointers. This should be called when objects are created, or if they are
+ /// taken out of an owning collection.
+ ///
+ static void addGarbageObject(void *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// removeGarbageObject - Remove a pointer from our internal representation of
+ /// our "garbage" objects. This should be called when an object is added to
+ /// an "owning" collection.
+ ///
+ static void removeGarbageObject(void *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+ /// checkForGarbage - Traverse the internal representation of garbage
+ /// pointers. If there are any pointers that have been add'ed, but not
+ /// remove'd, big obnoxious warnings about memory leaks are issued.
+ ///
+ /// The specified message will be printed indicating when the check was
+ /// performed.
+ ///
+ static void checkForGarbage(const std::string &Message) {
+#ifndef NDEBUG
+ checkForGarbageImpl(Message);
+#endif
+ }
+
+ /// Overload the normal methods to work better with Value*'s because they are
+ /// by far the most common in LLVM. This does not affect the actual
+ /// functioning of this class, it just makes the warning messages nicer.
+ ///
+ static void addGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ addGarbageObjectImpl(Object);
+#endif
+ }
+ static void removeGarbageObject(const Value *Object) {
+#ifndef NDEBUG
+ removeGarbageObjectImpl(Object);
+#endif
+ }
+
+private:
+ // If we are debugging, the actual implementations will be called...
+ static void addGarbageObjectImpl(const Value *Object);
+ static void removeGarbageObjectImpl(const Value *Object);
+ static void addGarbageObjectImpl(void *Object);
+ static void removeGarbageObjectImpl(void *Object);
+ static void checkForGarbageImpl(const std::string &Message);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/ManagedStatic.h b/include/llvm/Support/ManagedStatic.h
new file mode 100644
index 0000000..e65fb1b
--- /dev/null
+++ b/include/llvm/Support/ManagedStatic.h
@@ -0,0 +1,96 @@
+//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the ManagedStatic class and the llvm_shutdown() function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
+#define LLVM_SUPPORT_MANAGED_STATIC_H
+
+namespace llvm {
+
+/// object_deleter - Helper method for ManagedStatic.
+///
+template<class C>
+void object_deleter(void *Ptr) {
+ delete (C*)Ptr;
+}
+
+/// ManagedStaticBase - Common base class for ManagedStatic instances.
+class ManagedStaticBase {
+protected:
+ // This should only be used as a static variable, which guarantees that this
+ // will be zero initialized.
+ mutable void *Ptr;
+ mutable void (*DeleterFn)(void*);
+ mutable const ManagedStaticBase *Next;
+
+ void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
+public:
+ /// isConstructed - Return true if this object has not been created yet.
+ bool isConstructed() const { return Ptr != 0; }
+
+ void destroy() const;
+};
+
+/// ManagedStatic - This transparently changes the behavior of global statics to
+/// be lazily constructed on demand (good for reducing startup times of dynamic
+/// libraries that link in LLVM components) and for making destruction be
+/// explicit through the llvm_shutdown() function call.
+///
+template<class C>
+class ManagedStatic : public ManagedStaticBase {
+public:
+
+ // Accessors.
+ C &operator*() {
+ if (!Ptr) LazyInit();
+ return *static_cast<C*>(Ptr);
+ }
+ C *operator->() {
+ if (!Ptr) LazyInit();
+ return static_cast<C*>(Ptr);
+ }
+ const C &operator*() const {
+ if (!Ptr) LazyInit();
+ return *static_cast<C*>(Ptr);
+ }
+ const C *operator->() const {
+ if (!Ptr) LazyInit();
+ return static_cast<C*>(Ptr);
+ }
+
+public:
+ void LazyInit() const {
+ RegisterManagedStatic(new C(), object_deleter<C>);
+ }
+};
+
+template<void (*CleanupFn)(void*)>
+class ManagedCleanup : public ManagedStaticBase {
+public:
+ void Register() { RegisterManagedStatic(0, CleanupFn); }
+};
+
+
+/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
+void llvm_shutdown();
+
+
+/// llvm_shutdown_obj - This is a simple helper class that calls
+/// llvm_shutdown() when it is destroyed.
+struct llvm_shutdown_obj {
+ llvm_shutdown_obj() {}
+ ~llvm_shutdown_obj() { llvm_shutdown(); }
+};
+
+}
+
+#endif
diff --git a/include/llvm/Support/Mangler.h b/include/llvm/Support/Mangler.h
new file mode 100644
index 0000000..b6f9839
--- /dev/null
+++ b/include/llvm/Support/Mangler.h
@@ -0,0 +1,118 @@
+//===-- llvm/Support/Mangler.h - Self-contained name mangler ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unified name mangler for various backends.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MANGLER_H
+#define LLVM_SUPPORT_MANGLER_H
+
+#include "llvm/System/IncludeFile.h"
+#include <map>
+#include <set>
+#include <string>
+
+namespace llvm {
+class Type;
+class Module;
+class Value;
+class GlobalValue;
+
+class Mangler {
+ /// Prefix - This string is added to each symbol that is emitted, unless the
+ /// symbol is marked as not needing this prefix.
+ const char *Prefix;
+
+ /// UseQuotes - If this is set, the target accepts global names in quotes,
+ /// e.g. "foo bar" is a legal name. This syntax is used instead of escaping
+ /// the space character. By default, this is false.
+ bool UseQuotes;
+
+ /// PreserveAsmNames - If this is set, the asm escape character is not removed
+ /// from names with 'asm' specifiers.
+ bool PreserveAsmNames;
+
+ /// Memo - This is used to remember the name that we assign a value.
+ ///
+ std::map<const Value*, std::string> Memo;
+
+ /// Count - This simple counter is used to unique value names.
+ ///
+ unsigned Count;
+
+ /// TypeMap - If the client wants us to unique types, this keeps track of the
+ /// current assignments and TypeCounter keeps track of the next id to assign.
+ std::map<const Type*, unsigned> TypeMap;
+ unsigned TypeCounter;
+
+ /// This keeps track of which global values have had their names
+ /// mangled in the current module.
+ ///
+ std::set<const GlobalValue*> MangledGlobals;
+
+ /// AcceptableChars - This bitfield contains a one for each character that is
+ /// allowed to be part of an unmangled name.
+ unsigned AcceptableChars[256/32];
+public:
+
+ // Mangler ctor - if a prefix is specified, it will be prepended onto all
+ // symbols.
+ Mangler(Module &M, const char *Prefix = "");
+
+ /// setUseQuotes - If UseQuotes is set to true, this target accepts quoted
+ /// strings for assembler labels.
+ void setUseQuotes(bool Val) { UseQuotes = Val; }
+
+ /// setPreserveAsmNames - If the mangler should not strip off the asm name
+ /// identifier (\001), this should be set.
+ void setPreserveAsmNames(bool Val) { PreserveAsmNames = Val; }
+
+ /// Acceptable Characters - This allows the target to specify which characters
+ /// are acceptable to the assembler without being mangled. By default we
+ /// allow letters, numbers, '_', '$', and '.', which is what GAS accepts.
+ void markCharAcceptable(unsigned char X) {
+ AcceptableChars[X/32] |= 1 << (X&31);
+ }
+ void markCharUnacceptable(unsigned char X) {
+ AcceptableChars[X/32] &= ~(1 << (X&31));
+ }
+ bool isCharAcceptable(unsigned char X) const {
+ return (AcceptableChars[X/32] & (1 << (X&31))) != 0;
+ }
+
+ /// getTypeID - Return a unique ID for the specified LLVM type.
+ ///
+ unsigned getTypeID(const Type *Ty);
+
+ /// getValueName - Returns the mangled name of V, an LLVM Value,
+ /// in the current module.
+ ///
+ std::string getValueName(const GlobalValue *V);
+ std::string getValueName(const Value *V);
+
+ /// makeNameProper - We don't want identifier names with ., space, or
+ /// - in them, so we mangle these characters into the strings "d_",
+ /// "s_", and "D_", respectively. This is a very simple mangling that
+ /// doesn't guarantee unique names for values. getValueName already
+ /// does this for you, so there's no point calling it on the result
+ /// from getValueName.
+ ///
+ std::string makeNameProper(const std::string &x, const char *Prefix = "");
+
+private:
+ void InsertName(GlobalValue *GV, std::map<std::string, GlobalValue*> &Names);
+};
+
+} // End llvm namespace
+
+// Force the Mangler.cpp file to be linked when this header is #included
+FORCE_DEFINING_FILE_TO_BE_LINKED(Mangler)
+
+#endif // LLVM_SUPPORT_MANGLER_H
diff --git a/include/llvm/Support/MathExtras.h b/include/llvm/Support/MathExtras.h
new file mode 100644
index 0000000..88a1103
--- /dev/null
+++ b/include/llvm/Support/MathExtras.h
@@ -0,0 +1,363 @@
+//===-- llvm/Support/MathExtras.h - Useful math functions -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains some functions that are useful for math stuff.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MATHEXTRAS_H
+#define LLVM_SUPPORT_MATHEXTRAS_H
+
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+// NOTE: The following support functions use the _32/_64 extensions instead of
+// type overloading so that signed and unsigned integers can be used without
+// ambiguity.
+
+/// Hi_32 - This function returns the high 32 bits of a 64 bit value.
+inline uint32_t Hi_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value >> 32);
+}
+
+/// Lo_32 - This function returns the low 32 bits of a 64 bit value.
+inline uint32_t Lo_32(uint64_t Value) {
+ return static_cast<uint32_t>(Value);
+}
+
+/// is?Type - these functions produce optimal testing for integer data types.
+inline bool isInt8 (int64_t Value) {
+ return static_cast<int8_t>(Value) == Value;
+}
+inline bool isUInt8 (int64_t Value) {
+ return static_cast<uint8_t>(Value) == Value;
+}
+inline bool isInt16 (int64_t Value) {
+ return static_cast<int16_t>(Value) == Value;
+}
+inline bool isUInt16(int64_t Value) {
+ return static_cast<uint16_t>(Value) == Value;
+}
+inline bool isInt32 (int64_t Value) {
+ return static_cast<int32_t>(Value) == Value;
+}
+inline bool isUInt32(int64_t Value) {
+ return static_cast<uint32_t>(Value) == Value;
+}
+
+/// isMask_32 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (32 bit
+/// version). Ex. isMask_32(0x0000FFFFU) == true.
+inline bool isMask_32(uint32_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isMask_64 - This function returns true if the argument is a sequence of ones
+/// starting at the least significant bit with the remainder zero (64 bit
+/// version).
+inline bool isMask_64(uint64_t Value) {
+ return Value && ((Value + 1) & Value) == 0;
+}
+
+/// isShiftedMask_32 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (32 bit version.)
+/// Ex. isShiftedMask_32(0x0000FF00U) == true.
+inline bool isShiftedMask_32(uint32_t Value) {
+ return isMask_32((Value - 1) | Value);
+}
+
+/// isShiftedMask_64 - This function returns true if the argument contains a
+/// sequence of ones with the remainder zero (64 bit version.)
+inline bool isShiftedMask_64(uint64_t Value) {
+ return isMask_64((Value - 1) | Value);
+}
+
+/// isPowerOf2_32 - This function returns true if the argument is a power of
+/// two > 0. Ex. isPowerOf2_32(0x00100000U) == true (32 bit edition.)
+inline bool isPowerOf2_32(uint32_t Value) {
+ return Value && !(Value & (Value - 1));
+}
+
+/// isPowerOf2_64 - This function returns true if the argument is a power of two
+/// > 0 (64 bit edition.)
+inline bool isPowerOf2_64(uint64_t Value) {
+ return Value && !(Value & (Value - int64_t(1L)));
+}
+
+/// ByteSwap_16 - This function returns a byte-swapped representation of the
+/// 16-bit argument, Value.
+inline uint16_t ByteSwap_16(uint16_t Value) {
+#if defined(_MSC_VER) && !defined(_DEBUG)
+ // The DLL version of the runtime lacks these functions (bug!?), but in a
+ // release build they're replaced with BSWAP instructions anyway.
+ return _byteswap_ushort(Value);
+#else
+ uint16_t Hi = Value << 8;
+ uint16_t Lo = Value >> 8;
+ return Hi | Lo;
+#endif
+}
+
+/// ByteSwap_32 - This function returns a byte-swapped representation of the
+/// 32-bit argument, Value.
+inline uint32_t ByteSwap_32(uint32_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap32(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_ulong(Value);
+#else
+ uint32_t Byte0 = Value & 0x000000FF;
+ uint32_t Byte1 = Value & 0x0000FF00;
+ uint32_t Byte2 = Value & 0x00FF0000;
+ uint32_t Byte3 = Value & 0xFF000000;
+ return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
+#endif
+}
+
+/// ByteSwap_64 - This function returns a byte-swapped representation of the
+/// 64-bit argument, Value.
+inline uint64_t ByteSwap_64(uint64_t Value) {
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+ return __builtin_bswap64(Value);
+#elif defined(_MSC_VER) && !defined(_DEBUG)
+ return _byteswap_uint64(Value);
+#else
+ uint64_t Hi = ByteSwap_32(uint32_t(Value));
+ uint32_t Lo = ByteSwap_32(uint32_t(Value >> 32));
+ return (Hi << 32) | Lo;
+#endif
+}
+
+/// CountLeadingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the most significant bit to the first one
+/// bit. Ex. CountLeadingZeros_32(0x00F000FF) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountLeadingZeros_32(uint32_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clz(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 32;
+#endif
+ Count = __builtin_clz(Value);
+#else
+ if (!Value) return 32;
+ Count = 0;
+ // bisecton method for count leading zeros
+ for (unsigned Shift = 32 >> 1; Shift; Shift >>= 1) {
+ uint32_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountLeadingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the most significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountLeadingZeros_64(uint64_t Value) {
+ unsigned Count; // result
+#if __GNUC__ >= 4
+ // PowerPC is defined for __builtin_clzll(0)
+#if !defined(__ppc__) && !defined(__ppc64__)
+ if (!Value) return 64;
+#endif
+ Count = __builtin_clzll(Value);
+#else
+ if (sizeof(long) == sizeof(int64_t)) {
+ if (!Value) return 64;
+ Count = 0;
+ // bisecton method for count leading zeros
+ for (unsigned Shift = 64 >> 1; Shift; Shift >>= 1) {
+ uint64_t Tmp = Value >> Shift;
+ if (Tmp) {
+ Value = Tmp;
+ } else {
+ Count |= Shift;
+ }
+ }
+ } else {
+ // get hi portion
+ uint32_t Hi = Hi_32(Value);
+
+ // if some bits in hi portion
+ if (Hi) {
+ // leading zeros in hi portion plus all bits in lo portion
+ Count = CountLeadingZeros_32(Hi);
+ } else {
+ // get lo portion
+ uint32_t Lo = Lo_32(Value);
+ // same as 32 bit value
+ Count = CountLeadingZeros_32(Lo)+32;
+ }
+ }
+#endif
+ return Count;
+}
+
+/// CountTrailingZeros_32 - this function performs the platform optimal form of
+/// counting the number of zeros from the least significant bit to the first one
+/// bit. Ex. CountTrailingZeros_32(0xFF00FF00) == 8.
+/// Returns 32 if the word is zero.
+inline unsigned CountTrailingZeros_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctz(Value) : 32;
+#else
+ static const unsigned Mod37BitPosition[] = {
+ 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13,
+ 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9,
+ 5, 20, 8, 19, 18
+ };
+ return Mod37BitPosition[(-Value & Value) % 37];
+#endif
+}
+
+/// CountTrailingZeros_64 - This function performs the platform optimal form
+/// of counting the number of zeros from the least significant bit to the first
+/// one bit (64 bit edition.)
+/// Returns 64 if the word is zero.
+inline unsigned CountTrailingZeros_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return Value ? __builtin_ctzll(Value) : 64;
+#else
+ static const unsigned Mod67Position[] = {
+ 64, 0, 1, 39, 2, 15, 40, 23, 3, 12, 16, 59, 41, 19, 24, 54,
+ 4, 64, 13, 10, 17, 62, 60, 28, 42, 30, 20, 51, 25, 44, 55,
+ 47, 5, 32, 65, 38, 14, 22, 11, 58, 18, 53, 63, 9, 61, 27,
+ 29, 50, 43, 46, 31, 37, 21, 57, 52, 8, 26, 49, 45, 36, 56,
+ 7, 48, 35, 6, 34, 33, 0
+ };
+ return Mod67Position[(-Value & Value) % 67];
+#endif
+}
+
+/// CountPopulation_32 - this function counts the number of set bits in a value.
+/// Ex. CountPopulation(0xF000F000) = 8
+/// Returns 0 if the word is zero.
+inline unsigned CountPopulation_32(uint32_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcount(Value);
+#else
+ uint32_t v = Value - ((Value >> 1) & 0x55555555);
+ v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
+ return ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
+#endif
+}
+
+/// CountPopulation_64 - this function counts the number of set bits in a value,
+/// (64 bit edition.)
+inline unsigned CountPopulation_64(uint64_t Value) {
+#if __GNUC__ >= 4
+ return __builtin_popcountll(Value);
+#else
+ uint64_t v = Value - ((Value >> 1) & 0x5555555555555555ULL);
+ v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
+ v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
+ return unsigned((uint64_t)(v * 0x0101010101010101ULL) >> 56);
+#endif
+}
+
+/// Log2_32 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (32 bit edition.)
+/// Ex. Log2_32(32) == 5, Log2_32(1) == 0, Log2_32(0) == -1, Log2_32(6) == 2
+inline unsigned Log2_32(uint32_t Value) {
+ return 31 - CountLeadingZeros_32(Value);
+}
+
+/// Log2_64 - This function returns the floor log base 2 of the specified value,
+/// -1 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64(uint64_t Value) {
+ return 63 - CountLeadingZeros_64(Value);
+}
+
+/// Log2_32_Ceil - This function returns the ceil log base 2 of the specified
+/// value, 32 if the value is zero. (32 bit edition).
+/// Ex. Log2_32_Ceil(32) == 5, Log2_32_Ceil(1) == 0, Log2_32_Ceil(6) == 3
+inline unsigned Log2_32_Ceil(uint32_t Value) {
+ return 32-CountLeadingZeros_32(Value-1);
+}
+
+/// Log2_64 - This function returns the ceil log base 2 of the specified value,
+/// 64 if the value is zero. (64 bit edition.)
+inline unsigned Log2_64_Ceil(uint64_t Value) {
+ return 64-CountLeadingZeros_64(Value-1);
+}
+
+/// GreatestCommonDivisor64 - Return the greatest common divisor of the two
+/// values using Euclid's algorithm.
+inline uint64_t GreatestCommonDivisor64(uint64_t A, uint64_t B) {
+ while (B) {
+ uint64_t T = B;
+ B = A % B;
+ A = T;
+ }
+ return A;
+}
+
+/// BitsToDouble - This function takes a 64-bit integer and returns the bit
+/// equivalent double.
+inline double BitsToDouble(uint64_t Bits) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.L = Bits;
+ return T.D;
+}
+
+/// BitsToFloat - This function takes a 32-bit integer and returns the bit
+/// equivalent float.
+inline float BitsToFloat(uint32_t Bits) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.I = Bits;
+ return T.F;
+}
+
+/// DoubleToBits - This function takes a double and returns the bit
+/// equivalent 64-bit integer.
+inline uint64_t DoubleToBits(double Double) {
+ union {
+ uint64_t L;
+ double D;
+ } T;
+ T.D = Double;
+ return T.L;
+}
+
+/// FloatToBits - This function takes a float and returns the bit
+/// equivalent 32-bit integer.
+inline uint32_t FloatToBits(float Float) {
+ union {
+ uint32_t I;
+ float F;
+ } T;
+ T.F = 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);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/MemoryBuffer.h b/include/llvm/Support/MemoryBuffer.h
new file mode 100644
index 0000000..d7e0317
--- /dev/null
+++ b/include/llvm/Support/MemoryBuffer.h
@@ -0,0 +1,106 @@
+//===--- MemoryBuffer.h - Memory Buffer Interface ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MemoryBuffer interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MEMORYBUFFER_H
+#define LLVM_SUPPORT_MEMORYBUFFER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+
+/// MemoryBuffer - This interface provides simple read-only access to a block
+/// of memory, and provides simple methods for reading files and standard input
+/// into a memory buffer. In addition to basic access to the characters in the
+/// file, this interface guarantees you can read one character past the end of
+/// the file, and that this character will read as '\0'.
+class MemoryBuffer {
+ const char *BufferStart; // Start of the buffer.
+ const char *BufferEnd; // End of the buffer.
+
+ /// MustDeleteBuffer - True if we allocated this buffer. If so, the
+ /// destructor must know the delete[] it.
+ bool MustDeleteBuffer;
+protected:
+ MemoryBuffer() : MustDeleteBuffer(false) {}
+ void init(const char *BufStart, const char *BufEnd);
+ void initCopyOf(const char *BufStart, const char *BufEnd);
+public:
+ virtual ~MemoryBuffer();
+
+ const char *getBufferStart() const { return BufferStart; }
+ const char *getBufferEnd() const { return BufferEnd; }
+ unsigned getBufferSize() const { return BufferEnd-BufferStart; }
+
+ /// getBufferIdentifier - Return an identifier for this buffer, typically the
+ /// filename it was read from.
+ virtual const char *getBufferIdentifier() const {
+ return "Unknown buffer";
+ }
+
+ /// getFile - Open the specified file as a MemoryBuffer, returning a new
+ /// MemoryBuffer if successful, otherwise returning null. If FileSize is
+ /// specified, this means that the client knows that the file exists and that
+ /// it has the specified size.
+ static MemoryBuffer *getFile(const char *FilenameStart, unsigned FnSize,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1);
+
+ /// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
+ /// that EndPtr[0] must be a null byte and be accessible!
+ static MemoryBuffer *getMemBuffer(const char *StartPtr, const char *EndPtr,
+ const char *BufferName = "");
+
+ /// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
+ /// is completely initialized to zeros. Note that the caller should
+ /// initialize the memory allocated by this method. The memory is owned by
+ /// the MemoryBuffer object.
+ static MemoryBuffer *getNewMemBuffer(unsigned Size,
+ const char *BufferName = "");
+
+ /// getNewUninitMemBuffer - Allocate a new MemoryBuffer of the specified size
+ /// that is not initialized. Note that the caller should initialize the
+ /// memory allocated by this method. The memory is owned by the MemoryBuffer
+ /// object.
+ static MemoryBuffer *getNewUninitMemBuffer(unsigned Size,
+ const char *BufferName = "");
+
+ /// getSTDIN - Read all of stdin into a file buffer, and return it. This
+ /// fails if stdin is empty.
+ static MemoryBuffer *getSTDIN();
+
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason.
+ static MemoryBuffer *getFileOrSTDIN(const char *FilenameStart,unsigned FnSize,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1) {
+ if (FnSize == 1 && FilenameStart[0] == '-')
+ return getSTDIN();
+ return getFile(FilenameStart, FnSize, ErrStr, FileSize);
+ }
+
+ /// getFileOrSTDIN - Open the specified file as a MemoryBuffer, or open stdin
+ /// if the Filename is "-". If an error occurs, this returns null and fills
+ /// in *ErrStr with a reason.
+ static MemoryBuffer *getFileOrSTDIN(const std::string &FN,
+ std::string *ErrStr = 0,
+ int64_t FileSize = -1) {
+ return getFileOrSTDIN(&FN[0], FN.size(), ErrStr, FileSize);
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/llvm/Support/MutexGuard.h b/include/llvm/Support/MutexGuard.h
new file mode 100644
index 0000000..21c756d
--- /dev/null
+++ b/include/llvm/Support/MutexGuard.h
@@ -0,0 +1,41 @@
+//===-- Support/MutexGuard.h - Acquire/Release Mutex In Scope ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a guard for a block of code that ensures a Mutex is locked
+// upon construction and released upon destruction.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_MUTEXGUARD_H
+#define LLVM_SUPPORT_MUTEXGUARD_H
+
+#include <llvm/System/Mutex.h>
+
+namespace llvm {
+ /// Instances of this class acquire a given Mutex Lock when constructed and
+ /// hold that lock until destruction. The intention is to instantiate one of
+ /// these on the stack at the top of some scope to be assured that C++
+ /// destruction of the object will always release the Mutex and thus avoid
+ /// a host of nasty multi-threading problems in the face of exceptions, etc.
+ /// @brief Guard a section of code with a Mutex.
+ class MutexGuard {
+ sys::Mutex &M;
+ MutexGuard(const MutexGuard &); // DO NOT IMPLEMENT
+ void operator=(const MutexGuard &); // DO NOT IMPLEMENT
+ public:
+ MutexGuard(sys::Mutex &m) : M(m) { M.acquire(); }
+ ~MutexGuard() { M.release(); }
+ /// holds - Returns true if this locker instance holds the specified lock.
+ /// This is mostly used in assertions to validate that the correct mutex
+ /// is held.
+ bool holds(const sys::Mutex& lock) const { return &M == &lock; }
+ };
+}
+
+#endif // LLVM_SUPPORT_MUTEXGUARD_H
diff --git a/include/llvm/Support/OutputBuffer.h b/include/llvm/Support/OutputBuffer.h
new file mode 100644
index 0000000..9c6456a
--- /dev/null
+++ b/include/llvm/Support/OutputBuffer.h
@@ -0,0 +1,152 @@
+//=== OutputBuffer.h - Output Buffer ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Methods to output values to a data buffer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_OUTPUTBUFFER_H
+#define LLVM_SUPPORT_OUTPUTBUFFER_H
+
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+ class OutputBuffer {
+ /// Output buffer.
+ std::vector<unsigned char> &Output;
+
+ /// is64Bit/isLittleEndian - This information is inferred from the target
+ /// machine directly, indicating what header values and flags to set.
+ bool is64Bit, isLittleEndian;
+ public:
+ OutputBuffer(std::vector<unsigned char> &Out,
+ bool is64bit, bool le)
+ : Output(Out), is64Bit(is64bit), isLittleEndian(le) {}
+
+ // align - Emit padding into the file until the current output position is
+ // aligned to the specified power of two boundary.
+ void align(unsigned Boundary) {
+ assert(Boundary && (Boundary & (Boundary - 1)) == 0 &&
+ "Must align to 2^k boundary");
+ size_t Size = Output.size();
+
+ if (Size & (Boundary - 1)) {
+ // Add padding to get alignment to the correct place.
+ size_t Pad = Boundary - (Size & (Boundary - 1));
+ Output.resize(Size + Pad);
+ }
+ }
+
+ //===------------------------------------------------------------------===//
+ // Out Functions - Output the specified value to the data buffer.
+
+ void outbyte(unsigned char X) {
+ Output.push_back(X);
+ }
+ void outhalf(unsigned short X) {
+ if (isLittleEndian) {
+ Output.push_back(X & 255);
+ Output.push_back(X >> 8);
+ } else {
+ Output.push_back(X >> 8);
+ Output.push_back(X & 255);
+ }
+ }
+ void outword(unsigned X) {
+ if (isLittleEndian) {
+ Output.push_back((X >> 0) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 24) & 255);
+ } else {
+ Output.push_back((X >> 24) & 255);
+ Output.push_back((X >> 16) & 255);
+ Output.push_back((X >> 8) & 255);
+ Output.push_back((X >> 0) & 255);
+ }
+ }
+ void outxword(uint64_t X) {
+ if (isLittleEndian) {
+ Output.push_back(unsigned(X >> 0) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 56) & 255);
+ } else {
+ Output.push_back(unsigned(X >> 56) & 255);
+ Output.push_back(unsigned(X >> 48) & 255);
+ Output.push_back(unsigned(X >> 40) & 255);
+ Output.push_back(unsigned(X >> 32) & 255);
+ Output.push_back(unsigned(X >> 24) & 255);
+ Output.push_back(unsigned(X >> 16) & 255);
+ Output.push_back(unsigned(X >> 8) & 255);
+ Output.push_back(unsigned(X >> 0) & 255);
+ }
+ }
+ void outaddr32(unsigned X) {
+ outword(X);
+ }
+ void outaddr64(uint64_t X) {
+ outxword(X);
+ }
+ void outaddr(uint64_t X) {
+ if (!is64Bit)
+ outword((unsigned)X);
+ else
+ outxword(X);
+ }
+ void outstring(const std::string &S, unsigned Length) {
+ unsigned len_to_copy = S.length() < Length ? S.length() : Length;
+ unsigned len_to_fill = S.length() < Length ? Length - S.length() : 0;
+
+ for (unsigned i = 0; i < len_to_copy; ++i)
+ outbyte(S[i]);
+
+ for (unsigned i = 0; i < len_to_fill; ++i)
+ outbyte(0);
+ }
+
+ //===------------------------------------------------------------------===//
+ // Fix Functions - Replace an existing entry at an offset.
+
+ void fixhalf(unsigned short X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 8)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 0)) & 255;
+ }
+ void fixword(unsigned X, unsigned Offset) {
+ unsigned char *P = &Output[Offset];
+ P[0] = (X >> (isLittleEndian ? 0 : 24)) & 255;
+ P[1] = (X >> (isLittleEndian ? 8 : 16)) & 255;
+ P[2] = (X >> (isLittleEndian ? 16 : 8)) & 255;
+ P[3] = (X >> (isLittleEndian ? 24 : 0)) & 255;
+ }
+ void fixaddr(uint64_t X, unsigned Offset) {
+ if (!is64Bit)
+ fixword((unsigned)X, Offset);
+ else
+ assert(0 && "Emission of 64-bit data not implemented yet!");
+ }
+
+ unsigned char &operator[](unsigned Index) {
+ return Output[Index];
+ }
+ const unsigned char &operator[](unsigned Index) const {
+ return Output[Index];
+ }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_SUPPORT_OUTPUTBUFFER_H
diff --git a/include/llvm/Support/PassNameParser.h b/include/llvm/Support/PassNameParser.h
new file mode 100644
index 0000000..e87e16a
--- /dev/null
+++ b/include/llvm/Support/PassNameParser.h
@@ -0,0 +1,94 @@
+//===- llvm/Support/PassNameParser.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file the PassNameParser and FilteredPassNameParser<> classes, which are
+// used to add command line arguments to a utility for all of the passes that
+// have been registered into the system.
+//
+// The PassNameParser class adds ALL passes linked into the system (that are
+// creatable) as command line arguments to the tool (when instantiated with the
+// appropriate command line option template). The FilteredPassNameParser<>
+// template is used for the same purposes as PassNameParser, except that it only
+// includes passes that have a PassType that are compatible with the filter
+// (which is the template argument).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PASS_NAME_PARSER_H
+#define LLVM_SUPPORT_PASS_NAME_PARSER_H
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Pass.h"
+#include <algorithm>
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// PassNameParser class - Make use of the pass registration mechanism to
+// automatically add a command line argument to opt for each pass.
+//
+class PassNameParser : public PassRegistrationListener,
+ public cl::parser<const PassInfo*> {
+ cl::Option *Opt;
+public:
+ PassNameParser() : Opt(0) {}
+
+ void initialize(cl::Option &O) {
+ Opt = &O;
+ cl::parser<const PassInfo*>::initialize(O);
+
+ // Add all of the passes to the map that got initialized before 'this' did.
+ enumeratePasses();
+ }
+
+ // ignorablePassImpl - Can be overriden in subclasses to refine the list of
+ // which passes we want to include.
+ //
+ virtual bool ignorablePassImpl(const PassInfo *P) const { return false; }
+
+ inline bool ignorablePass(const PassInfo *P) const {
+ // Ignore non-selectable and non-constructible passes! Ignore
+ // non-optimizations.
+ return P->getPassArgument() == 0 || *P->getPassArgument() == 0 ||
+ P->getNormalCtor() == 0 || ignorablePassImpl(P);
+ }
+
+ // Implement the PassRegistrationListener callbacks used to populate our map
+ //
+ virtual void passRegistered(const PassInfo *P) {
+ if (ignorablePass(P) || !Opt) return;
+ if (findOption(P->getPassArgument()) != getNumOptions()) {
+ cerr << "Two passes with the same argument (-"
+ << P->getPassArgument() << ") attempted to be registered!\n";
+ abort();
+ }
+ addLiteralOption(P->getPassArgument(), P, P->getPassName());
+ }
+ virtual void passEnumerate(const PassInfo *P) { passRegistered(P); }
+
+ // ValLessThan - Provide a sorting comparator for Values elements...
+ typedef std::pair<const char*,
+ std::pair<const PassInfo*, const char*> > ValType;
+ static bool ValLessThan(const ValType &VT1, const ValType &VT2) {
+ return std::string(VT1.first) < std::string(VT2.first);
+ }
+
+ // printOptionInfo - Print out information about this option. Override the
+ // default implementation to sort the table before we print...
+ virtual void printOptionInfo(const cl::Option &O, unsigned GlobalWidth) const{
+ PassNameParser *PNP = const_cast<PassNameParser*>(this);
+ std::sort(PNP->Values.begin(), PNP->Values.end(), ValLessThan);
+ cl::parser<const PassInfo*>::printOptionInfo(O, GlobalWidth);
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/PatternMatch.h b/include/llvm/Support/PatternMatch.h
new file mode 100644
index 0000000..6b295d6
--- /dev/null
+++ b/include/llvm/Support/PatternMatch.h
@@ -0,0 +1,382 @@
+//===-- llvm/Support/PatternMatch.h - Match on the LLVM IR ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a simple and efficient mechanism for performing general
+// tree-based pattern matches on the LLVM IR. The power of these routines is
+// that it allows you to write concise patterns that are expressive and easy to
+// understand. The other major advantage of this is that it allows you to
+// trivially capture/bind elements in the pattern to variables. For example,
+// you can do something like this:
+//
+// Value *Exp = ...
+// Value *X, *Y; ConstantInt *C1, *C2; // (X & C1) | (Y & C2)
+// if (match(Exp, m_Or(m_And(m_Value(X), m_ConstantInt(C1)),
+// m_And(m_Value(Y), m_ConstantInt(C2))))) {
+// ... Pattern is matched and variables are bound ...
+// }
+//
+// This is primarily useful to things like the instruction combiner, but can
+// also be useful for static analysis tools or code generators.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PATTERNMATCH_H
+#define LLVM_SUPPORT_PATTERNMATCH_H
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+namespace llvm {
+namespace PatternMatch {
+
+template<typename Val, typename Pattern>
+bool match(Val *V, const Pattern &P) {
+ return const_cast<Pattern&>(P).match(V);
+}
+
+template<typename Class>
+struct leaf_ty {
+ template<typename ITy>
+ bool match(ITy *V) { return isa<Class>(V); }
+};
+
+inline leaf_ty<Value> m_Value() { return leaf_ty<Value>(); }
+inline leaf_ty<ConstantInt> m_ConstantInt() { return leaf_ty<ConstantInt>(); }
+
+template<typename Class>
+struct bind_ty {
+ Class *&VR;
+ bind_ty(Class *&V) : VR(V) {}
+
+ template<typename ITy>
+ bool match(ITy *V) {
+ if (Class *CV = dyn_cast<Class>(V)) {
+ VR = CV;
+ return true;
+ }
+ return false;
+ }
+};
+
+inline bind_ty<Value> m_Value(Value *&V) { return V; }
+inline bind_ty<ConstantInt> m_ConstantInt(ConstantInt *&CI) { return CI; }
+
+//===----------------------------------------------------------------------===//
+// Matchers for specific binary operators.
+//
+
+template<typename LHS_t, typename RHS_t,
+ unsigned Opcode, typename ConcreteTy = BinaryOperator>
+struct BinaryOp_match {
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOp_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Opcode) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return I->getOpcode() == Opcode && L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Add> m_Add(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Add>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Sub> m_Sub(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Sub>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Mul> m_Mul(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Mul>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::UDiv> m_UDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::UDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SDiv> m_SDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FDiv> m_FDiv(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FDiv>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::URem> m_URem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::URem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::SRem> m_SRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::SRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::FRem> m_FRem(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::FRem>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::And> m_And(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::And>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Or> m_Or(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Or>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Xor> m_Xor(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Xor>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::Shl> m_Shl(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::Shl>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::LShr> m_LShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::LShr>(L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOp_match<LHS, RHS, Instruction::AShr> m_AShr(const LHS &L,
+ const RHS &R) {
+ return BinaryOp_match<LHS, RHS, Instruction::AShr>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for either AShr or LShr .. for convenience
+//
+template<typename LHS_t, typename RHS_t, typename ConcreteTy = BinaryOperator>
+struct Shr_match {
+ LHS_t L;
+ RHS_t R;
+
+ Shr_match(const LHS_t &LHS, const RHS_t &RHS) : L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (V->getValueID() == Value::InstructionVal + Instruction::LShr ||
+ V->getValueID() == Value::InstructionVal + Instruction::AShr) {
+ ConcreteTy *I = cast<ConcreteTy>(V);
+ return (I->getOpcode() == Instruction::AShr ||
+ I->getOpcode() == Instruction::LShr) &&
+ L.match(I->getOperand(0)) &&
+ R.match(I->getOperand(1));
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return (CE->getOpcode() == Instruction::LShr ||
+ CE->getOpcode() == Instruction::AShr) &&
+ L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline Shr_match<LHS, RHS> m_Shr(const LHS &L, const RHS &R) {
+ return Shr_match<LHS, RHS>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for binary classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename OpcType>
+struct BinaryOpClass_match {
+ OpcType *Opcode;
+ LHS_t L;
+ RHS_t R;
+
+ BinaryOpClass_match(OpcType &Op, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Opcode(&Op), L(LHS), R(RHS) {}
+ BinaryOpClass_match(const LHS_t &LHS, const RHS_t &RHS)
+ : Opcode(0), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ if (Opcode)
+ *Opcode = I->getOpcode();
+ return true;
+ }
+#if 0 // Doesn't handle constantexprs yet!
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ return CE->getOpcode() == Opcode && L.match(CE->getOperand(0)) &&
+ R.match(CE->getOperand(1));
+#endif
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(Instruction::BinaryOps &Op, const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(Op, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline BinaryOpClass_match<LHS, RHS, BinaryOperator, Instruction::BinaryOps>
+m_Shift(const LHS &L, const RHS &R) {
+ return BinaryOpClass_match<LHS, RHS,
+ BinaryOperator, Instruction::BinaryOps>(L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for CmpInst classes
+//
+
+template<typename LHS_t, typename RHS_t, typename Class, typename PredicateTy>
+struct CmpClass_match {
+ PredicateTy &Predicate;
+ LHS_t L;
+ RHS_t R;
+
+ CmpClass_match(PredicateTy &Pred, const LHS_t &LHS,
+ const RHS_t &RHS)
+ : Predicate(Pred), L(LHS), R(RHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Class *I = dyn_cast<Class>(V))
+ if (L.match(I->getOperand(0)) && R.match(I->getOperand(1))) {
+ Predicate = I->getPredicate();
+ return true;
+ }
+ return false;
+ }
+};
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, ICmpInst, ICmpInst::Predicate>
+m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ ICmpInst, ICmpInst::Predicate>(Pred, L, R);
+}
+
+template<typename LHS, typename RHS>
+inline CmpClass_match<LHS, RHS, FCmpInst, FCmpInst::Predicate>
+m_FCmp(FCmpInst::Predicate &Pred, const LHS &L, const RHS &R) {
+ return CmpClass_match<LHS, RHS,
+ FCmpInst, FCmpInst::Predicate>(Pred, L, R);
+}
+
+//===----------------------------------------------------------------------===//
+// Matchers for unary operators
+//
+
+template<typename LHS_t>
+struct not_match {
+ LHS_t L;
+
+ not_match(const LHS_t &LHS) : L(LHS) {}
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ if (I->getOpcode() == Instruction::Xor)
+ return matchIfNot(I->getOperand(0), I->getOperand(1));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::Xor)
+ return matchIfNot(CE->getOperand(0), CE->getOperand(1));
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return L.match(ConstantExpr::getNot(CI));
+ return false;
+ }
+private:
+ bool matchIfNot(Value *LHS, Value *RHS) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
+ return CI->isAllOnesValue() && L.match(LHS);
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(LHS))
+ return CI->isAllOnesValue() && L.match(RHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(RHS))
+ return CV->isAllOnesValue() && L.match(LHS);
+ if (ConstantVector *CV = dyn_cast<ConstantVector>(LHS))
+ return CV->isAllOnesValue() && L.match(RHS);
+ return false;
+ }
+};
+
+template<typename LHS>
+inline not_match<LHS> m_Not(const LHS &L) { return L; }
+
+
+//===----------------------------------------------------------------------===//
+// Matchers for control flow
+//
+
+template<typename Cond_t>
+struct brc_match {
+ Cond_t Cond;
+ BasicBlock *&T, *&F;
+ brc_match(const Cond_t &C, BasicBlock *&t, BasicBlock *&f)
+ : Cond(C), T(t), F(f) {
+ }
+
+ template<typename OpTy>
+ bool match(OpTy *V) {
+ if (BranchInst *BI = dyn_cast<BranchInst>(V))
+ if (BI->isConditional()) {
+ if (Cond.match(BI->getCondition())) {
+ T = BI->getSuccessor(0);
+ F = BI->getSuccessor(1);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+template<typename Cond_t>
+inline brc_match<Cond_t> m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F){
+ return brc_match<Cond_t>(C, T, F);
+}
+
+
+}} // end llvm::match
+
+
+#endif
+
diff --git a/include/llvm/Support/PluginLoader.h b/include/llvm/Support/PluginLoader.h
new file mode 100644
index 0000000..7789ae8
--- /dev/null
+++ b/include/llvm/Support/PluginLoader.h
@@ -0,0 +1,37 @@
+//===-- llvm/Support/PluginLoader.h - Plugin Loader for Tools ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A tool can #include this file to get a -load option that allows the user to
+// load arbitrary shared objects into the tool's address space. Note that this
+// header can only be included by a program ONCE, so it should never to used by
+// library authors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PLUGINLOADER_H
+#define LLVM_SUPPORT_PLUGINLOADER_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ struct PluginLoader {
+ void operator=(const std::string &Filename);
+ static unsigned getNumPlugins();
+ static std::string& getPlugin(unsigned num);
+ };
+
+#ifndef DONT_GET_PLUGIN_LOADER_OPTION
+ // This causes operator= above to be invoked for every -load option.
+ static cl::opt<PluginLoader, false, cl::parser<std::string> >
+ LoadOpt("load", cl::ZeroOrMore, cl::value_desc("pluginfilename"),
+ cl::desc("Load the specified plugin"));
+#endif
+}
+
+#endif
diff --git a/include/llvm/Support/SlowOperationInformer.h b/include/llvm/Support/SlowOperationInformer.h
new file mode 100644
index 0000000..d057926
--- /dev/null
+++ b/include/llvm/Support/SlowOperationInformer.h
@@ -0,0 +1,65 @@
+//===- llvm/Support/SlowOperationInformer.h - Keep user informed *- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple object which can be used to let the user know what
+// is going on when a slow operation is happening, and gives them the ability to
+// cancel it. Potentially slow operations can stack allocate one of these
+// objects, and periodically call the "progress" method to update the progress
+// bar. If the operation takes more than 1 second to complete, the progress bar
+// is automatically shown and updated. As such, the slow operation should not
+// print stuff to the screen, and should not be confused if an extra line
+// appears on the screen (ie, the cursor should be at the start of the line).
+//
+// If the user presses CTRL-C during the operation, the next invocation of the
+// progress method return true indicating that the operation was cancelled.
+//
+// Because SlowOperationInformers fiddle around with signals, they cannot be
+// nested, and interact poorly with threads. The SIGALRM handler is set back to
+// SIGDFL, but the SIGINT signal handler is restored when the
+// SlowOperationInformer is destroyed.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+#define LLVM_SUPPORT_SLOW_OPERATION_INFORMER_H
+
+#include <string>
+#include <cassert>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class SlowOperationInformer {
+ std::string OperationName;
+ unsigned LastPrintAmount;
+
+ SlowOperationInformer(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ void operator=(const SlowOperationInformer&); // DO NOT IMPLEMENT
+ public:
+ SlowOperationInformer(const std::string &Name);
+ ~SlowOperationInformer();
+
+ /// progress - Clients should periodically call this method when they can
+ /// handle cancellation. The Amount variable should indicate how far
+ /// along the operation is, given in 1/10ths of a percent (in other words,
+ /// Amount should range from 0 to 1000). If the user cancels the operation,
+ /// this returns true, false otherwise.
+ bool progress(unsigned Amount);
+
+ /// progress - Same as the method above, but this performs the division for
+ /// you, and helps you avoid overflow if you are dealing with largish
+ /// numbers.
+ bool progress(unsigned Current, unsigned Maximum) {
+ assert(Maximum != 0 &&
+ "Shouldn't be doing work if there is nothing to do!");
+ return progress(Current*uint64_t(1000UL)/Maximum);
+ }
+ };
+} // end namespace llvm
+
+#endif /* SLOW_OPERATION_INFORMER_H */
diff --git a/include/llvm/Support/StableBasicBlockNumbering.h b/include/llvm/Support/StableBasicBlockNumbering.h
new file mode 100644
index 0000000..3ba72ea
--- /dev/null
+++ b/include/llvm/Support/StableBasicBlockNumbering.h
@@ -0,0 +1,59 @@
+//===- StableBasicBlockNumbering.h - Provide BB identifiers -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class provides a *stable* numbering of basic blocks that does not depend
+// on their address in memory (which is nondeterministic). When requested, this
+// class simply provides a unique ID for each basic block in the function
+// specified and the inverse mapping.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+#define LLVM_SUPPORT_STABLEBASICBLOCKNUMBERING_H
+
+#include "llvm/Function.h"
+#include "llvm/ADT/UniqueVector.h"
+
+namespace llvm {
+ class StableBasicBlockNumbering {
+ // BBNumbering - Holds the numbering.
+ UniqueVector<BasicBlock*> BBNumbering;
+ public:
+ StableBasicBlockNumbering(Function *F = 0) {
+ if (F) compute(*F);
+ }
+
+ /// compute - If we have not computed a numbering for the function yet, do
+ /// so.
+ void compute(Function &F) {
+ if (BBNumbering.empty()) {
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ BBNumbering.insert(I);
+ }
+ }
+
+ /// getNumber - Return the ID number for the specified BasicBlock.
+ ///
+ unsigned getNumber(BasicBlock *BB) const {
+ unsigned Idx = BBNumbering.idFor(BB);
+ assert(Idx && "Invalid basic block or numbering not computed!");
+ return Idx-1;
+ }
+
+ /// getBlock - Return the BasicBlock corresponding to a particular ID.
+ ///
+ BasicBlock *getBlock(unsigned N) const {
+ assert(N < BBNumbering.size() &&
+ "Block ID out of range or numbering not computed!");
+ return BBNumbering[N+1];
+ }
+ };
+}
+
+#endif
diff --git a/include/llvm/Support/Streams.h b/include/llvm/Support/Streams.h
new file mode 100644
index 0000000..4e1e4f3
--- /dev/null
+++ b/include/llvm/Support/Streams.h
@@ -0,0 +1,72 @@
+//===- llvm/Support/Streams.h - Wrappers for iostreams ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a wrapper for the STL I/O streams. It prevents the need
+// to include <iostream> in a file just to get I/O.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_STREAMS_H
+#define LLVM_SUPPORT_STREAMS_H
+
+#include <iosfwd>
+
+namespace llvm {
+
+ /// BaseStream - Acts like the STL streams. It's a wrapper for the std::cerr,
+ /// std::cout, std::cin, etc. streams. However, it doesn't require #including
+ /// <iostream> in every file (doing so increases static c'tors & d'tors in the
+ /// object code).
+ ///
+ template <typename StreamTy>
+ class BaseStream {
+ StreamTy *Stream;
+ public:
+ BaseStream() : Stream(0) {}
+ BaseStream(StreamTy &S) : Stream(&S) {}
+ BaseStream(StreamTy *S) : Stream(S) {}
+
+ StreamTy *stream() const { return Stream; }
+
+ inline BaseStream &operator << (StreamTy &(*Func)(StreamTy&)) {
+ if (Stream) *Stream << Func;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &operator << (const Ty &Thing) {
+ if (Stream) *Stream << Thing;
+ return *this;
+ }
+
+ template <typename Ty>
+ BaseStream &operator >> (const Ty &Thing) {
+ if (Stream) *Stream >> Thing;
+ return *this;
+ }
+
+ operator StreamTy* () { return Stream; }
+
+ bool operator == (const StreamTy &S) { return &S == Stream; }
+ bool operator != (const StreamTy &S) { return !(*this == S); }
+ bool operator == (const BaseStream &S) { return S.Stream == Stream; }
+ bool operator != (const BaseStream &S) { return !(*this == S); }
+ };
+
+ typedef BaseStream<std::ostream> OStream;
+ typedef BaseStream<std::istream> IStream;
+ typedef BaseStream<std::stringstream> StringStream;
+
+ extern OStream cout;
+ extern OStream cerr;
+ extern IStream cin;
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/SystemUtils.h b/include/llvm/Support/SystemUtils.h
new file mode 100644
index 0000000..6dc5c27
--- /dev/null
+++ b/include/llvm/Support/SystemUtils.h
@@ -0,0 +1,42 @@
+//===- SystemUtils.h - Utilities to do low-level system stuff ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains functions used to do a variety of low-level, often
+// system-specific, tasks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_SYSTEMUTILS_H
+#define LLVM_SUPPORT_SYSTEMUTILS_H
+
+#include "llvm/System/Program.h"
+
+namespace llvm {
+
+/// Determine if the ostream provided is connected to the std::cout and
+/// displayed or not (to a console window). If so, generate a warning message
+/// advising against display of bitcode and return true. Otherwise just return
+/// false
+/// @brief Check for output written to a console
+bool CheckBitcodeOutputToConsole(
+ std::ostream* stream_to_check, ///< The stream to be checked
+ bool print_warning = true ///< Control whether warnings are printed
+);
+
+/// FindExecutable - Find a named executable, giving the argv[0] of program
+/// being executed. This allows us to find another LLVM tool if it is built into
+/// the same directory, but that directory is neither the current directory, nor
+/// in the PATH. If the executable cannot be found, return an empty string.
+/// @brief Find a named executable.
+sys::Path FindExecutable(const std::string &ExeName,
+ const std::string &ProgramPath);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/Timer.h b/include/llvm/Support/Timer.h
new file mode 100644
index 0000000..5a97f49
--- /dev/null
+++ b/include/llvm/Support/Timer.h
@@ -0,0 +1,165 @@
+//===-- llvm/Support/Timer.h - Interval Timing Support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines three classes: Timer, TimeRegion, and TimerGroup,
+// documented below.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TIMER_H
+#define LLVM_SUPPORT_TIMER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include <cassert>
+
+namespace llvm {
+
+class TimerGroup;
+
+/// Timer - This class is used to track the amount of time spent between
+/// invocations of it's startTimer()/stopTimer() methods. Given appropriate OS
+/// support it can also keep track of the RSS of the program at various points.
+/// By default, the Timer will print the amount of time it has captured to
+/// standard error when the laster timer is destroyed, otherwise it is printed
+/// when it's TimerGroup is destroyed. Timer's do not print their information
+/// if they are never started.
+///
+class Timer {
+ double Elapsed; // Wall clock time elapsed in seconds
+ double UserTime; // User time elapsed
+ double SystemTime; // System time elapsed
+ ssize_t MemUsed; // Memory allocated (in bytes)
+ size_t PeakMem; // Peak memory used
+ size_t PeakMemBase; // Temporary for peak calculation...
+ std::string Name; // The name of this time variable
+ bool Started; // Has this time variable ever been started?
+ TimerGroup *TG; // The TimerGroup this Timer is in.
+public:
+ Timer(const std::string &N);
+ Timer(const std::string &N, TimerGroup &tg);
+ Timer(const Timer &T);
+ ~Timer();
+
+ double getProcessTime() const { return UserTime+SystemTime; }
+ double getWallTime() const { return Elapsed; }
+ ssize_t getMemUsed() const { return MemUsed; }
+ size_t getPeakMem() const { return PeakMem; }
+ std::string getName() const { return Name; }
+
+ const Timer &operator=(const Timer &T) {
+ Elapsed = T.Elapsed;
+ UserTime = T.UserTime;
+ SystemTime = T.SystemTime;
+ MemUsed = T.MemUsed;
+ PeakMem = T.PeakMem;
+ PeakMemBase = T.PeakMemBase;
+ Name = T.Name;
+ Started = T.Started;
+ assert(TG == T.TG && "Can only assign timers in the same TimerGroup!");
+ return *this;
+ }
+
+ // operator< - Allow sorting...
+ bool operator<(const Timer &T) const {
+ // Sort by Wall Time elapsed, as it is the only thing really accurate
+ return Elapsed < T.Elapsed;
+ }
+ bool operator>(const Timer &T) const { return T.operator<(*this); }
+
+ /// startTimer - Start the timer running. Time between calls to
+ /// startTimer/stopTimer is counted by the Timer class. Note that these calls
+ /// must be correctly paired.
+ ///
+ void startTimer();
+
+ /// stopTimer - Stop the timer.
+ ///
+ void stopTimer();
+
+ /// addPeakMemoryMeasurement - This method should be called whenever memory
+ /// usage needs to be checked. It adds a peak memory measurement to the
+ /// currently active timers, which will be printed when the timer group prints
+ ///
+ static void addPeakMemoryMeasurement();
+
+ /// print - Print the current timer to standard error, and reset the "Started"
+ /// flag.
+ void print(const Timer &Total, std::ostream &OS);
+
+private:
+ friend class TimerGroup;
+
+ // Copy ctor, initialize with no TG member.
+ Timer(bool, const Timer &T);
+
+ /// sum - Add the time accumulated in the specified timer into this timer.
+ ///
+ void sum(const Timer &T);
+};
+
+
+/// The TimeRegion class is used as a helper class to call the startTimer() and
+/// stopTimer() methods of the Timer class. When the object is constructed, it
+/// starts the timer specified as it's argument. When it is destroyed, it stops
+/// the relevant timer. This makes it easy to time a region of code.
+///
+class TimeRegion {
+ Timer &T;
+ TimeRegion(const TimeRegion &); // DO NOT IMPLEMENT
+public:
+ TimeRegion(Timer &t) : T(t) {
+ T.startTimer();
+ }
+ ~TimeRegion() {
+ T.stopTimer();
+ }
+};
+
+
+/// NamedRegionTimer - This class is basically a combination of TimeRegion and
+/// Timer. It allows you to declare a new timer, AND specify the region to
+/// time, all in one statement. All timers with the same name are merged. This
+/// is primarily used for debugging and for hunting performance problems.
+///
+struct NamedRegionTimer : public TimeRegion {
+ NamedRegionTimer(const std::string &Name);
+};
+
+
+/// The TimerGroup class is used to group together related timers into a single
+/// report that is printed when the TimerGroup is destroyed. It is illegal to
+/// destroy a TimerGroup object before all of the Timers in it are gone. A
+/// TimerGroup can be specified for a newly created timer in its constructor.
+///
+class TimerGroup {
+ std::string Name;
+ unsigned NumTimers;
+ std::vector<Timer> TimersToPrint;
+public:
+ TimerGroup(const std::string &name) : Name(name), NumTimers(0) {}
+ ~TimerGroup() {
+ assert(NumTimers == 0 &&
+ "TimerGroup destroyed before all contained timers!");
+ }
+
+private:
+ friend class Timer;
+ void addTimer() { ++NumTimers; }
+ void removeTimer();
+ void addTimerToPrint(const Timer &T) {
+ TimersToPrint.push_back(Timer(true, T));
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/TypeInfo.h b/include/llvm/Support/TypeInfo.h
new file mode 100644
index 0000000..0dfa583
--- /dev/null
+++ b/include/llvm/Support/TypeInfo.h
@@ -0,0 +1,76 @@
+//===- llvm/Support/TypeInfo.h - Support for type_info objects -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class makes std::type_info objects behave like first class objects that
+// can be put in maps and hashtables. This code is based off of code in the
+// Loki C++ library from the Modern C++ Design book.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPEINFO_H
+#define LLVM_SUPPORT_TYPEINFO_H
+
+#include <typeinfo>
+
+namespace llvm {
+
+struct TypeInfo {
+ TypeInfo() { // needed for containers
+ struct Nil {}; // Anonymous class distinct from all others...
+ Info = &typeid(Nil);
+ }
+
+ TypeInfo(const std::type_info &ti) : Info(&ti) { // non-explicit
+ }
+
+ // Access for the wrapped std::type_info
+ const std::type_info &get() const {
+ return *Info;
+ }
+
+ // Compatibility functions
+ bool before(const TypeInfo &rhs) const {
+ return Info->before(*rhs.Info) != 0;
+ }
+ const char *getClassName() const {
+ return Info->name();
+ }
+
+private:
+ const std::type_info *Info;
+};
+
+// Comparison operators
+inline bool operator==(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return lhs.get() == rhs.get();
+}
+
+inline bool operator<(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return lhs.before(rhs);
+}
+
+inline bool operator!=(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator>(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return rhs < lhs;
+}
+
+inline bool operator<=(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return !(lhs > rhs);
+}
+
+inline bool operator>=(const TypeInfo &lhs, const TypeInfo &rhs) {
+ return !(lhs < rhs);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Support/type_traits.h b/include/llvm/Support/type_traits.h
new file mode 100644
index 0000000..8befb25
--- /dev/null
+++ b/include/llvm/Support/type_traits.h
@@ -0,0 +1,54 @@
+//===- llvm/Support/type_traits.h - Simplfied type traits -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides a template class that determines if a type is a class or
+// not. The basic mechanism, based on using the pointer to member function of
+// a zero argument to a function was "boosted" from the boost type_traits
+// library. See http://www.boost.org/ for all the gory details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_TYPE_TRAITS_H
+#define LLVM_SUPPORT_TYPE_TRAITS_H
+
+// This is actually the conforming implementation which works with abstract
+// classes. However, enough compilers have trouble with it that most will use
+// the one in boost/type_traits/object_traits.hpp. This implementation actually
+// works with VC7.0, but other interactions seem to fail when we use it.
+
+namespace llvm {
+
+namespace dont_use
+{
+ // These two functions should never be used. They are helpers to
+ // the is_class template below. They cannot be located inside
+ // is_class because doing so causes at least GCC to think that
+ // the value of the "value" enumerator is not constant. Placing
+ // them out here (for some strange reason) allows the sizeof
+ // operator against them to magically be constant. This is
+ // important to make the is_class<T>::value idiom zero cost. it
+ // evaluates to a constant 1 or 0 depending on whether the
+ // parameter T is a class or not (respectively).
+ template<typename T> char is_class_helper(void(T::*)(void));
+ template<typename T> double is_class_helper(...);
+}
+
+template <typename T>
+struct is_class
+{
+ // is_class<> metafunction due to Paul Mensonides (leavings@attbi.com). For
+ // more details:
+ // http://groups.google.com/groups?hl=en&selm=000001c1cc83%24e154d5e0%247772e50c%40c161550a&rnum=1
+ public:
+ enum { value = sizeof(char) == sizeof(dont_use::is_class_helper<T>(0)) };
+};
+
+}
+
+#endif
diff --git a/include/llvm/SymbolTableListTraits.h b/include/llvm/SymbolTableListTraits.h
new file mode 100644
index 0000000..205b409
--- /dev/null
+++ b/include/llvm/SymbolTableListTraits.h
@@ -0,0 +1,76 @@
+//===-- llvm/SymbolTableListTraits.h - Traits for iplist --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a generic class that is used to implement the automatic
+// symbol table manipulation that occurs when you put (for example) a named
+// instruction into a basic block.
+//
+// The way that this is implemented is by using a special traits class with the
+// intrusive list that makes up the list of instructions in a basic block. When
+// a new element is added to the list of instructions, the traits class is
+// notified, allowing the symbol table to be updated.
+//
+// This generic class implements the traits class. It must be generic so that
+// it can work for all uses it, which include lists of instructions, basic
+// blocks, arguments, functions, global variables, etc...
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYMBOLTABLELISTTRAITS_H
+#define LLVM_SYMBOLTABLELISTTRAITS_H
+
+namespace llvm {
+
+template<typename NodeTy> class ilist_iterator;
+template<typename NodeTy, typename Traits> class iplist;
+template<typename Ty> struct ilist_traits;
+
+// ValueSubClass - The type of objects that I hold, e.g. Instruction.
+// ItemParentType - The type of object that owns the list, e.g. BasicBlock.
+// TraitBaseClass - The class this trait should inherit from, it should
+// inherit from ilist_traits<ValueSubClass>
+//
+template<typename ValueSubClass, typename ItemParentClass>
+class SymbolTableListTraits {
+ typedef ilist_traits<ValueSubClass> TraitsClass;
+public:
+ SymbolTableListTraits() {}
+
+ /// getListOwner - Return the object that owns this list. If this is a list
+ /// of instructions, it returns the BasicBlock that owns them.
+ ItemParentClass *getListOwner() {
+ return reinterpret_cast<ItemParentClass*>((char*)this-
+ TraitsClass::getListOffset());
+ }
+ static ValueSubClass *getPrev(ValueSubClass *V) { return V->getPrev(); }
+ static ValueSubClass *getNext(ValueSubClass *V) { return V->getNext(); }
+ static const ValueSubClass *getPrev(const ValueSubClass *V) {
+ return V->getPrev();
+ }
+ static const ValueSubClass *getNext(const ValueSubClass *V) {
+ return V->getNext();
+ }
+
+ static void setPrev(ValueSubClass *V, ValueSubClass *P) { V->setPrev(P); }
+ static void setNext(ValueSubClass *V, ValueSubClass *N) { V->setNext(N); }
+
+ void addNodeToList(ValueSubClass *V);
+ void removeNodeFromList(ValueSubClass *V);
+ void transferNodesFromList(iplist<ValueSubClass,
+ ilist_traits<ValueSubClass> > &L2,
+ ilist_iterator<ValueSubClass> first,
+ ilist_iterator<ValueSubClass> last);
+//private:
+ template<typename TPtr>
+ void setSymTabObject(TPtr *, TPtr);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/System/Alarm.h b/include/llvm/System/Alarm.h
new file mode 100644
index 0000000..2b78da6
--- /dev/null
+++ b/include/llvm/System/Alarm.h
@@ -0,0 +1,49 @@
+//===- llvm/System/Alarm.h - Alarm Generation support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an operating system independent interface to alarm(2)
+// type functionality. The Alarm class allows a one-shot alarm to be set up
+// at some number of seconds in the future. When the alarm triggers, a method
+// is called to process the event
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_ALARM_H
+#define LLVM_SYSTEM_ALARM_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This function registers an alarm to trigger some number of \p seconds in
+ /// the future. When that time arrives, the AlarmStatus function will begin
+ /// to return 1 instead of 0. The user must poll the status of the alarm by
+ /// making occasional calls to AlarmStatus. If the user sends an interrupt
+ /// signal, AlarmStatus will begin returning -1, even if the alarm event
+ /// occurred.
+ /// @returns nothing
+ void SetupAlarm(
+ unsigned seconds ///< Number of seconds in future when alarm arrives
+ );
+
+ /// This function terminates the alarm previously set up
+ /// @returns nothing
+ void TerminateAlarm();
+
+ /// This function acquires the status of the alarm.
+ /// @returns -1=cancelled, 0=untriggered, 1=triggered
+ int AlarmStatus();
+
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemAlarm)
+
+#endif
diff --git a/include/llvm/System/Disassembler.h b/include/llvm/System/Disassembler.h
new file mode 100644
index 0000000..fd08f2d
--- /dev/null
+++ b/include/llvm/System/Disassembler.h
@@ -0,0 +1,35 @@
+//===- llvm/Support/Disassembler.h ------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Anton Korobeynikov and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the necessary glue to call external disassembler
+// libraries.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DISASSEMBLER_H
+#define LLVM_SYSTEM_DISASSEMBLER_H
+
+#include "llvm/Support/DataTypes.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+/// This function returns true, if there is possible to use some external
+/// disassembler library. False otherwise.
+bool hasDisassembler(void);
+
+/// This function provides some "glue" code to call external disassembler
+/// libraries.
+std::string disassembleBuffer(uint8_t* start, size_t length, uint64_t pc = 0);
+
+}
+}
+
+#endif // LLVM_SYSTEM_DISASSEMBLER_H
diff --git a/include/llvm/System/DynamicLibrary.h b/include/llvm/System/DynamicLibrary.h
new file mode 100644
index 0000000..5499f9d
--- /dev/null
+++ b/include/llvm/System/DynamicLibrary.h
@@ -0,0 +1,125 @@
+//===-- llvm/System/DynamicLibrary.h - Portable Dynamic Library -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the sys::DynamicLibrary class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+#define LLVM_SYSTEM_DYNAMIC_LIBRARY_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+#include <string>
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides a portable interface to dynamic libraries which also
+ /// might be known as shared libraries, shared objects, dynamic shared
+ /// objects, or dynamic link libraries. Regardless of the terminology or the
+ /// operating system interface, this class provides a portable interface that
+ /// allows dynamic libraries to be loaded and and searched for externally
+ /// defined symbols. This is typically used to provide "plug-in" support.
+ /// It also allows for symbols to be defined which don't live in any library,
+ /// but rather the main program itself, useful on Windows where the main
+ /// executable cannot be searched.
+ /// @since 1.4
+ /// @brief Portable dynamic library abstraction.
+ class DynamicLibrary {
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a DynamicLibrary that represents the currently executing
+ /// program. The program must have been linked with -export-dynamic or
+ /// -dlopen self for this to work. Any symbols retrieved with the
+ /// GetAddressOfSymbol function will refer to the program not to any
+ /// library.
+ /// @throws std::string indicating why the program couldn't be opened.
+ /// @brief Open program as dynamic library.
+ DynamicLibrary();
+
+ /// After destruction, the symbols of the library will no longer be
+ /// available to the program. It is important to make sure the lifespan
+ /// of a DynamicLibrary exceeds the lifetime of the pointers returned
+ /// by the GetAddressOfSymbol otherwise the program may walk off into
+ /// uncharted territory.
+ /// @see GetAddressOfSymbol.
+ /// @brief Closes the DynamicLibrary
+ ~DynamicLibrary();
+
+ /// @}
+ /// @name Functions
+ /// @{
+ public:
+ /// This function allows a library to be loaded without instantiating a
+ /// DynamicLibrary object. Consequently, it is marked as being permanent
+ /// and will only be unloaded when the program terminates. This returns
+ /// false on success or returns true and fills in *ErrMsg on failure.
+ /// @brief Open a dynamic library permanently.
+ static bool LoadLibraryPermanently(const char* filename,
+ std::string *ErrMsg = 0);
+
+ /// This function will search through all previously loaded dynamic
+ /// libraries for the symbol \p symbolName. If it is found, the addressof
+ /// that symbol is returned. If not, null is returned. Note that this will
+ /// search permanently loaded libraries (LoadLibraryPermanently) as well
+ /// as ephemerally loaded libraries (constructors).
+ /// @throws std::string on error.
+ /// @brief Search through libraries for address of a symbol
+ static void* SearchForAddressOfSymbol(const char* symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ static void* SearchForAddressOfSymbol(const std::string& symbolName) {
+ return SearchForAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// This functions permanently adds the symbol \p symbolName with the
+ /// value \p symbolValue. These symbols are searched before any
+ /// libraries.
+ /// @brief Add searchable symbol/value pair.
+ static void AddSymbol(const char* symbolName, void *symbolValue);
+
+ /// @brief Convenience function for C++ophiles.
+ static void AddSymbol(const std::string& symbolName, void *symbolValue) {
+ AddSymbol(symbolName.c_str(), symbolValue);
+ }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// Looks up a \p symbolName in the DynamicLibrary and returns its address
+ /// if it exists. If the symbol does not exist, returns (void*)0.
+ /// @returns the address of the symbol or 0.
+ /// @brief Get the address of a symbol in the DynamicLibrary.
+ void* GetAddressOfSymbol(const char* symbolName);
+
+ /// @brief Convenience function for C++ophiles.
+ void* GetAddressOfSymbol(const std::string& symbolName) {
+ return GetAddressOfSymbol(symbolName.c_str());
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ protected:
+ void* handle; // Opaque handle for information about the library
+
+ DynamicLibrary(const DynamicLibrary&); ///< Do not implement
+ DynamicLibrary& operator=(const DynamicLibrary&); ///< Do not implement
+ /// @}
+ };
+
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemDynamicLibrary)
+
+#endif // LLVM_SYSTEM_DYNAMIC_LIBRARY_H
diff --git a/include/llvm/System/IncludeFile.h b/include/llvm/System/IncludeFile.h
new file mode 100644
index 0000000..c9f3882
--- /dev/null
+++ b/include/llvm/System/IncludeFile.h
@@ -0,0 +1,65 @@
+//===- llvm/System/IncludeFile.h - Ensure Linking Of Library ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the FORCE_DEFINING_FILE_TO_BE_LINKED and DEFINE_FILE_FOR
+// macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_INCLUDEFILE_H
+#define LLVM_SYSTEM_INCLUDEFILE_H
+
+/// This macro is the public interface that IncludeFile.h exports. This gives
+/// us the option to implement the "link the definition" capability in any
+/// manner that we choose. All header files that depend on a specific .cpp
+/// file being linked at run time should use this macro instead of the
+/// IncludeFile class directly.
+///
+/// For example, foo.h would use:<br/>
+/// <tt>FORCE_DEFINING_FILE_TO_BE_LINKED(foo)</tt><br/>
+///
+/// And, foo.cp would use:<br/>
+/// <tt>DEFINING_FILE_FOR(foo)</tt><br/>
+#define FORCE_DEFINING_FILE_TO_BE_LINKED(name) \
+ namespace llvm { \
+ extern char name ## LinkVar; \
+ static IncludeFile name ## LinkObj ( &name ## LinkVar ); \
+ }
+
+/// This macro is the counterpart to FORCE_DEFINING_FILE_TO_BE_LINKED. It should
+/// be used in a .cpp file to define the name referenced in a header file that
+/// will cause linkage of the .cpp file. It should only be used at extern level.
+#define DEFINING_FILE_FOR(name) namespace llvm { char name ## LinkVar; }
+
+namespace llvm {
+
+/// This class is used in the implementation of FORCE_DEFINING_FILE_TO_BE_LINKED
+/// macro to make sure that the implementation of a header file is included
+/// into a tool that uses the header. This is solely
+/// to overcome problems linking .a files and not getting the implementation
+/// of compilation units we need. This is commonly an issue with the various
+/// Passes but also occurs elsewhere in LLVM. We like to use .a files because
+/// they link faster and provide the smallest executables. However, sometimes
+/// those executables are too small, if the program doesn't reference something
+/// that might be needed, especially by a loaded share object. This little class
+/// helps to resolve that problem. The basic strategy is to use this class in
+/// a header file and pass the address of a variable to the constructor. If the
+/// variable is defined in the header file's corresponding .cpp file then all
+/// tools/libraries that #include the header file will require the .cpp as well.
+/// For example:<br/>
+/// <tt>extern int LinkMyCodeStub;</tt><br/>
+/// <tt>static IncludeFile LinkMyModule(&LinkMyCodeStub);</tt><br/>
+/// @brief Class to ensure linking of corresponding object file.
+struct IncludeFile {
+ IncludeFile(void *);
+};
+
+}
+
+#endif
diff --git a/include/llvm/System/LICENSE.TXT b/include/llvm/System/LICENSE.TXT
new file mode 100644
index 0000000..f569da2
--- /dev/null
+++ b/include/llvm/System/LICENSE.TXT
@@ -0,0 +1,6 @@
+LLVM System Interface Library
+-------------------------------------------------------------------------------
+The LLVM System Interface Library is licensed under the Illinois Open Source
+License and has the following additional copyright:
+
+Copyright (C) 2004 eXtensible Systems, Inc.
diff --git a/include/llvm/System/MappedFile.h b/include/llvm/System/MappedFile.h
new file mode 100644
index 0000000..6276bc3
--- /dev/null
+++ b/include/llvm/System/MappedFile.h
@@ -0,0 +1,175 @@
+//===- llvm/System/MappedFile.h - MappedFile OS Concept ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::MappedFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MAPPEDFILE_H
+#define LLVM_SYSTEM_MAPPEDFILE_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// Forward declare a class used for holding platform specific information
+ /// that needs to be
+ struct MappedFileInfo;
+
+ /// This class provides an abstraction for a memory mapped file in the
+ /// operating system's filesystem. It provides platform independent operations
+ /// for mapping a file into memory for both read and write access. This class
+ /// does not provide facilities for finding the file or operating on paths to
+ /// files. The sys::Path class is used for that.
+ /// @since 1.4
+ /// @brief An abstraction for memory mapped files.
+ class MappedFile {
+ /// @name Types
+ /// @{
+ public:
+ enum MappingOptions {
+ READ_ACCESS = 0x0001, ///< Map the file for reading
+ WRITE_ACCESS = 0x0002, ///< Map the file for write access
+ EXEC_ACCESS = 0x0004, ///< Map the file for execution access
+ SHARED_MAPPING = 0x0008 ///< Map the file shared with other processes
+ };
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a MappedFile to the \p path in the operating system's file
+ /// system with the mapping \p options provided.
+ /// @throws std::string if an error occurs
+ MappedFile() : path_(), options_(READ_ACCESS), base_(0), info_(0) {}
+
+ /// Destruct a MappedFile and release all memory associated with it.
+ /// @throws std::string if an error occurs
+ ~MappedFile() { if (info_) terminate(); }
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+ /// This function determines if the file is currently mapped or not.
+ /// @returns true iff the file is mapped into memory, false otherwise
+ /// @brief Determine if a MappedFile is currently mapped
+ /// @throws nothing
+ bool isMapped() const { return base_ != 0; }
+
+ /// This function returns a void* pointer to the base address of the file
+ /// mapping. This is the memory address of the first byte in the file.
+ /// Note that although a non-const pointer is returned, the memory might
+ /// not actually be writable, depending on the MappingOptions used when
+ /// the MappedFile was opened.
+ /// @returns The base pointer to the memory mapped file.
+ /// @brief Obtain the base pointer to the memory mapped file.
+ /// @throws nothing
+ void* base() const { return base_; }
+
+ /// This function returns a char* pointer to the base address of the file
+ /// mapping. This is the memory address of the first byte in the file.
+ /// Note that although a non-const pointer is returned, the memory might
+ /// not actually be writable, depending on the MappingOptions used when
+ /// the MappedFile was opened.
+ /// @returns The base pointer to the memory mapped file as a char pointer.
+ /// @brief Obtain the base pointer to the memory mapped file.
+ /// @throws nothing
+ char* charBase() const { return reinterpret_cast<char*>(base_); }
+
+ /// This function returns a reference to the sys::Path object kept by the
+ /// MappedFile object. This contains the path to the file that is or
+ /// will be mapped.
+ /// @returns sys::Path containing the path name.
+ /// @brief Returns the mapped file's path as a sys::Path
+ /// @throws nothing
+ const sys::Path& path() const { return path_; }
+
+ /// This function returns the number of bytes in the file.
+ /// @throws std::string if an error occurs
+ size_t size() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// Open a file to be mapped and get its size but don't map it yet.
+ /// @returns true if an error occurred
+ bool open(
+ const sys::Path& p, ///< Path to file to be mapped
+ int options = READ_ACCESS, ///< Access mode for the mapping
+ std::string* ErrMsg = 0 ///< Optional error string pointer
+ ) {
+ path_ = p;
+ options_ = options;
+ return initialize(ErrMsg);
+ }
+
+ /// The mapped file is removed from memory. If the file was mapped for
+ /// write access, the memory contents will be automatically synchronized
+ /// with the file's disk contents.
+ /// @brief Remove the file mapping from memory.
+ void unmap();
+
+ /// The mapped file is put into memory.
+ /// @returns The base memory address of the mapped file or 0 if an error
+ /// occurred.
+ /// @brief Map the file into memory.
+ void* map(
+ std::string* ErrMsg = 0///< Optional error string pointer
+ );
+
+ /// This method causes the size of the file, and consequently the size
+ /// of the mapping to be set. This is logically the same as unmap(),
+ /// adjust size of the file, map(). Consequently, when calling this
+ /// function, the caller should not rely on previous results of the
+ /// map(), base(), or baseChar() members as they may point to invalid
+ /// areas of memory after this call.
+ /// @throws std::string if an error occurs
+ /// @brief Set the size of the file and memory mapping.
+ bool size(size_t new_size, std::string* ErrMsg = 0);
+
+ void close() { if (info_) terminate(); }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// @brief Initialize platform-specific portion
+ bool initialize(std::string* ErrMsg);
+
+ /// @brief Terminate platform-specific portion
+ void terminate();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ sys::PathWithStatus path_; ///< Path to the file.
+ int options_; ///< Options used to create the mapping
+ void* base_; ///< Pointer to the base memory address
+ mutable MappedFileInfo* info_; ///< Platform specific info for the mapping
+
+ /// @}
+ /// @name Disabled
+ /// @{
+ private:
+ ///< Disallow assignment
+ MappedFile& operator = ( const MappedFile & that );
+ ///< Disallow copying
+ MappedFile(const MappedFile& that);
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMappedFile)
+
+#endif
diff --git a/include/llvm/System/Memory.h b/include/llvm/System/Memory.h
new file mode 100644
index 0000000..c343177
--- /dev/null
+++ b/include/llvm/System/Memory.h
@@ -0,0 +1,76 @@
+//===- llvm/System/Memory.h - Memory Support --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Memory class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MEMORY_H
+#define LLVM_SYSTEM_MEMORY_H
+
+#include <string>
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This class encapsulates the notion of a memory block which has an address
+ /// and a size. It is used by the Memory class (a friend) as the result of
+ /// various memory allocation operations.
+ /// @see Memory
+ /// @brief Memory block abstraction.
+ class MemoryBlock {
+ public:
+ void *base() const { return Address; }
+ unsigned size() const { return Size; }
+ private:
+ void *Address; ///< Address of first byte of memory area
+ unsigned Size; ///< Size, in bytes of the memory area
+ friend class Memory;
+ };
+
+ /// This class provides various memory handling functions that manipulate
+ /// MemoryBlock instances.
+ /// @since 1.4
+ /// @brief An abstraction for memory operations.
+ class Memory {
+ /// @name Functions
+ /// @{
+ public:
+ /// This method allocates a block of Read/Write/Execute memory that is
+ /// suitable for executing dynamically generated code (e.g. JIT). An
+ /// attempt to allocate \p NumBytes bytes of virtual memory is made.
+ /// \p NearBlock may point to an existing allocation in which case
+ /// an attempt is made to allocate more memory near the existing block.
+ ///
+ /// On success, this returns a non-null memory block, otherwise it returns
+ /// a null memory block and fills in *ErrMsg.
+ ///
+ /// @brief Allocate Read/Write/Execute memory.
+ static MemoryBlock AllocateRWX(unsigned NumBytes,
+ const MemoryBlock *NearBlock,
+ std::string *ErrMsg = 0);
+
+ /// This method releases a block of Read/Write/Execute memory that was
+ /// allocated with the AllocateRWX method. It should not be used to
+ /// release any memory block allocated any other way.
+ ///
+ /// On success, this returns false, otherwise it returns true and fills
+ /// in *ErrMsg.
+ /// @throws std::string if an error occurred.
+ /// @brief Release Read/Write/Execute memory.
+ static bool ReleaseRWX(MemoryBlock &block, std::string *ErrMsg = 0);
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMemory)
+
+#endif
diff --git a/include/llvm/System/Mutex.h b/include/llvm/System/Mutex.h
new file mode 100644
index 0000000..27bcea1
--- /dev/null
+++ b/include/llvm/System/Mutex.h
@@ -0,0 +1,88 @@
+//===- llvm/System/Mutex.h - Mutex Operating System Concept -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Mutex class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_MUTEX_H
+#define LLVM_SYSTEM_MUTEX_H
+
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm
+{
+ namespace sys
+ {
+ /// @brief Platform agnostic Mutex class.
+ class Mutex
+ {
+ /// @name Constructors
+ /// @{
+ public:
+
+ /// Initializes the lock but doesn't acquire it. if \p recursive is set
+ /// to false, the lock will not be recursive which makes it cheaper but
+ /// also more likely to deadlock (same thread can't acquire more than
+ /// once).
+ /// @brief Default Constructor.
+ Mutex ( bool recursive = true );
+
+ /// Releases and removes the lock
+ /// @brief Destructor
+ ~Mutex ( void );
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+
+ /// Attempts to unconditionally acquire the lock. If the lock is held by
+ /// another thread, this method will wait until it can acquire the lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally acquire the lock.
+ bool acquire();
+
+ /// Attempts to release the lock. If the lock is held by the current
+ /// thread, the lock is released allowing other threads to acquire the
+ /// lock.
+ /// @returns false if any kind of error occurs, true otherwise.
+ /// @brief Unconditionally release the lock.
+ bool release(void);
+
+ /// Attempts to acquire the lock without blocking. If the lock is not
+ /// available, this function returns false quickly (without blocking). If
+ /// the lock is available, it is acquired.
+ /// @returns false if any kind of error occurs or the lock is not
+ /// available, true otherwise.
+ /// @brief Try to acquire the lock.
+ bool tryacquire();
+
+ //@}
+ /// @name Platform Dependent Data
+ /// @{
+ private:
+#ifdef ENABLE_THREADS
+ void* data_; ///< We don't know what the data will be
+#endif
+
+ /// @}
+ /// @name Do Not Implement
+ /// @{
+ private:
+ Mutex(const Mutex & original);
+ void operator=(const Mutex &);
+ /// @}
+ };
+ }
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemMutex)
+
+#endif
diff --git a/include/llvm/System/Path.h b/include/llvm/System/Path.h
new file mode 100644
index 0000000..e7aa45b
--- /dev/null
+++ b/include/llvm/System/Path.h
@@ -0,0 +1,656 @@
+//===- llvm/System/Path.h - Path Operating System Concept -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Path class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PATH_H
+#define LLVM_SYSTEM_PATH_H
+
+#include "llvm/System/TimeValue.h"
+#include "llvm/System/IncludeFile.h"
+#include <set>
+#include <string>
+#include <vector>
+#include <iosfwd>
+
+namespace llvm {
+namespace sys {
+
+ /// This structure provides basic file system information about a file. It
+ /// is patterned after the stat(2) Unix operating system call but made
+ /// platform independent and eliminates many of the unix-specific fields.
+ /// However, to support llvm-ar, the mode, user, and group fields are
+ /// retained. These pertain to unix security and may not have a meaningful
+ /// value on non-Unix platforms. However, the other fields fields should
+ /// always be applicable on all platforms. The structure is filled in by
+ /// the PathWithStatus class.
+ /// @brief File status structure
+ class FileStatus {
+ public:
+ uint64_t fileSize; ///< Size of the file in bytes
+ TimeValue modTime; ///< Time of file's modification
+ uint32_t mode; ///< Mode of the file, if applicable
+ uint32_t user; ///< User ID of owner, if applicable
+ uint32_t group; ///< Group ID of owner, if applicable
+ uint64_t uniqueID; ///< A number to uniquely ID this file
+ bool isDir : 1; ///< True if this is a directory.
+ bool isFile : 1; ///< True if this is a file.
+
+ FileStatus() : fileSize(0), modTime(0,0), mode(0777), user(999),
+ group(999), uniqueID(0), isDir(false), isFile(false) { }
+
+ TimeValue getTimestamp() const { return modTime; }
+ uint64_t getSize() const { return fileSize; }
+ uint32_t getMode() const { return mode; }
+ uint32_t getUser() const { return user; }
+ uint32_t getGroup() const { return group; }
+ uint64_t getUniqueID() const { return uniqueID; }
+ };
+
+ /// This class provides an abstraction for the path to a file or directory
+ /// in the operating system's filesystem and provides various basic operations
+ /// on it. Note that this class only represents the name of a path to a file
+ /// or directory which may or may not be valid for a given machine's file
+ /// system. The class is patterned after the java.io.File class with various
+ /// extensions and several omissions (not relevant to LLVM). A Path object
+ /// ensures that the path it encapsulates is syntactically valid for the
+ /// operating system it is running on but does not ensure correctness for
+ /// any particular file system. That is, a syntactically valid path might
+ /// specify path components that do not exist in the file system and using
+ /// such a Path to act on the file system could produce errors. There is one
+ /// invalid Path value which is permitted: the empty path. The class should
+ /// never allow a syntactically invalid non-empty path name to be assigned.
+ /// Empty paths are required in order to indicate an error result in some
+ /// situations. If the path is empty, the isValid operation will return
+ /// false. All operations will fail if isValid is false. Operations that
+ /// change the path will either return false if it would cause a syntactically
+ /// invalid path name (in which case the Path object is left unchanged) or
+ /// throw an std::string exception indicating the error. The methods are
+ /// grouped into four basic categories: Path Accessors (provide information
+ /// about the path without accessing disk), Disk Accessors (provide
+ /// information about the underlying file or directory), Path Mutators
+ /// (change the path information, not the disk), and Disk Mutators (change
+ /// the disk file/directory referenced by the path). The Disk Mutator methods
+ /// all have the word "disk" embedded in their method name to reinforce the
+ /// notion that the operation modifies the file system.
+ /// @since 1.4
+ /// @brief An abstraction for operating system paths.
+ class Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// Construct a path to the root directory of the file system. The root
+ /// directory is a top level directory above which there are no more
+ /// directories. For example, on UNIX, the root directory is /. On Windows
+ /// it is C:\. Other operating systems may have different notions of
+ /// what the root directory is or none at all. In that case, a consistent
+ /// default root directory will be used.
+ static Path GetRootDirectory();
+
+ /// Construct a path to a unique temporary directory that is created in
+ /// a "standard" place for the operating system. The directory is
+ /// guaranteed to be created on exit from this function. If the directory
+ /// cannot be created, the function will throw an exception.
+ /// @returns an invalid path (empty) on error
+ /// @param ErrMsg Optional place for an error message if an error occurs
+ /// @brief Constrct a path to an new, unique, existing temporary
+ /// directory.
+ static Path GetTemporaryDirectory(std::string* ErrMsg = 0);
+
+ /// Construct a vector of sys::Path that contains the "standard" system
+ /// library paths suitable for linking into programs. This function *must*
+ /// return the value of LLVM_LIB_SEARCH_PATH as the first item in \p Paths
+ /// if that environment variable is set and it references a directory.
+ /// @brief Construct a path to the system library directory
+ static void GetSystemLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Construct a vector of sys::Path that contains the "standard" bitcode
+ /// library paths suitable for linking into an llvm program. This function
+ /// *must* return the value of LLVM_LIB_SEARCH_PATH as well as the value
+ /// of LLVM_LIBDIR. It also must provide the System library paths as
+ /// returned by GetSystemLibraryPaths.
+ /// @see GetSystemLibraryPaths
+ /// @brief Construct a list of directories in which bitcode could be
+ /// found.
+ static void GetBitcodeLibraryPaths(std::vector<sys::Path>& Paths);
+
+ /// Find the path to a library using its short name. Use the system
+ /// dependent library paths to locate the library.
+ /// @brief Find a library.
+ static Path FindLibrary(std::string& short_name);
+
+ /// Construct a path to the default LLVM configuration directory. The
+ /// implementation must ensure that this is a well-known (same on many
+ /// systems) directory in which llvm configuration files exist. For
+ /// example, on Unix, the /etc/llvm directory has been selected.
+ /// @brief Construct a path to the default LLVM configuration directory
+ static Path GetLLVMDefaultConfigDir();
+
+ /// Construct a path to the LLVM installed configuration directory. The
+ /// implementation must ensure that this refers to the "etc" directory of
+ /// the LLVM installation. This is the location where configuration files
+ /// will be located for a particular installation of LLVM on a machine.
+ /// @brief Construct a path to the LLVM installed configuration directory
+ static Path GetLLVMConfigDir();
+
+ /// Construct a path to the current user's home directory. The
+ /// implementation must use an operating system specific mechanism for
+ /// determining the user's home directory. For example, the environment
+ /// variable "HOME" could be used on Unix. If a given operating system
+ /// does not have the concept of a user's home directory, this static
+ /// constructor must provide the same result as GetRootDirectory.
+ /// @brief Construct a path to the current user's "home" directory
+ static Path GetUserHomeDirectory();
+
+ /// Return the suffix commonly used on file names that contain a shared
+ /// object, shared archive, or dynamic link library. Such files are
+ /// linked at runtime into a process and their code images are shared
+ /// between processes.
+ /// @returns The dynamic link library suffix for the current platform.
+ /// @brief Return the dynamic link library suffix.
+ static std::string GetDLLSuffix();
+
+ /// This is one of the very few ways in which a path can be constructed
+ /// with a syntactically invalid name. The only *legal* invalid name is an
+ /// empty one. Other invalid names are not permitted. Empty paths are
+ /// provided so that they can be used to indicate null or error results in
+ /// other lib/System functionality.
+ /// @brief Construct an empty (and invalid) path.
+ Path() : path() {}
+ Path(const Path &that) : path(that.path) {}
+
+ /// This constructor will accept a std::string as a path. No checking is
+ /// done on this path to determine if it is valid. To determine validity
+ /// of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit Path(const std::string& p) : path(p) {}
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit Path(const char *StrStart, unsigned StrLen)
+ : path(StrStart, StrStart+StrLen) {}
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ Path &operator=(const Path &that) {
+ path = that.path;
+ return *this;
+ }
+
+ /// Compares \p this Path with \p that Path for equality.
+ /// @returns true if \p this and \p that refer to the same thing.
+ /// @brief Equality Operator
+ bool operator==(const Path &that) const {
+ return 0 == path.compare(that.path);
+ }
+
+ /// Compares \p this Path with \p that Path for inequality.
+ /// @returns true if \p this and \p that refer to different things.
+ /// @brief Inequality Operator
+ bool operator!=(const Path &that) const {
+ return 0 != path.compare(that.path);
+ }
+
+ /// Determines if \p this Path is less than \p that Path. This is required
+ /// so that Path objects can be placed into ordered collections (e.g.
+ /// std::map). The comparison is done lexicographically as defined by
+ /// the std::string::compare method.
+ /// @returns true if \p this path is lexicographically less than \p that.
+ /// @brief Less Than Operator
+ bool operator<(const Path& that) const {
+ return 0 > path.compare(that.path);
+ }
+
+ /// @}
+ /// @name Path Accessors
+ /// @{
+ public:
+ /// This function will use an operating system specific algorithm to
+ /// determine if the current value of \p this is a syntactically valid
+ /// path name for the operating system. The path name does not need to
+ /// exist, validity is simply syntactical. Empty paths are always invalid.
+ /// @returns true iff the path name is syntactically legal for the
+ /// host operating system.
+ /// @brief Determine if a path is syntactically valid or not.
+ bool isValid() const;
+
+ /// This function determines if the contents of the path name are empty.
+ /// That is, the path name has a zero length. This does NOT determine if
+ /// if the file is empty. To get the length of the file itself, Use the
+ /// PathWithStatus::getFileStatus() method and then the getSize() method
+ /// on the returned FileStatus object.
+ /// @returns true iff the path is empty.
+ /// @brief Determines if the path name is empty (invalid).
+ bool isEmpty() const { return path.empty(); }
+
+ /// This function returns the current contents of the path as a
+ /// std::string. This allows the underlying path string to be manipulated.
+ /// @returns std::string containing the path name.
+ /// @brief Returns the path as a std::string.
+ const std::string &toString() const { return path; }
+
+ /// This function returns the last component of the path name. The last
+ /// component is the file or directory name occuring after the last
+ /// directory separator. If no directory separator is present, the entire
+ /// path name is returned (i.e. same as toString).
+ /// @returns std::string containing the last component of the path name.
+ /// @brief Returns the last component of the path name.
+ std::string getLast() const;
+
+ /// This function strips off the path and suffix of the file or directory
+ /// name and returns just the basename. For example /a/foo.bar would cause
+ /// this function to return "foo".
+ /// @returns std::string containing the basename of the path
+ /// @brief Get the base name of the path
+ std::string getBasename() const;
+
+ /// Obtain a 'C' string for the path name.
+ /// @returns a 'C' string containing the path name.
+ /// @brief Returns the path as a C string.
+ const char *c_str() const { return path.c_str(); }
+
+ /// @}
+ /// @name Disk Accessors
+ /// @{
+ public:
+ /// This function determines if the path name in this object references
+ /// the root (top level directory) of the file system. The details of what
+ /// is considered the "root" may vary from system to system so this method
+ /// will do the necessary checking.
+ /// @returns true iff the path name references the root directory.
+ /// @brief Determines if the path references the root directory.
+ bool isRootDirectory() const;
+
+ /// This function determines if the path name is absolute, as opposed to
+ /// relative.
+ /// @breif Determine if the path is absolute.
+ bool isAbsolute() const;
+
+ /// This function opens the file associated with the path name provided by
+ /// the Path object and reads its magic number. If the magic number at the
+ /// start of the file matches \p magic, true is returned. In all other
+ /// cases (file not found, file not accessible, etc.) it returns false.
+ /// @returns true if the magic number of the file matches \p magic.
+ /// @brief Determine if file has a specific magic number
+ bool hasMagicNumber(const std::string& magic) const;
+
+ /// This function retrieves the first \p len bytes of the file associated
+ /// with \p this. These bytes are returned as the "magic number" in the
+ /// \p Magic parameter.
+ /// @returns true if the Path is a file and the magic number is retrieved,
+ /// false otherwise.
+ /// @brief Get the file's magic number.
+ bool getMagicNumber(std::string& Magic, unsigned len) const;
+
+ /// This function determines if the path name in the object references an
+ /// archive file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for an archive
+ /// file.
+ /// @brief Determine if the path references an archive file.
+ bool isArchive() const;
+
+ /// This function determines if the path name in the object references an
+ /// LLVM Bitcode file by looking at its magic number.
+ /// @returns true if the file starts with the magic number for LLVM
+ /// bitcode files.
+ /// @brief Determine if the path references a bitcode file.
+ bool isBitcodeFile() const;
+
+ /// This function determines if the path name in the object references a
+ /// native Dynamic Library (shared library, shared object) by looking at
+ /// the file's magic number. The Path object must reference a file, not a
+ /// directory.
+ /// @return strue if the file starts with the magid number for a native
+ /// shared library.
+ /// @brief Determine if the path reference a dynamic library.
+ bool isDynamicLibrary() const;
+
+ /// This function determines if the path name references an existing file
+ /// or directory in the file system.
+ /// @returns true if the pathname references an existing file or
+ /// directory.
+ /// @brief Determines if the path is a file or directory in
+ /// the file system.
+ bool exists() const;
+
+ /// This function determines if the path name references a readable file
+ /// or directory in the file system. This function checks for
+ /// the existence and readability (by the current program) of the file
+ /// or directory.
+ /// @returns true if the pathname references a readable file.
+ /// @brief Determines if the path is a readable file or directory
+ /// in the file system.
+ bool canRead() const;
+
+ /// This function determines if the path name references a writable file
+ /// or directory in the file system. This function checks for the
+ /// existence and writability (by the current program) of the file or
+ /// directory.
+ /// @returns true if the pathname references a writable file.
+ /// @brief Determines if the path is a writable file or directory
+ /// in the file system.
+ bool canWrite() const;
+
+ /// This function determines if the path name references an executable
+ /// file in the file system. This function checks for the existence and
+ /// executability (by the current program) of the file.
+ /// @returns true if the pathname references an executable file.
+ /// @brief Determines if the path is an executable file in the file
+ /// system.
+ bool canExecute() const;
+
+ /// This function builds a list of paths that are the names of the
+ /// files and directories in a directory.
+ /// @returns true if an error occurs, true otherwise
+ /// @brief Build a list of directory's contents.
+ bool getDirectoryContents(
+ std::set<Path> &paths, ///< The resulting list of file & directory names
+ std::string* ErrMsg ///< Optional place to return an error message.
+ ) const;
+
+ /// @}
+ /// @name Path Mutators
+ /// @{
+ public:
+ /// The path name is cleared and becomes empty. This is an invalid
+ /// path name but is the *only* invalid path name. This is provided
+ /// so that path objects can be used to indicate the lack of a
+ /// valid path being found.
+ /// @brief Make the path empty.
+ void clear() { path.clear(); }
+
+ /// This method sets the Path object to \p unverified_path. This can fail
+ /// if the \p unverified_path does not pass the syntactic checks of the
+ /// isValid() method. If verification fails, the Path object remains
+ /// unchanged and false is returned. Otherwise true is returned and the
+ /// Path object takes on the path value of \p unverified_path
+ /// @returns true if the path was set, false otherwise.
+ /// @param unverified_path The path to be set in Path object.
+ /// @brief Set a full path from a std::string
+ bool set(const std::string& unverified_path);
+
+ /// One path component is removed from the Path. If only one component is
+ /// present in the path, the Path object becomes empty. If the Path object
+ /// is empty, no change is made.
+ /// @returns false if the path component could not be removed.
+ /// @brief Removes the last directory component of the Path.
+ bool eraseComponent();
+
+ /// The \p component is added to the end of the Path if it is a legal
+ /// name for the operating system. A directory separator will be added if
+ /// needed.
+ /// @returns false if the path component could not be added.
+ /// @brief Appends one path component to the Path.
+ bool appendComponent( const std::string& component );
+
+ /// A period and the \p suffix are appended to the end of the pathname.
+ /// The precondition for this function is that the Path reference a file
+ /// name (i.e. isFile() returns true). If the Path is not a file, no
+ /// action is taken and the function returns false. If the path would
+ /// become invalid for the host operating system, false is returned.
+ /// @returns false if the suffix could not be added, true if it was.
+ /// @brief Adds a period and the \p suffix to the end of the pathname.
+ bool appendSuffix(const std::string& suffix);
+
+ /// The suffix of the filename is erased. The suffix begins with and
+ /// includes the last . character in the filename after the last directory
+ /// separator and extends until the end of the name. If no . character is
+ /// after the last directory separator, then the file name is left
+ /// unchanged (i.e. it was already without a suffix) but the function
+ /// returns false.
+ /// @returns false if there was no suffix to remove, true otherwise.
+ /// @brief Remove the suffix from a path name.
+ bool eraseSuffix();
+
+ /// The current Path name is made unique in the file system. Upon return,
+ /// the Path will have been changed to make a unique file in the file
+ /// system or it will not have been changed if the current path name is
+ /// already unique.
+ /// @throws std::string if an unrecoverable error occurs.
+ /// @brief Make the current path name unique in the file system.
+ bool makeUnique( bool reuse_current /*= true*/, std::string* ErrMsg );
+
+ /// @}
+ /// @name Disk Mutators
+ /// @{
+ public:
+ /// This method attempts to make the file referenced by the Path object
+ /// available for reading so that the canRead() method will return true.
+ /// @brief Make the file readable;
+ bool makeReadableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for writing so that the canWrite() method will return true.
+ /// @brief Make the file writable;
+ bool makeWriteableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method attempts to make the file referenced by the Path object
+ /// available for execution so that the canExecute() method will return
+ /// true.
+ /// @brief Make the file readable;
+ bool makeExecutableOnDisk(std::string* ErrMsg = 0);
+
+ /// This method allows the last modified time stamp and permission bits
+ /// to be set on the disk object referenced by the Path.
+ /// @throws std::string if an error occurs.
+ /// @returns true on error.
+ /// @brief Set the status information.
+ bool setStatusInfoOnDisk(const FileStatus &SI,
+ std::string *ErrStr = 0) const;
+
+ /// This method attempts to create a directory in the file system with the
+ /// same name as the Path object. The \p create_parents parameter controls
+ /// whether intermediate directories are created or not. if \p
+ /// create_parents is true, then an attempt will be made to create all
+ /// intermediate directories, as needed. If \p create_parents is false,
+ /// then only the final directory component of the Path name will be
+ /// created. The created directory will have no entries.
+ /// @returns true if the directory could not be created, false otherwise
+ /// @brief Create the directory this Path refers to.
+ bool createDirectoryOnDisk(
+ bool create_parents = false, ///< Determines whether non-existent
+ ///< directory components other than the last one (the "parents")
+ ///< are created or not.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This method attempts to create a file in the file system with the same
+ /// name as the Path object. The intermediate directories must all exist
+ /// at the time this method is called. Use createDirectoriesOnDisk to
+ /// accomplish that. The created file will be empty upon return from this
+ /// function.
+ /// @returns true if the file could not be created, false otherwise.
+ /// @brief Create the file this Path refers to.
+ bool createFileOnDisk(
+ std::string* ErrMsg = 0 ///< Optional place to put error messages.
+ );
+
+ /// This is like createFile except that it creates a temporary file. A
+ /// unique temporary file name is generated based on the contents of
+ /// \p this before the call. The new name is assigned to \p this and the
+ /// file is created. Note that this will both change the Path object
+ /// *and* create the corresponding file. This function will ensure that
+ /// the newly generated temporary file name is unique in the file system.
+ /// @returns true if the file couldn't be created, false otherwise.
+ /// @brief Create a unique temporary file
+ bool createTemporaryFileOnDisk(
+ bool reuse_current = false, ///< When set to true, this parameter
+ ///< indicates that if the current file name does not exist then
+ ///< it will be used without modification.
+ std::string* ErrMsg = 0 ///< Optional place to put error messages
+ );
+
+ /// This method renames the file referenced by \p this as \p newName. The
+ /// file referenced by \p this must exist. The file referenced by
+ /// \p newName does not need to exist.
+ /// @returns true on error, false otherwise
+ /// @brief Rename one file as another.
+ bool renamePathOnDisk(const Path& newName, std::string* ErrMsg);
+
+ /// This method attempts to destroy the file or directory named by the
+ /// last component of the Path. If the Path refers to a directory and the
+ /// \p destroy_contents is false, an attempt will be made to remove just
+ /// the directory (the final Path component). If \p destroy_contents is
+ /// true, an attempt will be made to remove the entire contents of the
+ /// directory, recursively. If the Path refers to a file, the
+ /// \p destroy_contents parameter is ignored.
+ /// @param destroy_contents Indicates whether the contents of a destroyed
+ /// directory should also be destroyed (recursively).
+ /// @returns false if the file/directory was destroyed, true on error.
+ /// @brief Removes the file or directory from the filesystem.
+ bool eraseFromDisk(bool destroy_contents = false,
+ std::string *Err = 0) const;
+ /// @}
+ /// @name Data
+ /// @{
+ protected:
+ mutable std::string path; ///< Storage for the path name.
+
+ /// @}
+ };
+
+ /// This class is identical to Path class except it allows you to obtain the
+ /// file status of the Path as well. The reason for the distinction is one of
+ /// efficiency. First, the file status requires additional space and the space
+ /// is incorporated directly into PathWithStatus without an additional malloc.
+ /// Second, obtaining status information is an expensive operation on most
+ /// operating systems so we want to be careful and explicity about where we
+ /// allow this operation in LLVM.
+ /// @brief Path with file status class.
+ class PathWithStatus : public Path {
+ /// @name Constructors
+ /// @{
+ public:
+ /// @brief Default constructor
+ PathWithStatus() : Path(), status(), fsIsValid(false) {}
+
+ /// @brief Copy constructor
+ PathWithStatus(const PathWithStatus &that)
+ : Path(static_cast<const Path&>(that)), status(that.status),
+ fsIsValid(that.fsIsValid) {}
+
+ /// This constructor allows construction from a Path object
+ /// @brief Path constructor
+ PathWithStatus(const Path &other)
+ : Path(other), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a std::string as a path. No checking is
+ /// done on this path to determine if it is valid. To determine validity
+ /// of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(const std::string& p)
+ : Path(p), status(), fsIsValid(false) {}
+
+ /// This constructor will accept a character range as a path. No checking
+ /// is done on this path to determine if it is valid. To determine
+ /// validity of the path, use the isValid method.
+ /// @param p The path to assign.
+ /// @brief Construct a Path from a string.
+ explicit PathWithStatus(const char *StrStart, unsigned StrLen)
+ : Path(StrStart, StrLen), status(), fsIsValid(false) {}
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const PathWithStatus &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ status = that.status;
+ fsIsValid = that.fsIsValid;
+ return *this;
+ }
+
+ /// Makes a copy of \p that to \p this.
+ /// @returns \p this
+ /// @brief Assignment Operator
+ PathWithStatus &operator=(const Path &that) {
+ static_cast<Path&>(*this) = static_cast<const Path&>(that);
+ fsIsValid = false;
+ return *this;
+ }
+
+ /// @}
+ /// @name Methods
+ /// @{
+ public:
+ /// This function returns status information about the file. The type of
+ /// path (file or directory) is updated to reflect the actual contents
+ /// of the file system.
+ /// @returns 0 on failure, with Error explaining why (if non-zero)
+ /// @returns a pointer to a FileStatus structure on success.
+ /// @brief Get file status.
+ const FileStatus *getFileStatus(
+ bool forceUpdate = false, ///< Force an update from the file system
+ std::string *Error = 0 ///< Optional place to return an error msg.
+ ) const;
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ mutable FileStatus status; ///< Status information.
+ mutable bool fsIsValid; ///< Whether we've obtained it or not
+
+ /// @}
+ };
+
+ /// This enumeration delineates the kinds of files that LLVM knows about.
+ enum LLVMFileType {
+ Unknown_FileType = 0, ///< Unrecognized file
+ Bitcode_FileType, ///< Bitcode file
+ Archive_FileType, ///< ar style archive file
+ ELF_Relocatable_FileType, ///< ELF Relocatable object file
+ ELF_Executable_FileType, ///< ELF Executable image
+ ELF_SharedObject_FileType, ///< ELF dynamically linked shared lib
+ ELF_Core_FileType, ///< ELF core image
+ Mach_O_Object_FileType, ///< Mach-O Object file
+ Mach_O_Executable_FileType, ///< Mach-O Executable
+ Mach_O_FixedVirtualMemorySharedLib_FileType, ///< Mach-O Shared Lib, FVM
+ Mach_O_Core_FileType, ///< Mach-O Core File
+ Mach_O_PreloadExectuable_FileType, ///< Mach-O Preloaded Executable
+ Mach_O_DynamicallyLinkedSharedLib_FileType, ///< Mach-O dynlinked shared lib
+ Mach_O_DynamicLinker_FileType, ///< The Mach-O dynamic linker
+ Mach_O_Bundle_FileType, ///< Mach-O Bundle file
+ Mach_O_DynamicallyLinkedSharedLibStub_FileType, ///< Mach-O Shared lib stub
+ COFF_FileType ///< COFF object file or lib
+ };
+
+ /// This utility function allows any memory block to be examined in order
+ /// to determine its file type.
+ LLVMFileType IdentifyFileType(const char*magic, unsigned length);
+
+ /// This function can be used to copy the file specified by Src to the
+ /// file specified by Dest. If an error occurs, Dest is removed.
+ /// @returns true if an error occurs, false otherwise
+ /// @brief Copy one file to another.
+ bool CopyFile(const Path& Dest, const Path& Src, std::string* ErrMsg);
+}
+
+std::ostream& operator<<(std::ostream& strm, const sys::Path& aPath);
+inline std::ostream& operator<<(std::ostream& strm,
+ const sys::PathWithStatus& aPath) {
+ strm << static_cast<const sys::Path&>(aPath);
+ return strm;
+}
+
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemPath)
+#endif
diff --git a/include/llvm/System/Process.h b/include/llvm/System/Process.h
new file mode 100644
index 0000000..f843af3
--- /dev/null
+++ b/include/llvm/System/Process.h
@@ -0,0 +1,105 @@
+//===- llvm/System/Process.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Process class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROCESS_H
+#define LLVM_SYSTEM_PROCESS_H
+
+#include "llvm/System/TimeValue.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides an abstraction for getting information about the
+ /// currently executing process.
+ /// @since 1.4
+ /// @brief An abstraction for operating system processes.
+ class Process {
+ /// @name Accessors
+ /// @{
+ public:
+ /// This static function will return the operating system's virtual memory
+ /// page size.
+ /// @returns The number of bytes in a virtual memory page.
+ /// @throws nothing
+ /// @brief Get the virtual memory page size
+ static unsigned GetPageSize();
+
+ /// This static function will return the total amount of memory allocated
+ /// by the process. This only counts the memory allocated via the malloc,
+ /// calloc and realloc functions and includes any "free" holes in the
+ /// allocated space.
+ /// @throws nothing
+ /// @brief Return process memory usage.
+ static size_t GetMallocUsage();
+
+ /// This static function will return the total memory usage of the
+ /// process. This includes code, data, stack and mapped pages usage. Notei
+ /// that the value returned here is not necessarily the Running Set Size,
+ /// it is the total virtual memory usage, regardless of mapped state of
+ /// that memory.
+ static size_t GetTotalMemoryUsage();
+
+ /// This static function will set \p user_time to the amount of CPU time
+ /// spent in user (non-kernel) mode and \p sys_time to the amount of CPU
+ /// time spent in system (kernel) mode. If the operating system does not
+ /// support collection of these metrics, a zero TimeValue will be for both
+ /// values.
+ static void GetTimeUsage(
+ TimeValue& elapsed,
+ ///< Returns the TimeValue::now() giving current time
+ TimeValue& user_time,
+ ///< Returns the current amount of user time for the process
+ TimeValue& sys_time
+ ///< Returns the current amount of system time for the process
+ );
+
+ /// This static function will return the process' current user id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentUserId();
+
+ /// This static function will return the process' current group id number.
+ /// Not all operating systems support this feature. Where it is not
+ /// supported, the function should return 65536 as the value.
+ static int GetCurrentGroupId();
+
+ /// This function makes the necessary calls to the operating system to
+ /// prevent core files or any other kind of large memory dumps that can
+ /// occur when a program fails.
+ /// @brief Prevent core file generation.
+ static void PreventCoreFiles();
+
+ /// This function determines if the standard input is connected directly
+ /// to a user's input (keyboard probably), rather than coming from a file
+ /// or pipe.
+ static bool StandardInIsUserInput();
+
+ /// This function determines if the standard output is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardOutIsDisplayed();
+
+ /// This function determines if the standard error is connected to a
+ /// "tty" or "console" window. That is, the output would be displayed to
+ /// the user rather than being put on a pipe or stored in a file.
+ static bool StandardErrIsDisplayed();
+
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemProcess)
+
+#endif
diff --git a/include/llvm/System/Program.h b/include/llvm/System/Program.h
new file mode 100644
index 0000000..cef3805
--- /dev/null
+++ b/include/llvm/System/Program.h
@@ -0,0 +1,95 @@
+//===- llvm/System/Program.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the llvm::sys::Program class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_PROGRAM_H
+#define LLVM_SYSTEM_PROGRAM_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+#include <vector>
+
+namespace llvm {
+namespace sys {
+
+ /// This class provides an abstraction for programs that are executable by the
+ /// operating system. It provides a platform generic way to find executable
+ /// programs from the path and to execute them in various ways. The sys::Path
+ /// class is used to specify the location of the Program.
+ /// @since 1.4
+ /// @brief An abstraction for finding and executing programs.
+ class Program {
+ /// @name Methods
+ /// @{
+ public:
+ /// This static constructor (factory) will attempt to locate a program in
+ /// the operating system's file system using some pre-determined set of
+ /// locations to search (e.g. the PATH on Unix).
+ /// @returns A Path object initialized to the path of the program or a
+ /// Path object that is empty (invalid) if the program could not be found.
+ /// @throws nothing
+ /// @brief Construct a Program by finding it by name.
+ static Path FindProgramByName(const std::string& name);
+
+ /// This function executes the program using the \p arguments provided and
+ /// waits for the program to exit. This function will block the current
+ /// program until the invoked program exits. The invoked program will
+ /// inherit the stdin, stdout, and stderr file descriptors, the
+ /// environment and other configuration settings of the invoking program.
+ /// If Path::executable() does not return true when this function is
+ /// called then a std::string is thrown.
+ /// @returns an integer result code indicating the status of the program.
+ /// A zero or positive value indicates the result code of the program. A
+ /// negative value is the signal number on which it terminated.
+ /// @see FindProgrambyName
+ /// @brief Executes the program with the given set of \p args.
+ static int ExecuteAndWait(
+ const Path& path, ///< sys::Path object providing the path of the
+ ///< program to be executed. It is presumed this is the result of
+ ///< the FindProgramByName method.
+ const char** args, ///< A vector of strings that are passed to the
+ ///< program. The first element should be the name of the program.
+ ///< The list *must* be terminated by a null char* entry.
+ const char ** env = 0, ///< An optional vector of strings to use for
+ ///< the program's environment. If not provided, the current program's
+ ///< environment will be used.
+ const sys::Path** redirects = 0, ///< An optional array of pointers to
+ ///< Paths. If the array is null, no redirection is done. The array
+ ///< should have a size of at least three. If the pointer in the array
+ ///< are not null, then the inferior process's stdin(0), stdout(1),
+ ///< and stderr(2) will be redirected to the corresponding Paths.
+ unsigned secondsToWait = 0, ///< If non-zero, this specifies the amount
+ ///< of time to wait for the child process to exit. If the time
+ ///< expires, the child is killed and this call returns. If zero,
+ ///< this function will wait until the child finishes or forever if
+ ///< it doesn't.
+ unsigned memoryLimit = 0, ///< If non-zero, this specifies max. amount
+ ///< of memory can be allocated by process. If memory usage will be
+ ///< higher limit, the child is killed and this call returns. If zero -
+ ///< no memory limit.
+ std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string
+ ///< instance in which error messages will be returned. If the string
+ ///< is non-empty upon return an error occurred while invoking the
+ ///< program.
+ );
+ // These methods change the specified standard stream (stdin or stdout) to
+ // binary mode. They return true if an error occurred
+ static bool ChangeStdinToBinary();
+ static bool ChangeStdoutToBinary();
+ /// @}
+ };
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemProgram)
+
+#endif
diff --git a/include/llvm/System/Signals.h b/include/llvm/System/Signals.h
new file mode 100644
index 0000000..f4b8b14
--- /dev/null
+++ b/include/llvm/System/Signals.h
@@ -0,0 +1,55 @@
+//===- llvm/System/Signals.h - Signal Handling support ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines some helpful functions for dealing with the possibility of
+// unix signals occuring while your program is running.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SYSTEM_SIGNALS_H
+#define LLVM_SYSTEM_SIGNALS_H
+
+#include "llvm/System/Path.h"
+#include "llvm/System/IncludeFile.h"
+
+namespace llvm {
+namespace sys {
+
+ /// This function registers signal handlers to ensure that if a signal gets
+ /// delivered that the named file is removed.
+ /// @brief Remove a file if a fatal signal occurs.
+ bool RemoveFileOnSignal(const Path &Filename, std::string* ErrMsg = 0);
+
+ /// This function registers a signal handler to ensure that if a fatal signal
+ /// gets delivered to the process that the named directory and all its
+ /// contents are removed.
+ /// @brief Remove a directory if a fatal signal occurs.
+ bool RemoveDirectoryOnSignal(const Path& path, std::string* ErrMsg = 0);
+
+ /// When an error signal (such as SIBABRT or SIGSEGV) is delivered to the
+ /// process, print a stack trace and then exit.
+ /// @brief Print a stack trace if a fatal signal occurs.
+ void PrintStackTraceOnErrorSignal();
+
+ /// This function registers a function to be called when the user "interrupts"
+ /// the program (typically by pressing ctrl-c). When the user interrupts the
+ /// program, the specified interrupt function is called instead of the program
+ /// being killed, and the interrupt function automatically disabled. Note
+ /// that interrupt functions are not allowed to call any non-reentrant
+ /// functions. An null interrupt function pointer disables the current
+ /// installed function. Note also that the handler may be executed on a
+ /// different thread on some platforms.
+ /// @brief Register a function to be called when ctrl-c is pressed.
+ void SetInterruptFunction(void (*IF)());
+} // End sys namespace
+} // End llvm namespace
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemSignals)
+
+#endif
diff --git a/include/llvm/System/TimeValue.h b/include/llvm/System/TimeValue.h
new file mode 100644
index 0000000..93610b8
--- /dev/null
+++ b/include/llvm/System/TimeValue.h
@@ -0,0 +1,385 @@
+//===-- TimeValue.h - Declare OS TimeValue Concept --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file declares the operating system TimeValue concept.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/DataTypes.h"
+#include "llvm/System/IncludeFile.h"
+#include <string>
+
+#ifndef LLVM_SYSTEM_TIMEVALUE_H
+#define LLVM_SYSTEM_TIMEVALUE_H
+
+namespace llvm {
+namespace sys {
+ /// This class is used where a precise fixed point in time is required. The
+ /// range of TimeValue spans many hundreds of billions of years both past and
+ /// present. The precision of TimeValue is to the nanosecond. However, the
+ /// actual precision of its values will be determined by the resolution of
+ /// the system clock. The TimeValue class is used in conjunction with several
+ /// other lib/System interfaces to specify the time at which a call should
+ /// timeout, etc.
+ /// @since 1.4
+ /// @brief Provides an abstraction for a fixed point in time.
+ class TimeValue {
+
+ /// @name Constants
+ /// @{
+ public:
+
+ /// A constant TimeValue representing the smallest time
+ /// value permissable by the class. MinTime is some point
+ /// in the distant past, about 300 billion years BCE.
+ /// @brief The smallest possible time value.
+ static const TimeValue MinTime;
+
+ /// A constant TimeValue representing the largest time
+ /// value permissable by the class. MaxTime is some point
+ /// in the distant future, about 300 billion years AD.
+ /// @brief The largest possible time value.
+ static const TimeValue MaxTime;
+
+ /// A constant TimeValue representing the base time,
+ /// or zero time of 00:00:00 (midnight) January 1st, 2000.
+ /// @brief 00:00:00 Jan 1, 2000 UTC.
+ static const TimeValue ZeroTime;
+
+ /// A constant TimeValue for the Posix base time which is
+ /// 00:00:00 (midnight) January 1st, 1970.
+ /// @brief 00:00:00 Jan 1, 1970 UTC.
+ static const TimeValue PosixZeroTime;
+
+ /// A constant TimeValue for the Win32 base time which is
+ /// 00:00:00 (midnight) January 1st, 1601.
+ /// @brief 00:00:00 Jan 1, 1601 UTC.
+ static const TimeValue Win32ZeroTime;
+
+ /// @}
+ /// @name Types
+ /// @{
+ public:
+ typedef int64_t SecondsType; ///< Type used for representing seconds.
+ typedef int32_t NanoSecondsType; ///< Type used for representing nanoseconds.
+
+ enum TimeConversions {
+ NANOSECONDS_PER_SECOND = 1000000000, ///< One Billion
+ MICROSECONDS_PER_SECOND = 1000000, ///< One Million
+ MILLISECONDS_PER_SECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MICROSECOND = 1000, ///< One Thousand
+ NANOSECONDS_PER_MILLISECOND = 1000000,///< One Million
+ NANOSECONDS_PER_POSIX_TICK = 100, ///< Posix tick is 100 Hz (10ms)
+ NANOSECONDS_PER_WIN32_TICK = 100 ///< Win32 tick is 100 Hz (10ms)
+ };
+
+ /// @}
+ /// @name Constructors
+ /// @{
+ public:
+ /// Caller provides the exact value in seconds and nanoseconds. The
+ /// \p nanos argument defaults to zero for convenience.
+ /// @brief Explicit constructor
+ explicit TimeValue (SecondsType seconds, NanoSecondsType nanos = 0)
+ : seconds_( seconds ), nanos_( nanos ) { this->normalize(); }
+
+ /// Caller provides the exact value as a double in seconds with the
+ /// fractional part representing nanoseconds.
+ /// @brief Double Constructor.
+ explicit TimeValue( double new_time )
+ : seconds_( 0 ) , nanos_ ( 0 ) {
+ SecondsType integer_part = static_cast<SecondsType>( new_time );
+ seconds_ = integer_part;
+ nanos_ = static_cast<NanoSecondsType>( (new_time -
+ static_cast<double>(integer_part)) * NANOSECONDS_PER_SECOND );
+ this->normalize();
+ }
+
+ /// This is a static constructor that returns a TimeValue that represents
+ /// the current time.
+ /// @brief Creates a TimeValue with the current time (UTC).
+ static TimeValue now();
+
+ /// @}
+ /// @name Operators
+ /// @{
+ public:
+ /// Add \p that to \p this.
+ /// @returns this
+ /// @brief Incrementing assignment operator.
+ TimeValue& operator += (const TimeValue& that ) {
+ this->seconds_ += that.seconds_ ;
+ this->nanos_ += that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Subtract \p that from \p this.
+ /// @returns this
+ /// @brief Decrementing assignment operator.
+ TimeValue& operator -= (const TimeValue &that ) {
+ this->seconds_ -= that.seconds_ ;
+ this->nanos_ -= that.nanos_ ;
+ this->normalize();
+ return *this;
+ }
+
+ /// Determine if \p this is less than \p that.
+ /// @returns True iff *this < that.
+ /// @brief True if this < that.
+ int operator < (const TimeValue &that) const { return that > *this; }
+
+ /// Determine if \p this is greather than \p that.
+ /// @returns True iff *this > that.
+ /// @brief True if this > that.
+ int operator > (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ > that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determine if \p this is less than or equal to \p that.
+ /// @returns True iff *this <= that.
+ /// @brief True if this <= that.
+ int operator <= (const TimeValue &that) const { return that >= *this; }
+
+ /// Determine if \p this is greater than or equal to \p that.
+ /// @returns True iff *this >= that.
+ /// @brief True if this >= that.
+ int operator >= (const TimeValue &that) const {
+ if ( this->seconds_ > that.seconds_ ) {
+ return 1;
+ } else if ( this->seconds_ == that.seconds_ ) {
+ if ( this->nanos_ >= that.nanos_ ) return 1;
+ }
+ return 0;
+ }
+
+ /// Determines if two TimeValue objects represent the same moment in time.
+ /// @brief True iff *this == that.
+ /// @brief True if this == that.
+ int operator == (const TimeValue &that) const {
+ return (this->seconds_ == that.seconds_) &&
+ (this->nanos_ == that.nanos_);
+ }
+
+ /// Determines if two TimeValue objects represent times that are not the
+ /// same.
+ /// @return True iff *this != that.
+ /// @brief True if this != that.
+ int operator != (const TimeValue &that) const { return !(*this == that); }
+
+ /// Adds two TimeValue objects together.
+ /// @returns The sum of the two operands as a new TimeValue
+ /// @brief Addition operator.
+ friend TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// Subtracts two TimeValue objects.
+ /// @returns The difference of the two operands as a new TimeValue
+ /// @brief Subtraction operator.
+ friend TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2);
+
+ /// @}
+ /// @name Accessors
+ /// @{
+ public:
+
+ /// Returns only the seconds component of the TimeValue. The nanoseconds
+ /// portion is ignored. No rounding is performed.
+ /// @brief Retrieve the seconds component
+ SecondsType seconds() const { return seconds_; }
+
+ /// Returns only the nanoseconds component of the TimeValue. The seconds
+ /// portion is ignored.
+ /// @brief Retrieve the nanoseconds component.
+ NanoSecondsType nanoseconds() const { return nanos_; }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest microsecond (divide by one thousand).
+ /// @brief Retrieve the fractional part as microseconds;
+ uint32_t microseconds() const {
+ return nanos_ / NANOSECONDS_PER_MICROSECOND;
+ }
+
+ /// Returns only the fractional portion of the TimeValue rounded down to the
+ /// nearest millisecond (divide by one million).
+ /// @brief Retrieve the fractional part as milliseconds;
+ uint32_t milliseconds() const {
+ return nanos_ / NANOSECONDS_PER_MILLISECOND;
+ }
+
+ /// Returns the TimeValue as a number of microseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of microseconds (can overflow)
+ uint64_t usec() const {
+ return seconds_ * MICROSECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MICROSECOND );
+ }
+
+ /// Returns the TimeValue as a number of milliseconds. Note that the value
+ /// returned can overflow because the range of a uint64_t is smaller than
+ /// the range of a TimeValue. Nevertheless, this is useful on some operating
+ /// systems and is therefore provided.
+ /// @brief Convert to a number of milliseconds (can overflow)
+ uint64_t msec() const {
+ return seconds_ * MILLISECONDS_PER_SECOND +
+ ( nanos_ / NANOSECONDS_PER_MILLISECOND );
+ }
+
+ /// Converts the TimeValue into the corresponding number of "ticks" for
+ /// Posix, correcting for the difference in Posix zero time.
+ /// @brief Convert to unix time (100 nanoseconds since 12:00:00a Jan 1,1970)
+ uint64_t toPosixTime() const {
+ uint64_t result = seconds_ - PosixZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_POSIX_TICK;
+ return result;
+ }
+
+ /// Converts the TimeValue into the corresponding number of seconds
+ /// since the epoch (00:00:00 Jan 1,1970).
+ uint64_t toEpochTime() const {
+ return seconds_ - PosixZeroTime.seconds_;
+ }
+
+ /// Converts the TiemValue into the correspodning number of "ticks" for
+ /// Win32 platforms, correcting for the difference in Win32 zero time.
+ /// @brief Convert to windows time (seconds since 12:00:00a Jan 1, 1601)
+ uint64_t toWin32Time() const {
+ uint64_t result = seconds_ - Win32ZeroTime.seconds_;
+ result += nanos_ / NANOSECONDS_PER_WIN32_TICK;
+ return result;
+ }
+
+ /// Provides the seconds and nanoseconds as results in its arguments after
+ /// correction for the Posix zero time.
+ /// @brief Convert to timespec time (ala POSIX.1b)
+ void getTimespecTime( uint64_t& seconds, uint32_t& nanos ) const {
+ seconds = seconds_ - PosixZeroTime.seconds_;
+ nanos = nanos_;
+ }
+
+ /// Provides conversion of the TimeValue into a readable time & date.
+ /// @returns std::string containing the readable time value
+ /// @brief Convert time to a string.
+ std::string toString() const;
+
+ /// @}
+ /// @name Mutators
+ /// @{
+ public:
+ /// The seconds component of the TimeValue is set to \p sec without
+ /// modifying the nanoseconds part. This is useful for whole second
+ /// arithmetic.
+ /// @brief Set the seconds component.
+ void seconds (SecondsType sec ) {
+ this->seconds_ = sec;
+ this->normalize();
+ }
+
+ /// The nanoseconds component of the TimeValue is set to \p nanos without
+ /// modifying the seconds part. This is useful for basic computations
+ /// involving just the nanoseconds portion. Note that the TimeValue will be
+ /// normalized after this call so that the fractional (nanoseconds) portion
+ /// will have the smallest equivalent value.
+ /// @brief Set the nanoseconds component using a number of nanoseconds.
+ void nanoseconds ( NanoSecondsType nanos ) {
+ this->nanos_ = nanos;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of microseconds.
+ void microseconds ( int32_t micros ) {
+ this->nanos_ = micros * NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// The seconds component remains unchanged.
+ /// @brief Set the nanoseconds component using a number of milliseconds.
+ void milliseconds ( int32_t millis ) {
+ this->nanos_ = millis * NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from microsecond format to TimeValue format
+ void usec( int64_t microseconds ) {
+ this->seconds_ = microseconds / MICROSECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(microseconds % MICROSECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MICROSECOND;
+ this->normalize();
+ }
+
+ /// @brief Converts from millisecond format to TimeValue format
+ void msec( int64_t milliseconds ) {
+ this->seconds_ = milliseconds / MILLISECONDS_PER_SECOND;
+ this->nanos_ = NanoSecondsType(milliseconds % MILLISECONDS_PER_SECOND) *
+ NANOSECONDS_PER_MILLISECOND;
+ this->normalize();
+ }
+
+ /// Converts the \p seconds argument from PosixTime to the corresponding
+ /// TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form PosixTime to TimeValue
+ void fromEpochTime( SecondsType seconds ) {
+ seconds_ = seconds + PosixZeroTime.seconds_;
+ nanos_ = 0;
+ this->normalize();
+ }
+
+ /// Converts the \p win32Time argument from Windows FILETIME to the
+ /// corresponding TimeValue and assigns that value to \p this.
+ /// @brief Convert seconds form Windows FILETIME to TimeValue
+ void fromWin32Time( uint64_t win32Time ) {
+ this->seconds_ = win32Time / 10000000 + Win32ZeroTime.seconds_;
+ this->nanos_ = NanoSecondsType(win32Time % 10000000) * 100;
+ }
+
+ /// @}
+ /// @name Implementation
+ /// @{
+ private:
+ /// This causes the values to be represented so that the fractional
+ /// part is minimized, possibly incrementing the seconds part.
+ /// @brief Normalize to canonical form.
+ void normalize();
+
+ /// @}
+ /// @name Data
+ /// @{
+ private:
+ /// Store the values as a <timeval>.
+ SecondsType seconds_;///< Stores the seconds part of the TimeVal
+ NanoSecondsType nanos_; ///< Stores the nanoseconds part of the TimeVal
+ /// @}
+
+ };
+
+inline TimeValue operator + (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue sum (tv1.seconds_ + tv2.seconds_, tv1.nanos_ + tv2.nanos_);
+ sum.normalize ();
+ return sum;
+}
+
+inline TimeValue operator - (const TimeValue &tv1, const TimeValue &tv2) {
+ TimeValue difference (tv1.seconds_ - tv2.seconds_, tv1.nanos_ - tv2.nanos_ );
+ difference.normalize ();
+ return difference;
+}
+
+}
+}
+
+FORCE_DEFINING_FILE_TO_BE_LINKED(SystemTimeValue)
+
+#endif
diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h
new file mode 100644
index 0000000..d2b76b8
--- /dev/null
+++ b/include/llvm/Target/MRegisterInfo.h
@@ -0,0 +1,624 @@
+//===- Target/MRegisterInfo.h - Target Register Information -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes an abstract interface used to get information about a
+// target machines register file. This information is used for a variety of
+// purposed, especially register allocation.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_MREGISTERINFO_H
+#define LLVM_TARGET_MREGISTERINFO_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/ValueTypes.h"
+#include <cassert>
+#include <functional>
+
+namespace llvm {
+
+class BitVector;
+class CalleeSavedInfo;
+class MachineFunction;
+class MachineInstr;
+class MachineLocation;
+class MachineMove;
+class RegScavenger;
+class TargetRegisterClass;
+class Type;
+
+/// TargetRegisterDesc - This record contains all of the information known about
+/// a particular register. The AliasSet field (if not null) contains a pointer
+/// to a Zero terminated array of registers that this register aliases. This is
+/// needed for architectures like X86 which have AL alias AX alias EAX.
+/// Registers that this does not apply to simply should set this to null.
+/// The SubRegs field is a zero terminated array of registers that are
+/// sub-registers of the specific register, e.g. AL, AH are sub-registers of AX.
+/// The ImmsubRegs field is a subset of SubRegs. It includes only the immediate
+/// sub-registers. e.g. EAX has only one immediate sub-register of AX, not AH,
+/// AL which are immediate sub-registers of AX. The SuperRegs field is a zero
+/// terminated array of registers that are super-registers of the specific
+/// register, e.g. RAX, EAX, are super-registers of AX.
+///
+struct TargetRegisterDesc {
+ const char *Name; // Assembly language name for the register
+ const unsigned *AliasSet; // Register Alias Set, described above
+ const unsigned *SubRegs; // Sub-register set, described above
+ const unsigned *ImmSubRegs; // Immediate sub-register set, described above
+ const unsigned *SuperRegs; // Super-register set, described above
+};
+
+class TargetRegisterClass {
+public:
+ typedef const unsigned* iterator;
+ typedef const unsigned* const_iterator;
+
+ typedef const MVT::ValueType* vt_iterator;
+ typedef const TargetRegisterClass* const * sc_iterator;
+private:
+ unsigned ID;
+ bool isSubClass;
+ const vt_iterator VTs;
+ const sc_iterator SubClasses;
+ const sc_iterator SuperClasses;
+ const sc_iterator SubRegClasses;
+ const unsigned RegSize, Alignment; // Size & Alignment of register in bytes
+ const iterator RegsBegin, RegsEnd;
+public:
+ TargetRegisterClass(unsigned id,
+ const MVT::ValueType *vts,
+ const TargetRegisterClass * const *subcs,
+ const TargetRegisterClass * const *supcs,
+ const TargetRegisterClass * const *subregcs,
+ unsigned RS, unsigned Al, iterator RB, iterator RE)
+ : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs),
+ SubRegClasses(subregcs),
+ RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {}
+ virtual ~TargetRegisterClass() {} // Allow subclasses
+
+ /// getID() - Return the register class ID number.
+ ///
+ unsigned getID() const { return ID; }
+
+ /// begin/end - Return all of the registers in this class.
+ ///
+ iterator begin() const { return RegsBegin; }
+ iterator end() const { return RegsEnd; }
+
+ /// getNumRegs - Return the number of registers in this class.
+ ///
+ unsigned getNumRegs() const { return RegsEnd-RegsBegin; }
+
+ /// getRegister - Return the specified register in the class.
+ ///
+ unsigned getRegister(unsigned i) const {
+ assert(i < getNumRegs() && "Register number out of range!");
+ return RegsBegin[i];
+ }
+
+ /// contains - Return true if the specified register is included in this
+ /// register class.
+ bool contains(unsigned Reg) const {
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (*I == Reg) return true;
+ return false;
+ }
+
+ /// hasType - return true if this TargetRegisterClass has the ValueType vt.
+ ///
+ bool hasType(MVT::ValueType vt) const {
+ for(int i = 0; VTs[i] != MVT::Other; ++i)
+ if (VTs[i] == vt)
+ return true;
+ return false;
+ }
+
+ /// vt_begin / vt_end - Loop over all of the value types that can be
+ /// represented by values in this register class.
+ vt_iterator vt_begin() const {
+ return VTs;
+ }
+
+ vt_iterator vt_end() const {
+ vt_iterator I = VTs;
+ while (*I != MVT::Other) ++I;
+ return I;
+ }
+
+ /// hasSubRegClass - return true if the specified TargetRegisterClass is a
+ /// sub-register class of this TargetRegisterClass.
+ bool hasSubRegClass(const TargetRegisterClass *cs) const {
+ for (int i = 0; SubClasses[i] != NULL; ++i)
+ if (SubClasses[i] == cs)
+ return true;
+ return false;
+ }
+
+ /// subclasses_begin / subclasses_end - Loop over all of the sub-classes of
+ /// this register class.
+ sc_iterator subclasses_begin() const {
+ return SubClasses;
+ }
+
+ sc_iterator subclasses_end() const {
+ sc_iterator I = SubClasses;
+ while (*I != NULL) ++I;
+ return I;
+ }
+
+ /// hasSuperRegClass - return true if the specified TargetRegisterClass is a
+ /// super-register class of this TargetRegisterClass.
+ bool hasSuperRegClass(const TargetRegisterClass *cs) const {
+ for (int i = 0; SuperClasses[i] != NULL; ++i)
+ if (SuperClasses[i] == cs)
+ return true;
+ return false;
+ }
+
+ /// superclasses_begin / superclasses_end - Loop over all of the super-classes
+ /// of this register class.
+ sc_iterator superclasses_begin() const {
+ return SuperClasses;
+ }
+
+ sc_iterator superclasses_end() const {
+ sc_iterator I = SuperClasses;
+ while (*I != NULL) ++I;
+ return I;
+ }
+
+ /// hasSubRegForClass - return true if the specified TargetRegisterClass is a
+ /// class of a sub-register class for this TargetRegisterClass.
+ bool hasSubRegForClass(const TargetRegisterClass *cs) const {
+ for (int i = 0; SubRegClasses[i] != NULL; ++i)
+ if (SubRegClasses[i] == cs)
+ return true;
+ return false;
+ }
+
+ /// hasClassForSubReg - return true if the specified TargetRegisterClass is a
+ /// class of a sub-register class for this TargetRegisterClass.
+ bool hasClassForSubReg(unsigned SubReg) const {
+ --SubReg;
+ for (unsigned i = 0; SubRegClasses[i] != NULL; ++i)
+ if (i == SubReg)
+ return true;
+ return false;
+ }
+
+ /// getClassForSubReg - return theTargetRegisterClass for the sub-register
+ /// at idx for this TargetRegisterClass.
+ sc_iterator getClassForSubReg(unsigned SubReg) const {
+ --SubReg;
+ for (unsigned i = 0; SubRegClasses[i] != NULL; ++i)
+ if (i == SubReg)
+ return &SubRegClasses[i];
+ return NULL;
+ }
+
+ /// subregclasses_begin / subregclasses_end - Loop over all of
+ /// the subregister classes of this register class.
+ sc_iterator subregclasses_begin() const {
+ return SubRegClasses;
+ }
+
+ sc_iterator subregclasses_end() const {
+ sc_iterator I = SubRegClasses;
+ while (*I != NULL) ++I;
+ return I;
+ }
+
+ /// allocation_order_begin/end - These methods define a range of registers
+ /// which specify the registers in this class that are valid to register
+ /// allocate, and the preferred order to allocate them in. For example,
+ /// callee saved registers should be at the end of the list, because it is
+ /// cheaper to allocate caller saved registers.
+ ///
+ /// These methods take a MachineFunction argument, which can be used to tune
+ /// the allocatable registers based on the characteristics of the function.
+ /// One simple example is that the frame pointer register can be used if
+ /// frame-pointer-elimination is performed.
+ ///
+ /// By default, these methods return all registers in the class.
+ ///
+ virtual iterator allocation_order_begin(const MachineFunction &MF) const {
+ return begin();
+ }
+ virtual iterator allocation_order_end(const MachineFunction &MF) const {
+ return end();
+ }
+
+
+
+ /// getSize - Return the size of the register in bytes, which is also the size
+ /// of a stack slot allocated to hold a spilled copy of this register.
+ unsigned getSize() const { return RegSize; }
+
+ /// getAlignment - Return the minimum required alignment for a register of
+ /// this class.
+ unsigned getAlignment() const { return Alignment; }
+};
+
+
+/// MRegisterInfo base class - We assume that the target defines a static array
+/// of TargetRegisterDesc objects that represent all of the machine registers
+/// that the target has. As such, we simply have to track a pointer to this
+/// array so that we can turn register number into a register descriptor.
+///
+class MRegisterInfo {
+public:
+ typedef const TargetRegisterClass * const * regclass_iterator;
+private:
+ const TargetRegisterDesc *Desc; // Pointer to the descriptor array
+ unsigned NumRegs; // Number of entries in the array
+
+ regclass_iterator RegClassBegin, RegClassEnd; // List of regclasses
+
+ int CallFrameSetupOpcode, CallFrameDestroyOpcode;
+protected:
+ MRegisterInfo(const TargetRegisterDesc *D, unsigned NR,
+ regclass_iterator RegClassBegin, regclass_iterator RegClassEnd,
+ int CallFrameSetupOpcode = -1, int CallFrameDestroyOpcode = -1);
+ virtual ~MRegisterInfo();
+public:
+
+ enum { // Define some target independent constants
+ /// NoRegister - This physical register is not a real target register. It
+ /// is useful as a sentinal.
+ NoRegister = 0,
+
+ /// FirstVirtualRegister - This is the first register number that is
+ /// considered to be a 'virtual' register, which is part of the SSA
+ /// namespace. This must be the same for all targets, which means that each
+ /// target is limited to 1024 registers.
+ FirstVirtualRegister = 1024
+ };
+
+ /// isPhysicalRegister - Return true if the specified register number is in
+ /// the physical register namespace.
+ static bool isPhysicalRegister(unsigned Reg) {
+ assert(Reg && "this is not a register!");
+ return Reg < FirstVirtualRegister;
+ }
+
+ /// isVirtualRegister - Return true if the specified register number is in
+ /// the virtual register namespace.
+ static bool isVirtualRegister(unsigned Reg) {
+ assert(Reg && "this is not a register!");
+ return Reg >= FirstVirtualRegister;
+ }
+
+ /// getAllocatableSet - Returns a bitset indexed by register number
+ /// indicating if a register is allocatable or not. If a register class is
+ /// specified, returns the subset for the class.
+ BitVector getAllocatableSet(MachineFunction &MF,
+ const TargetRegisterClass *RC = NULL) const;
+
+ const TargetRegisterDesc &operator[](unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to access record for invalid register number!");
+ return Desc[RegNo];
+ }
+
+ /// Provide a get method, equivalent to [], but more useful if we have a
+ /// pointer to this object.
+ ///
+ const TargetRegisterDesc &get(unsigned RegNo) const {
+ return operator[](RegNo);
+ }
+
+ /// getAliasSet - Return the set of registers aliased by the specified
+ /// register, or a null list of there are none. The list returned is zero
+ /// terminated.
+ ///
+ const unsigned *getAliasSet(unsigned RegNo) const {
+ return get(RegNo).AliasSet;
+ }
+
+ /// getSubRegisters - Return the set of registers that are sub-registers of
+ /// the specified register, or a null list of there are none. The list
+ /// returned is zero terminated.
+ ///
+ const unsigned *getSubRegisters(unsigned RegNo) const {
+ return get(RegNo).SubRegs;
+ }
+
+ /// getImmediateSubRegisters - Return the set of registers that are immediate
+ /// sub-registers of the specified register, or a null list of there are none.
+ /// The list returned is zero terminated.
+ ///
+ const unsigned *getImmediateSubRegisters(unsigned RegNo) const {
+ return get(RegNo).ImmSubRegs;
+ }
+
+ /// getSuperRegisters - Return the set of registers that are super-registers
+ /// of the specified register, or a null list of there are none. The list
+ /// returned is zero terminated.
+ ///
+ const unsigned *getSuperRegisters(unsigned RegNo) const {
+ return get(RegNo).SuperRegs;
+ }
+
+ /// getName - Return the symbolic target specific name for the specified
+ /// physical register.
+ const char *getName(unsigned RegNo) const {
+ return get(RegNo).Name;
+ }
+
+ /// getNumRegs - Return the number of registers this target has
+ /// (useful for sizing arrays holding per register information)
+ unsigned getNumRegs() const {
+ return NumRegs;
+ }
+
+ /// areAliases - Returns true if the two registers alias each other,
+ /// false otherwise
+ bool areAliases(unsigned regA, unsigned regB) const {
+ for (const unsigned *Alias = getAliasSet(regA); *Alias; ++Alias)
+ if (*Alias == regB) return true;
+ return false;
+ }
+
+ /// regsOverlap - Returns true if the two registers are equal or alias
+ /// each other. The registers may be virtual register.
+ bool regsOverlap(unsigned regA, unsigned regB) const {
+ if (regA == regB)
+ return true;
+
+ if (isVirtualRegister(regA) || isVirtualRegister(regB))
+ return false;
+ return areAliases(regA, regB);
+ }
+
+ /// isSubRegister - Returns true if regB is a sub-register of regA.
+ ///
+ bool isSubRegister(unsigned regA, unsigned regB) const {
+ for (const unsigned *SR = getSubRegisters(regA); *SR; ++SR)
+ if (*SR == regB) return true;
+ return false;
+ }
+
+ /// isSuperRegister - Returns true if regB is a super-register of regA.
+ ///
+ bool isSuperRegister(unsigned regA, unsigned regB) const {
+ for (const unsigned *SR = getSuperRegisters(regA); *SR; ++SR)
+ if (*SR == regB) return true;
+ return false;
+ }
+
+ /// getCalleeSavedRegs - Return a null-terminated list of all of the
+ /// callee saved registers on this target. The register should be in the
+ /// order of desired callee-save stack frame offset. The first register is
+ /// closed to the incoming stack pointer if stack grows down, and vice versa.
+ virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF = 0)
+ const = 0;
+
+ /// getCalleeSavedRegClasses - Return a null-terminated list of the preferred
+ /// register classes to spill each callee saved register with. The order and
+ /// length of this list match the getCalleeSaveRegs() list.
+ virtual const TargetRegisterClass* const *getCalleeSavedRegClasses(
+ const MachineFunction *MF) const =0;
+
+ /// getReservedRegs - Returns a bitset indexed by physical register number
+ /// indicating if a register is a special register that has particular uses and
+ /// should be considered unavailable at all times, e.g. SP, RA. This is used by
+ /// register scavenger to determine what registers are free.
+ virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0;
+
+ /// getSubReg - Returns the physical register number of sub-register "Index"
+ /// for physical register RegNo.
+ virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ // Register Class Information
+ //
+
+ /// Register class iterators
+ ///
+ regclass_iterator regclass_begin() const { return RegClassBegin; }
+ regclass_iterator regclass_end() const { return RegClassEnd; }
+
+ unsigned getNumRegClasses() const {
+ return regclass_end()-regclass_begin();
+ }
+
+ /// getRegClass - Returns the register class associated with the enumeration
+ /// value. See class TargetOperandInfo.
+ const TargetRegisterClass *getRegClass(unsigned i) const {
+ assert(i <= getNumRegClasses() && "Register Class ID out of range");
+ return i ? RegClassBegin[i - 1] : NULL;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // Interfaces used by the register allocator and stack frame
+ // manipulation passes to move data around between registers,
+ // immediates and memory. FIXME: Move these to TargetInstrInfo.h.
+ //
+
+ /// spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved
+ /// registers and returns true if it isn't possible / profitable to do so by
+ /// issuing a series of store instructions via storeRegToStackSlot(). Returns
+ /// false otherwise.
+ virtual bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI) const {
+ return false;
+ }
+
+ /// restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee
+ /// saved registers and returns true if it isn't possible / profitable to do
+ /// so by issuing a series of load instructions via loadRegToStackSlot().
+ /// Returns false otherwise.
+ virtual bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ const std::vector<CalleeSavedInfo> &CSI) const {
+ return false;
+ }
+
+ virtual void storeRegToStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned SrcReg, int FrameIndex,
+ const TargetRegisterClass *RC) const = 0;
+
+ virtual void loadRegFromStackSlot(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, int FrameIndex,
+ const TargetRegisterClass *RC) const = 0;
+
+ virtual void copyRegToReg(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg, unsigned SrcReg,
+ const TargetRegisterClass *RC) const = 0;
+
+ /// reMaterialize - Re-issue the specified 'original' instruction at the
+ /// specific location targeting a new destination register.
+ virtual void reMaterialize(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI,
+ unsigned DestReg,
+ const MachineInstr *Orig) const = 0;
+
+ /// foldMemoryOperand - Attempt to fold a load or store of the
+ /// specified stack slot into the specified machine instruction for
+ /// the specified operand. If this is possible, a new instruction
+ /// is returned with the specified operand folded, otherwise NULL is
+ /// returned. The client is responsible for removing the old
+ /// instruction and adding the new one in the instruction stream
+ virtual MachineInstr* foldMemoryOperand(MachineInstr* MI,
+ unsigned OpNum,
+ int FrameIndex) const {
+ return 0;
+ }
+
+ /// targetHandlesStackFrameRounding - Returns true if the target is responsible
+ /// for rounding up the stack frame (probably at emitPrologue time).
+ virtual bool targetHandlesStackFrameRounding() const {
+ return false;
+ }
+
+ /// requiresRegisterScavenging - returns true if the target requires (and
+ /// can make use of) the register scavenger.
+ virtual bool requiresRegisterScavenging(const MachineFunction &MF) const {
+ return false;
+ }
+
+ /// hasFP - Return true if the specified function should have a dedicated frame
+ /// pointer register. For most targets this is true only if the function has
+ /// variable sized allocas or if frame pointer elimination is disabled.
+ virtual bool hasFP(const MachineFunction &MF) const = 0;
+
+ // hasReservedCallFrame - Under normal circumstances, when a frame pointer is
+ // not required, we reserve argument space for call sites in the function
+ // immediately on entry to the current function. This eliminates the need for
+ // add/sub sp brackets around call sites. Returns true if the call frame is
+ // included as part of the stack frame.
+ virtual bool hasReservedCallFrame(MachineFunction &MF) const {
+ return !hasFP(MF);
+ }
+
+ /// getCallFrameSetup/DestroyOpcode - These methods return the opcode of the
+ /// frame setup/destroy instructions if they exist (-1 otherwise). Some
+ /// targets use pseudo instructions in order to abstract away the difference
+ /// between operating with a frame pointer and operating without, through the
+ /// use of these two instructions.
+ ///
+ int getCallFrameSetupOpcode() const { return CallFrameSetupOpcode; }
+ int getCallFrameDestroyOpcode() const { return CallFrameDestroyOpcode; }
+
+
+ /// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
+ /// code insertion to eliminate call frame setup and destroy pseudo
+ /// instructions (but only if the Target is using them). It is responsible
+ /// for eliminating these instructions, replacing them with concrete
+ /// instructions. This method need only be implemented if using call frame
+ /// setup/destroy pseudo instructions.
+ ///
+ virtual void
+ eliminateCallFramePseudoInstr(MachineFunction &MF,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ assert(getCallFrameSetupOpcode()== -1 && getCallFrameDestroyOpcode()== -1 &&
+ "eliminateCallFramePseudoInstr must be implemented if using"
+ " call frame setup/destroy pseudo instructions!");
+ assert(0 && "Call Frame Pseudo Instructions do not exist on this target!");
+ }
+
+ /// processFunctionBeforeCalleeSavedScan - This method is called immediately
+ /// before PrologEpilogInserter scans the physical registers used to determine
+ /// what callee saved registers should be spilled. This method is optional.
+ virtual void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS = NULL) const {
+
+ }
+
+ /// processFunctionBeforeFrameFinalized - This method is called immediately
+ /// before the specified functions frame layout (MF.getFrameInfo()) is
+ /// finalized. Once the frame is finalized, MO_FrameIndex operands are
+ /// replaced with direct constants. This method is optional.
+ ///
+ virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
+ }
+
+ /// eliminateFrameIndex - This method must be overriden to eliminate abstract
+ /// frame indices from instructions which may use them. The instruction
+ /// referenced by the iterator contains an MO_FrameIndex operand which must be
+ /// eliminated by this method. This method may modify or replace the
+ /// specified instruction, as long as it keeps the iterator pointing the the
+ /// finished product. SPAdj is the SP adjustment due to call frame setup
+ /// instruction. The return value is the number of instructions added to
+ /// (negative if removed from) the basic block.
+ ///
+ virtual void eliminateFrameIndex(MachineBasicBlock::iterator MI,
+ int SPAdj, RegScavenger *RS=NULL) const = 0;
+
+ /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
+ /// the function. The return value is the number of instructions
+ /// added to (negative if removed from) the basic block (entry for prologue).
+ ///
+ virtual void emitPrologue(MachineFunction &MF) const = 0;
+ virtual void emitEpilogue(MachineFunction &MF,
+ MachineBasicBlock &MBB) const = 0;
+
+ //===--------------------------------------------------------------------===//
+ /// Debug information queries.
+
+ /// getDwarfRegNum - Map a target register to an equivalent dwarf register
+ /// number. Returns -1 if there is no equivalent value.
+ virtual int getDwarfRegNum(unsigned RegNum) const = 0;
+
+ /// getFrameRegister - This method should return the register used as a base
+ /// for values allocated in the current stack frame.
+ virtual unsigned getFrameRegister(MachineFunction &MF) const = 0;
+
+ /// getRARegister - This method should return the register where the return
+ /// address can be found.
+ virtual unsigned getRARegister() const = 0;
+
+ /// getLocation - This method should return the actual location of a frame
+ /// variable given the frame index. The location is returned in ML.
+ /// Subclasses should override this method for special handling of frame
+ /// variables and call MRegisterInfo::getLocation for the default action.
+ virtual void getLocation(MachineFunction &MF, unsigned Index,
+ MachineLocation &ML) const;
+
+ /// getInitialFrameState - Returns a list of machine moves that are assumed
+ /// on entry to all functions. Note that LabelID is ignored (assumed to be
+ /// the beginning of the function.)
+ virtual void getInitialFrameState(std::vector<MachineMove> &Moves) const;
+};
+
+// This is useful when building IndexedMaps keyed on virtual registers
+struct VirtReg2IndexFunctor : std::unary_function<unsigned, unsigned> {
+ unsigned operator()(unsigned Reg) const {
+ return Reg - MRegisterInfo::FirstVirtualRegister;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/SubtargetFeature.h b/include/llvm/Target/SubtargetFeature.h
new file mode 100644
index 0000000..e809fc0
--- /dev/null
+++ b/include/llvm/Target/SubtargetFeature.h
@@ -0,0 +1,110 @@
+//===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines and manages user or tool specified CPU characteristics.
+// The intent is to be able to package specific features that should or should
+// not be used on a specific target processor. A tool, such as llc, could, as
+// as example, gather chip info from the command line, a long with features
+// that should be used on that chip.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_SUBTARGETFEATURE_H
+#define LLVM_TARGET_SUBTARGETFEATURE_H
+
+#include <string>
+#include <vector>
+#include <iosfwd>
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatureKV - Used to provide key value pairs for feature and
+/// CPU bit flags.
+//
+struct SubtargetFeatureKV {
+ const char *Key; // K-V key string
+ const char *Desc; // Help descriptor
+ uint32_t Value; // K-V integer value
+ uint32_t Implies; // K-V bit mask
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetFeatureKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
+/// pointers.
+//
+struct SubtargetInfoKV {
+ const char *Key; // K-V key string
+ void *Value; // K-V pointer value
+
+ // Compare routine for std binary search
+ bool operator<(const SubtargetInfoKV &S) const {
+ return strcmp(Key, S.Key) < 0;
+ }
+};
+
+//===----------------------------------------------------------------------===//
+///
+/// SubtargetFeatures - Manages the enabling and disabling of subtarget
+/// specific features. Features are encoded as a string of the form
+/// "cpu,+attr1,+attr2,-attr3,...,+attrN"
+/// A comma separates each feature from the next (all lowercase.)
+/// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
+/// value is "generic" then the CPU subtype should be generic for the target.
+/// Each of the remaining features is prefixed with + or - indicating whether
+/// that feature should be enabled or disabled contrary to the cpu
+/// specification.
+///
+
+class SubtargetFeatures {
+ std::vector<std::string> Features; // Subtarget features as a vector
+public:
+ SubtargetFeatures(const std::string &Initial = std::string());
+
+ /// Features string accessors.
+ std::string getString() const;
+ void setString(const std::string &Initial);
+
+ /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
+ void setCPU(const std::string &String);
+
+ /// Setting CPU string only if no string is set.
+ void setCPUIfNone(const std::string &String);
+
+ /// Adding Features.
+ void AddFeature(const std::string &String, bool IsEnabled = true);
+
+ /// Get feature bits.
+ uint32_t getBits(const SubtargetFeatureKV *CPUTable,
+ size_t CPUTableSize,
+ const SubtargetFeatureKV *FeatureTable,
+ size_t FeatureTableSize);
+
+ /// Get info pointer
+ void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
+
+ /// Print feature string.
+ void print(std::ostream &OS) const;
+ void print(std::ostream *OS) const { if (OS) print(*OS); }
+
+ // Dump feature info.
+ void dump() const;
+};
+
+} // End namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h
new file mode 100644
index 0000000..4e6d3b9
--- /dev/null
+++ b/include/llvm/Target/TargetAsmInfo.h
@@ -0,0 +1,615 @@
+//===-- llvm/Target/TargetAsmInfo.h - Asm info ------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains a class to be used as the basis for target specific
+// asm writers. This class primarily takes care of global printing constants,
+// which are used in very similar ways across all targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_ASM_INFO_H
+#define LLVM_TARGET_ASM_INFO_H
+
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ class TargetMachine;
+ class CallInst;
+
+ /// TargetAsmInfo - This class is intended to be used as a base class for asm
+ /// properties and features specific to the target.
+ class TargetAsmInfo {
+ protected:
+ //===------------------------------------------------------------------===//
+ // Properties to be set by the target writer, used to configure asm printer.
+ //
+
+ /// TextSection - Section directive for standard text.
+ ///
+ const char *TextSection; // Defaults to ".text".
+
+ /// DataSection - Section directive for standard data.
+ ///
+ const char *DataSection; // Defaults to ".data".
+
+ /// BSSSection - Section directive for uninitialized data. Null if this
+ /// target doesn't support a BSS section.
+ ///
+ const char *BSSSection; // Default to ".bss".
+
+ /// TLSDataSection - Section directive for Thread Local data.
+ ///
+ const char *TLSDataSection;// Defaults to ".section .tdata,"awT",@progbits".
+
+ /// TLSBSSSection - Section directive for Thread Local uninitialized data.
+ /// Null if this target doesn't support a BSS section.
+ ///
+ const char *TLSBSSSection;// Default to ".section .tbss,"awT",@nobits".
+ /// ZeroFillDirective - Directive for emitting a global to the ZeroFill
+ /// section on this target. Null if this target doesn't support zerofill.
+ const char *ZeroFillDirective; // Default is null.
+
+ /// AddressSize - Size of addresses used in file.
+ ///
+ unsigned AddressSize; // Defaults to 4.
+
+ /// NeedsSet - True if target asm can't compute addresses on data
+ /// directives.
+ bool NeedsSet; // Defaults to false.
+
+ /// MaxInstLength - This is the maximum possible length of an instruction,
+ /// which is needed to compute the size of an inline asm.
+ unsigned MaxInstLength; // Defaults to 4.
+
+ /// PCSymbol - The symbol used to represent the current PC. Used in PC
+ /// relative expressions.
+ const char *PCSymbol; // Defaults to "$".
+
+ /// SeparatorChar - This character, if specified, is used to separate
+ /// instructions from each other when on the same line. This is used to
+ /// measure inline asm instructions.
+ char SeparatorChar; // Defaults to ';'
+
+ /// CommentString - This indicates the comment character used by the
+ /// assembler.
+ const char *CommentString; // Defaults to "#"
+
+ /// GlobalPrefix - If this is set to a non-empty string, it is prepended
+ /// onto all global symbols. This is often used for "_" or ".".
+ const char *GlobalPrefix; // Defaults to ""
+
+ /// PrivateGlobalPrefix - This prefix is used for globals like constant
+ /// pool entries that are completely private to the .o file and should not
+ /// have names in the .o file. This is often "." or "L".
+ const char *PrivateGlobalPrefix; // Defaults to "."
+
+ /// JumpTableSpecialLabelPrefix - If not null, a extra (dead) label is
+ /// emitted before jump tables with the specified prefix.
+ const char *JumpTableSpecialLabelPrefix; // Default to null.
+
+ /// GlobalVarAddrPrefix/Suffix - If these are nonempty, these strings
+ /// will enclose any GlobalVariable (that isn't a function)
+ ///
+ const char *GlobalVarAddrPrefix; // Defaults to ""
+ const char *GlobalVarAddrSuffix; // Defaults to ""
+
+ /// FunctionAddrPrefix/Suffix - If these are nonempty, these strings
+ /// will enclose any GlobalVariable that points to a function.
+ /// For example, this is used by the IA64 backend to materialize
+ /// function descriptors, by decorating the ".data8" object with the
+ /// \literal @fptr( ) \endliteral
+ /// link-relocation operator.
+ ///
+ const char *FunctionAddrPrefix; // Defaults to ""
+ const char *FunctionAddrSuffix; // Defaults to ""
+
+ /// InlineAsmStart/End - If these are nonempty, they contain a directive to
+ /// emit before and after an inline assembly statement.
+ const char *InlineAsmStart; // Defaults to "#APP\n"
+ const char *InlineAsmEnd; // Defaults to "#NO_APP\n"
+
+ /// AssemblerDialect - Which dialect of an assembler variant to use.
+ unsigned AssemblerDialect; // Defaults to 0
+
+ //===--- Data Emission Directives -------------------------------------===//
+
+ /// ZeroDirective - this should be set to the directive used to get some
+ /// number of zero bytes emitted to the current section. Common cases are
+ /// "\t.zero\t" and "\t.space\t". If this is set to null, the
+ /// Data*bitsDirective's will be used to emit zero bytes.
+ const char *ZeroDirective; // Defaults to "\t.zero\t"
+ const char *ZeroDirectiveSuffix; // Defaults to ""
+
+ /// AsciiDirective - This directive allows emission of an ascii string with
+ /// the standard C escape characters embedded into it.
+ const char *AsciiDirective; // Defaults to "\t.ascii\t"
+
+ /// AscizDirective - If not null, this allows for special handling of
+ /// zero terminated strings on this target. This is commonly supported as
+ /// ".asciz". If a target doesn't support this, it can be set to null.
+ const char *AscizDirective; // Defaults to "\t.asciz\t"
+
+ /// DataDirectives - These directives are used to output some unit of
+ /// integer data to the current section. If a data directive is set to
+ /// null, smaller data directives will be used to emit the large sizes.
+ const char *Data8bitsDirective; // Defaults to "\t.byte\t"
+ const char *Data16bitsDirective; // Defaults to "\t.short\t"
+ const char *Data32bitsDirective; // Defaults to "\t.long\t"
+ const char *Data64bitsDirective; // Defaults to "\t.quad\t"
+
+ //===--- Alignment Information ----------------------------------------===//
+
+ /// AlignDirective - The directive used to emit round up to an alignment
+ /// boundary.
+ ///
+ const char *AlignDirective; // Defaults to "\t.align\t"
+
+ /// AlignmentIsInBytes - If this is true (the default) then the asmprinter
+ /// emits ".align N" directives, where N is the number of bytes to align to.
+ /// Otherwise, it emits ".align log2(N)", e.g. 3 to align to an 8 byte
+ /// boundary.
+ bool AlignmentIsInBytes; // Defaults to true
+
+ //===--- Section Switching Directives ---------------------------------===//
+
+ /// SwitchToSectionDirective - This is the directive used when we want to
+ /// emit a global to an arbitrary section. The section name is emited after
+ /// this.
+ const char *SwitchToSectionDirective; // Defaults to "\t.section\t"
+
+ /// TextSectionStartSuffix - This is printed after each start of section
+ /// directive for text sections.
+ const char *TextSectionStartSuffix; // Defaults to "".
+
+ /// DataSectionStartSuffix - This is printed after each start of section
+ /// directive for data sections.
+ const char *DataSectionStartSuffix; // Defaults to "".
+
+ /// SectionEndDirectiveSuffix - If non-null, the asm printer will close each
+ /// section with the section name and this suffix printed.
+ const char *SectionEndDirectiveSuffix;// Defaults to null.
+
+ /// ConstantPoolSection - This is the section that we SwitchToSection right
+ /// before emitting the constant pool for a function.
+ const char *ConstantPoolSection; // Defaults to "\t.section .rodata"
+
+ /// JumpTableDataSection - This is the section that we SwitchToSection right
+ /// before emitting the jump tables for a function when the relocation model
+ /// is not PIC.
+ const char *JumpTableDataSection; // Defaults to "\t.section .rodata"
+
+ /// JumpTableDirective - if non-null, the directive to emit before a jump
+ /// table.
+ const char *JumpTableDirective;
+
+ /// CStringSection - If not null, this allows for special handling of
+ /// cstring constants (\0 terminated string that does not contain any
+ /// other null bytes) on this target. This is commonly supported as
+ /// ".cstring".
+ const char *CStringSection; // Defaults to NULL
+
+ /// StaticCtorsSection - This is the directive that is emitted to switch to
+ /// a section to emit the static constructor list.
+ /// Defaults to "\t.section .ctors,\"aw\",@progbits".
+ const char *StaticCtorsSection;
+
+ /// StaticDtorsSection - This is the directive that is emitted to switch to
+ /// a section to emit the static destructor list.
+ /// Defaults to "\t.section .dtors,\"aw\",@progbits".
+ const char *StaticDtorsSection;
+
+ /// FourByteConstantSection, EightByteConstantSection,
+ /// SixteenByteConstantSection - These are special sections where we place
+ /// 4-, 8-, and 16- byte constant literals.
+ const char *FourByteConstantSection;
+ const char *EightByteConstantSection;
+ const char *SixteenByteConstantSection;
+
+ /// ReadOnlySection - This is the directive that is emitted to switch to a
+ /// read-only section for constant data (e.g. data declared const,
+ /// jump tables).
+ const char *ReadOnlySection; // Defaults to NULL
+
+ //===--- Global Variable Emission Directives --------------------------===//
+
+ /// GlobalDirective - This is the directive used to declare a global entity.
+ ///
+ const char *GlobalDirective; // Defaults to NULL.
+
+ /// SetDirective - This is the name of a directive that can be used to tell
+ /// the assembler to set the value of a variable to some expression.
+ const char *SetDirective; // Defaults to null.
+
+ /// LCOMMDirective - This is the name of a directive (if supported) that can
+ /// be used to efficiently declare a local (internal) block of zero
+ /// initialized data in the .bss/.data section. The syntax expected is:
+ /// \literal <LCOMMDirective> SYMBOLNAME LENGTHINBYTES, ALIGNMENT
+ /// \endliteral
+ const char *LCOMMDirective; // Defaults to null.
+
+ const char *COMMDirective; // Defaults to "\t.comm\t".
+
+ /// COMMDirectiveTakesAlignment - True if COMMDirective take a third
+ /// argument that specifies the alignment of the declaration.
+ bool COMMDirectiveTakesAlignment; // Defaults to true.
+
+ /// HasDotTypeDotSizeDirective - True if the target has .type and .size
+ /// directives, this is true for most ELF targets.
+ bool HasDotTypeDotSizeDirective; // Defaults to true.
+
+ /// UsedDirective - This directive, if non-null, is used to declare a global
+ /// as being used somehow that the assembler can't see. This prevents dead
+ /// code elimination on some targets.
+ const char *UsedDirective; // Defaults to null.
+
+ /// WeakRefDirective - This directive, if non-null, is used to declare a
+ /// global as being a weak undefined symbol.
+ const char *WeakRefDirective; // Defaults to null.
+
+ /// HiddenDirective - This directive, if non-null, is used to declare a
+ /// global or function as having hidden visibility.
+ const char *HiddenDirective; // Defaults to "\t.hidden\t".
+
+ /// ProtectedDirective - This directive, if non-null, is used to declare a
+ /// global or function as having protected visibility.
+ const char *ProtectedDirective; // Defaults to "\t.protected\t".
+
+ //===--- Dwarf Emission Directives -----------------------------------===//
+
+ /// AbsoluteDebugSectionOffsets - True if we should emit abolute section
+ /// offsets for debug information. Defaults to false.
+ bool AbsoluteDebugSectionOffsets;
+
+ /// AbsoluteEHSectionOffsets - True if we should emit abolute section
+ /// offsets for EH information. Defaults to false.
+ bool AbsoluteEHSectionOffsets;
+
+ /// HasLEB128 - True if target asm supports leb128 directives.
+ ///
+ bool HasLEB128; // Defaults to false.
+
+ /// hasDotLoc - True if target asm supports .loc directives.
+ ///
+ bool HasDotLoc; // Defaults to false.
+
+ /// HasDotFile - True if target asm supports .file directives.
+ ///
+ bool HasDotFile; // Defaults to false.
+
+ /// SupportsDebugInformation - True if target supports emission of debugging
+ /// information.
+ bool SupportsDebugInformation;
+
+ /// SupportsExceptionHandling - True if target supports
+ /// exception handling.
+ ///
+ bool SupportsExceptionHandling; // Defaults to false.
+
+ /// RequiresFrameSection - true if the Dwarf2 output needs a frame section
+ ///
+ bool DwarfRequiresFrameSection; // Defaults to true.
+
+ /// DwarfSectionOffsetDirective - Special section offset directive.
+ const char* DwarfSectionOffsetDirective; // Defaults to NULL
+
+ /// DwarfAbbrevSection - Section directive for Dwarf abbrev.
+ ///
+ const char *DwarfAbbrevSection; // Defaults to ".debug_abbrev".
+
+ /// DwarfInfoSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfInfoSection; // Defaults to ".debug_info".
+
+ /// DwarfLineSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfLineSection; // Defaults to ".debug_line".
+
+ /// DwarfFrameSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfFrameSection; // Defaults to ".debug_frame".
+
+ /// DwarfPubNamesSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfPubNamesSection; // Defaults to ".debug_pubnames".
+
+ /// DwarfPubTypesSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfPubTypesSection; // Defaults to ".debug_pubtypes".
+
+ /// DwarfStrSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfStrSection; // Defaults to ".debug_str".
+
+ /// DwarfLocSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfLocSection; // Defaults to ".debug_loc".
+
+ /// DwarfARangesSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfARangesSection; // Defaults to ".debug_aranges".
+
+ /// DwarfRangesSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfRangesSection; // Defaults to ".debug_ranges".
+
+ /// DwarfMacInfoSection - Section directive for Dwarf info.
+ ///
+ const char *DwarfMacInfoSection; // Defaults to ".debug_macinfo".
+
+ /// DwarfEHFrameSection - Section directive for Exception frames.
+ ///
+ const char *DwarfEHFrameSection; // Defaults to ".eh_frame".
+
+ /// DwarfExceptionSection - Section directive for Exception table.
+ ///
+ const char *DwarfExceptionSection; // Defaults to ".gcc_except_table".
+
+
+ //===--- CBE Asm Translation Table -----------------------------------===//
+
+ const char** AsmTransCBE; // Defaults to empty
+
+ public:
+ TargetAsmInfo();
+ virtual ~TargetAsmInfo();
+
+ /// Measure the specified inline asm to determine an approximation of its
+ /// length.
+ virtual unsigned getInlineAsmLength(const char *Str) const;
+
+ /// ExpandInlineAsm - This hook allows the target to expand an inline asm
+ /// call to be explicit llvm code if it wants to. This is useful for
+ /// turning simple inline asms into LLVM intrinsics, which gives the
+ /// compiler more information about the behavior of the code.
+ virtual bool ExpandInlineAsm(CallInst *CI) const {
+ return false;
+ }
+
+ // Accessors.
+ //
+ const char *getTextSection() const {
+ return TextSection;
+ }
+ const char *getDataSection() const {
+ return DataSection;
+ }
+ const char *getBSSSection() const {
+ return BSSSection;
+ }
+ const char *getTLSDataSection() const {
+ return TLSDataSection;
+ }
+ const char *getTLSBSSSection() const {
+ return TLSBSSSection;
+ }
+ const char *getZeroFillDirective() const {
+ return ZeroFillDirective;
+ }
+ unsigned getAddressSize() const {
+ return AddressSize;
+ }
+ bool needsSet() const {
+ return NeedsSet;
+ }
+ const char *getPCSymbol() const {
+ return PCSymbol;
+ }
+ char getSeparatorChar() const {
+ return SeparatorChar;
+ }
+ const char *getCommentString() const {
+ return CommentString;
+ }
+ const char *getGlobalPrefix() const {
+ return GlobalPrefix;
+ }
+ const char *getPrivateGlobalPrefix() const {
+ return PrivateGlobalPrefix;
+ }
+ const char *getJumpTableSpecialLabelPrefix() const {
+ return JumpTableSpecialLabelPrefix;
+ }
+ const char *getGlobalVarAddrPrefix() const {
+ return GlobalVarAddrPrefix;
+ }
+ const char *getGlobalVarAddrSuffix() const {
+ return GlobalVarAddrSuffix;
+ }
+ const char *getFunctionAddrPrefix() const {
+ return FunctionAddrPrefix;
+ }
+ const char *getFunctionAddrSuffix() const {
+ return FunctionAddrSuffix;
+ }
+ const char *getInlineAsmStart() const {
+ return InlineAsmStart;
+ }
+ const char *getInlineAsmEnd() const {
+ return InlineAsmEnd;
+ }
+ unsigned getAssemblerDialect() const {
+ return AssemblerDialect;
+ }
+ const char *getZeroDirective() const {
+ return ZeroDirective;
+ }
+ const char *getZeroDirectiveSuffix() const {
+ return ZeroDirectiveSuffix;
+ }
+ const char *getAsciiDirective() const {
+ return AsciiDirective;
+ }
+ const char *getAscizDirective() const {
+ return AscizDirective;
+ }
+ const char *getData8bitsDirective() const {
+ return Data8bitsDirective;
+ }
+ const char *getData16bitsDirective() const {
+ return Data16bitsDirective;
+ }
+ const char *getData32bitsDirective() const {
+ return Data32bitsDirective;
+ }
+ const char *getData64bitsDirective() const {
+ return Data64bitsDirective;
+ }
+ const char *getJumpTableDirective() const {
+ return JumpTableDirective;
+ }
+ const char *getAlignDirective() const {
+ return AlignDirective;
+ }
+ bool getAlignmentIsInBytes() const {
+ return AlignmentIsInBytes;
+ }
+ const char *getSwitchToSectionDirective() const {
+ return SwitchToSectionDirective;
+ }
+ const char *getTextSectionStartSuffix() const {
+ return TextSectionStartSuffix;
+ }
+ const char *getDataSectionStartSuffix() const {
+ return DataSectionStartSuffix;
+ }
+ const char *getSectionEndDirectiveSuffix() const {
+ return SectionEndDirectiveSuffix;
+ }
+ const char *getConstantPoolSection() const {
+ return ConstantPoolSection;
+ }
+ const char *getJumpTableDataSection() const {
+ return JumpTableDataSection;
+ }
+ const char *getCStringSection() const {
+ return CStringSection;
+ }
+ const char *getStaticCtorsSection() const {
+ return StaticCtorsSection;
+ }
+ const char *getStaticDtorsSection() const {
+ return StaticDtorsSection;
+ }
+ const char *getFourByteConstantSection() const {
+ return FourByteConstantSection;
+ }
+ const char *getEightByteConstantSection() const {
+ return EightByteConstantSection;
+ }
+ const char *getSixteenByteConstantSection() const {
+ return SixteenByteConstantSection;
+ }
+ const char *getReadOnlySection() const {
+ return ReadOnlySection;
+ }
+ const char *getGlobalDirective() const {
+ return GlobalDirective;
+ }
+ const char *getSetDirective() const {
+ return SetDirective;
+ }
+ const char *getLCOMMDirective() const {
+ return LCOMMDirective;
+ }
+ const char *getCOMMDirective() const {
+ return COMMDirective;
+ }
+ bool getCOMMDirectiveTakesAlignment() const {
+ return COMMDirectiveTakesAlignment;
+ }
+ bool hasDotTypeDotSizeDirective() const {
+ return HasDotTypeDotSizeDirective;
+ }
+ const char *getUsedDirective() const {
+ return UsedDirective;
+ }
+ const char *getWeakRefDirective() const {
+ return WeakRefDirective;
+ }
+ const char *getHiddenDirective() const {
+ return HiddenDirective;
+ }
+ const char *getProtectedDirective() const {
+ return ProtectedDirective;
+ }
+ bool isAbsoluteDebugSectionOffsets() const {
+ return AbsoluteDebugSectionOffsets;
+ }
+ bool isAbsoluteEHSectionOffsets() const {
+ return AbsoluteEHSectionOffsets;
+ }
+ bool hasLEB128() const {
+ return HasLEB128;
+ }
+ bool hasDotLoc() const {
+ return HasDotLoc;
+ }
+ bool hasDotFile() const {
+ return HasDotFile;
+ }
+ bool doesSupportDebugInformation() const {
+ return SupportsDebugInformation;
+ }
+ bool doesSupportExceptionHandling() const {
+ return SupportsExceptionHandling;
+ }
+ bool doesDwarfRequireFrameSection() const {
+ return DwarfRequiresFrameSection;
+ }
+ const char *getDwarfSectionOffsetDirective() const {
+ return DwarfSectionOffsetDirective;
+ }
+ const char *getDwarfAbbrevSection() const {
+ return DwarfAbbrevSection;
+ }
+ const char *getDwarfInfoSection() const {
+ return DwarfInfoSection;
+ }
+ const char *getDwarfLineSection() const {
+ return DwarfLineSection;
+ }
+ const char *getDwarfFrameSection() const {
+ return DwarfFrameSection;
+ }
+ const char *getDwarfPubNamesSection() const {
+ return DwarfPubNamesSection;
+ }
+ const char *getDwarfPubTypesSection() const {
+ return DwarfPubTypesSection;
+ }
+ const char *getDwarfStrSection() const {
+ return DwarfStrSection;
+ }
+ const char *getDwarfLocSection() const {
+ return DwarfLocSection;
+ }
+ const char *getDwarfARangesSection() const {
+ return DwarfARangesSection;
+ }
+ const char *getDwarfRangesSection() const {
+ return DwarfRangesSection;
+ }
+ const char *getDwarfMacInfoSection() const {
+ return DwarfMacInfoSection;
+ }
+ const char *getDwarfEHFrameSection() const {
+ return DwarfEHFrameSection;
+ }
+ const char *getDwarfExceptionSection() const {
+ return DwarfExceptionSection;
+ }
+ const char** getAsmCBE() const {
+ return AsmTransCBE;
+ }
+ };
+}
+
+#endif
+
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h
new file mode 100644
index 0000000..5756079
--- /dev/null
+++ b/include/llvm/Target/TargetData.h
@@ -0,0 +1,243 @@
+//===-- llvm/Target/TargetData.h - Data size & alignment info ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines target properties related to datatype size/offset/alignment
+// information. It uses lazy annotations to cache information about how
+// structure types are laid out and used.
+//
+// This structure should be created once, filled in if the defaults are not
+// correct and then passed around by const&. None of the members functions
+// require modification to the object.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETDATA_H
+#define LLVM_TARGET_TARGETDATA_H
+
+#include "llvm/Pass.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
+
+namespace llvm {
+
+class Value;
+class Type;
+class StructType;
+class StructLayout;
+class GlobalVariable;
+
+/// Enum used to categorize the alignment types stored by TargetAlignElem
+enum AlignTypeEnum {
+ INTEGER_ALIGN = 'i', ///< Integer type alignment
+ VECTOR_ALIGN = 'v', ///< Vector type alignment
+ FLOAT_ALIGN = 'f', ///< Floating point type alignment
+ AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
+};
+/// Target alignment element.
+///
+/// Stores the alignment data associated with a given alignment type (pointer,
+/// integer, vector, float) and type bit width.
+///
+/// @note The unusual order of elements in the structure attempts to reduce
+/// padding and make the structure slightly more cache friendly.
+struct TargetAlignElem {
+ AlignTypeEnum AlignType : 8; //< Alignment type (AlignTypeEnum)
+ unsigned char ABIAlign; //< ABI alignment for this type/bitw
+ unsigned char PrefAlign; //< Pref. alignment for this type/bitw
+ uint32_t TypeBitWidth; //< Type bit width
+
+ /// Initializer
+ static TargetAlignElem get(AlignTypeEnum align_type, unsigned char abi_align,
+ unsigned char pref_align, uint32_t bit_width);
+ /// Equality predicate
+ bool operator==(const TargetAlignElem &rhs) const;
+ /// output stream operator
+ std::ostream &dump(std::ostream &os) const;
+};
+
+class TargetData : public ImmutablePass {
+private:
+ bool LittleEndian; ///< Defaults to false
+ unsigned char PointerMemSize; ///< Pointer size in bytes
+ unsigned char PointerABIAlign; ///< Pointer ABI alignment
+ unsigned char PointerPrefAlign; ///< Pointer preferred alignment
+
+ //! Where the primitive type alignment data is stored.
+ /*!
+ @sa init().
+ @note Could support multiple size pointer alignments, e.g., 32-bit pointers
+ vs. 64-bit pointers by extending TargetAlignment, but for now, we don't.
+ */
+ SmallVector<TargetAlignElem, 16> Alignments;
+ //! Alignment iterator shorthand
+ typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator;
+ //! Constant alignment iterator shorthand
+ typedef SmallVector<TargetAlignElem, 16>::const_iterator align_const_iterator;
+ //! Invalid alignment.
+ /*!
+ This member is a signal that a requested alignment type and bit width were
+ not found in the SmallVector.
+ */
+ static const TargetAlignElem InvalidAlignmentElem;
+
+ //! Set/initialize target alignments
+ void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
+ unsigned char pref_align, uint32_t bit_width);
+ unsigned getAlignmentInfo(AlignTypeEnum align_type, uint32_t bit_width,
+ bool ABIAlign) const;
+ //! Internal helper method that returns requested alignment for type.
+ unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const;
+
+ /// Valid alignment predicate.
+ ///
+ /// Predicate that tests a TargetAlignElem reference returned by get() against
+ /// InvalidAlignmentElem.
+ inline bool validAlignment(const TargetAlignElem &align) const {
+ return (&align != &InvalidAlignmentElem);
+ }
+
+public:
+ /// Default ctor.
+ ///
+ /// @note This has to exist, because this is a pass, but it should never be
+ /// used.
+ TargetData() : ImmutablePass((intptr_t)&ID) {
+ assert(0 && "ERROR: Bad TargetData ctor used. "
+ "Tool did not specify a TargetData to use?");
+ abort();
+ }
+
+ /// Constructs a TargetData from a specification string. See init().
+ TargetData(const std::string &TargetDescription)
+ : ImmutablePass((intptr_t)&ID) {
+ init(TargetDescription);
+ }
+
+ /// Initialize target data from properties stored in the module.
+ TargetData(const Module *M);
+
+ TargetData(const TargetData &TD) :
+ ImmutablePass((intptr_t)&ID),
+ LittleEndian(TD.isLittleEndian()),
+ PointerMemSize(TD.PointerMemSize),
+ PointerABIAlign(TD.PointerABIAlign),
+ PointerPrefAlign(TD.PointerPrefAlign),
+ Alignments(TD.Alignments)
+ { }
+
+ ~TargetData(); // Not virtual, do not subclass this class
+
+ //! Parse a target data layout string and initialize TargetData alignments.
+ void init(const std::string &TargetDescription);
+
+ /// Target endianness...
+ bool isLittleEndian() const { return LittleEndian; }
+ bool isBigEndian() const { return !LittleEndian; }
+
+ /// getStringRepresentation - Return the string representation of the
+ /// TargetData. This representation is in the same format accepted by the
+ /// string constructor above.
+ std::string getStringRepresentation() const;
+ /// Target pointer alignment
+ unsigned char getPointerABIAlignment() const { return PointerABIAlign; }
+ /// Return target's alignment for stack-based pointers
+ unsigned char getPointerPrefAlignment() const { return PointerPrefAlign; }
+ /// Target pointer size
+ unsigned char getPointerSize() const { return PointerMemSize; }
+ /// Target pointer size, in bits
+ unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; }
+
+ /// getTypeSize - Return the number of bytes necessary to hold the specified
+ /// type.
+ uint64_t getTypeSize(const Type *Ty) const;
+
+ /// getTypeSizeInBits - Return the number of bits necessary to hold the
+ /// specified type.
+ uint64_t getTypeSizeInBits(const Type* Ty) const;
+
+ /// getABITypeAlignment - Return the minimum ABI-required alignment for the
+ /// specified type.
+ unsigned char getABITypeAlignment(const Type *Ty) const;
+
+ /// getPrefTypeAlignment - Return the preferred stack/global alignment for
+ /// the specified type.
+ unsigned char getPrefTypeAlignment(const Type *Ty) const;
+
+ /// getPreferredTypeAlignmentShift - Return the preferred alignment for the
+ /// specified type, returned as log2 of the value (a shift amount).
+ ///
+ unsigned char getPreferredTypeAlignmentShift(const Type *Ty) const;
+
+ /// getIntPtrType - Return an unsigned integer type that is the same size or
+ /// greater to the host pointer size.
+ ///
+ const Type *getIntPtrType() const;
+
+ /// getIndexedOffset - return the offset from the beginning of the type for the
+ /// specified indices. This is used to implement getelementptr.
+ ///
+ uint64_t getIndexedOffset(const Type *Ty,
+ Value* const* Indices, unsigned NumIndices) const;
+
+ /// getStructLayout - Return a StructLayout object, indicating the alignment
+ /// of the struct, its size, and the offsets of its fields. Note that this
+ /// information is lazily cached.
+ const StructLayout *getStructLayout(const StructType *Ty) const;
+
+ /// InvalidateStructLayoutInfo - TargetData speculatively caches StructLayout
+ /// objects. If a TargetData object is alive when types are being refined and
+ /// removed, this method must be called whenever a StructType is removed to
+ /// avoid a dangling pointer in this cache.
+ void InvalidateStructLayoutInfo(const StructType *Ty) const;
+
+ /// getPreferredAlignmentLog - Return the preferred alignment of the
+ /// specified global, returned in log form. This includes an explicitly
+ /// requested alignment (if the global has one).
+ unsigned getPreferredAlignmentLog(const GlobalVariable *GV) const;
+
+ static char ID; // Pass identification, replacement for typeid
+};
+
+/// StructLayout - used to lazily calculate structure layout information for a
+/// target machine, based on the TargetData structure.
+///
+class StructLayout {
+ uint64_t StructSize;
+ unsigned StructAlignment;
+ unsigned NumElements;
+ uint64_t MemberOffsets[1]; // variable sized array!
+public:
+
+ uint64_t getSizeInBytes() const {
+ return StructSize;
+ }
+
+ unsigned getAlignment() const {
+ return StructAlignment;
+ }
+
+ /// getElementContainingOffset - Given a valid offset into the structure,
+ /// return the structure index that contains it.
+ ///
+ unsigned getElementContainingOffset(uint64_t Offset) const;
+
+ uint64_t getElementOffset(unsigned Idx) const {
+ assert(Idx < NumElements && "Invalid element idx!");
+ return MemberOffsets[Idx];
+ }
+
+private:
+ friend class TargetData; // Only TargetData can create this class
+ StructLayout(const StructType *ST, const TargetData &TD);
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetELFWriterInfo.h b/include/llvm/Target/TargetELFWriterInfo.h
new file mode 100644
index 0000000..a8332df
--- /dev/null
+++ b/include/llvm/Target/TargetELFWriterInfo.h
@@ -0,0 +1,43 @@
+//===-- llvm/Target/TargetELFWriterInfo.h - ELF Writer Info -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetELFWriterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETELFWRITERINFO_H
+#define LLVM_TARGET_TARGETELFWRITERINFO_H
+
+namespace llvm {
+
+ class MachineBasicBlock;
+
+ //===--------------------------------------------------------------------===//
+ // TargetELFWriterInfo
+ //===--------------------------------------------------------------------===//
+
+ class TargetELFWriterInfo {
+ // EMachine - This field is the target specific value to emit as the
+ // e_machine member of the ELF header.
+ unsigned short EMachine;
+ public:
+ enum MachineType {
+ NoMachine,
+ EM_386 = 3
+ };
+
+ TargetELFWriterInfo(MachineType machine) : EMachine(machine) {}
+ virtual ~TargetELFWriterInfo() {}
+
+ unsigned short getEMachine() const { return EMachine; }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_TARGET_TARGETELFWRITERINFO_H
diff --git a/include/llvm/Target/TargetFrameInfo.h b/include/llvm/Target/TargetFrameInfo.h
new file mode 100644
index 0000000..53430a5
--- /dev/null
+++ b/include/llvm/Target/TargetFrameInfo.h
@@ -0,0 +1,82 @@
+//===-- llvm/Target/TargetFrameInfo.h ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface to describe the layout of a stack frame on the target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETFRAMEINFO_H
+#define LLVM_TARGET_TARGETFRAMEINFO_H
+
+#include <utility>
+
+namespace llvm {
+
+class MachineFunction;
+
+/// Information about stack frame layout on the target. It holds the direction
+/// of stack growth, the known stack alignment on entry to each function, and
+/// the offset to the locals area.
+///
+/// The offset to the local area is the offset from the stack pointer on
+/// function entry to the first location where function data (local variables,
+/// spill locations) can be stored.
+class TargetFrameInfo {
+public:
+ enum StackDirection {
+ StackGrowsUp, // Adding to the stack increases the stack address
+ StackGrowsDown // Adding to the stack decreases the stack address
+ };
+private:
+ StackDirection StackDir;
+ unsigned StackAlignment;
+ int LocalAreaOffset;
+public:
+ TargetFrameInfo(StackDirection D, unsigned StackAl, int LAO)
+ : StackDir(D), StackAlignment(StackAl), LocalAreaOffset(LAO) {}
+
+ virtual ~TargetFrameInfo();
+
+ // These methods return information that describes the abstract stack layout
+ // of the target machine.
+
+ /// getStackGrowthDirection - Return the direction the stack grows
+ ///
+ StackDirection getStackGrowthDirection() const { return StackDir; }
+
+ /// getStackAlignment - This method returns the number of bytes that the stack
+ /// pointer must be aligned to. Typically, this is the largest alignment for
+ /// any data object in the target.
+ ///
+ unsigned getStackAlignment() const { return StackAlignment; }
+
+ /// getOffsetOfLocalArea - This method returns the offset of the local area
+ /// from the stack pointer on entrance to a function.
+ ///
+ int getOffsetOfLocalArea() const { return LocalAreaOffset; }
+
+ /// getCalleeSavedSpillSlots - This method returns a pointer to an array of
+ /// pairs, that contains an entry for each callee saved register that must be
+ /// spilled to a particular stack location if it is spilled.
+ ///
+ /// Each entry in this array contains a <register,offset> pair, indicating the
+ /// fixed offset from the incoming stack pointer that each register should be
+ /// spilled at. If a register is not listed here, the code generator is
+ /// allowed to spill it anywhere it chooses.
+ ///
+ virtual const std::pair<unsigned, int> *
+ getCalleeSavedSpillSlots(unsigned &NumEntries) const {
+ NumEntries = 0;
+ return 0;
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h
new file mode 100644
index 0000000..25fb79f
--- /dev/null
+++ b/include/llvm/Target/TargetInstrInfo.h
@@ -0,0 +1,478 @@
+//===-- llvm/Target/TargetInstrInfo.h - Instruction Info --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the target machine instructions to the code generator.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINSTRINFO_H
+#define LLVM_TARGET_TARGETINSTRINFO_H
+
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/DataTypes.h"
+#include <vector>
+#include <cassert>
+
+namespace llvm {
+
+class MachineInstr;
+class TargetMachine;
+class MachineCodeForInstruction;
+class TargetRegisterClass;
+class LiveVariables;
+
+//---------------------------------------------------------------------------
+// Data types used to define information about a single machine instruction
+//---------------------------------------------------------------------------
+
+typedef short MachineOpCode;
+typedef unsigned InstrSchedClass;
+
+//---------------------------------------------------------------------------
+// struct TargetInstrDescriptor:
+// Predefined information about each machine instruction.
+// Designed to initialized statically.
+//
+
+const unsigned M_BRANCH_FLAG = 1 << 0;
+const unsigned M_CALL_FLAG = 1 << 1;
+const unsigned M_RET_FLAG = 1 << 2;
+const unsigned M_BARRIER_FLAG = 1 << 3;
+const unsigned M_DELAY_SLOT_FLAG = 1 << 4;
+const unsigned M_LOAD_FLAG = 1 << 5;
+const unsigned M_STORE_FLAG = 1 << 6;
+
+// M_CONVERTIBLE_TO_3_ADDR - This is a 2-address instruction which can be
+// changed into a 3-address instruction if the first two operands cannot be
+// assigned to the same register. The target must implement the
+// TargetInstrInfo::convertToThreeAddress method for this instruction.
+const unsigned M_CONVERTIBLE_TO_3_ADDR = 1 << 7;
+
+// This M_COMMUTABLE - is a 2- or 3-address instruction (of the form X = op Y,
+// Z), which produces the same result if Y and Z are exchanged.
+const unsigned M_COMMUTABLE = 1 << 8;
+
+// M_TERMINATOR_FLAG - Is this instruction part of the terminator for a basic
+// block? Typically this is things like return and branch instructions.
+// Various passes use this to insert code into the bottom of a basic block, but
+// before control flow occurs.
+const unsigned M_TERMINATOR_FLAG = 1 << 9;
+
+// M_USES_CUSTOM_DAG_SCHED_INSERTION - Set if this instruction requires custom
+// insertion support when the DAG scheduler is inserting it into a machine basic
+// block.
+const unsigned M_USES_CUSTOM_DAG_SCHED_INSERTION = 1 << 10;
+
+// M_VARIABLE_OPS - Set if this instruction can have a variable number of extra
+// operands in addition to the minimum number operands specified.
+const unsigned M_VARIABLE_OPS = 1 << 11;
+
+// M_PREDICABLE - Set if this instruction has a predicate operand that
+// controls execution. It may be set to 'always'.
+const unsigned M_PREDICABLE = 1 << 12;
+
+// M_REMATERIALIZIBLE - Set if this instruction can be trivally re-materialized
+// at any time, e.g. constant generation, load from constant pool.
+const unsigned M_REMATERIALIZIBLE = 1 << 13;
+
+// M_NOT_DUPLICABLE - Set if this instruction cannot be safely duplicated.
+// (e.g. instructions with unique labels attached).
+const unsigned M_NOT_DUPLICABLE = 1 << 14;
+
+// M_HAS_OPTIONAL_DEF - Set if this instruction has an optional definition, e.g.
+// ARM instructions which can set condition code if 's' bit is set.
+const unsigned M_HAS_OPTIONAL_DEF = 1 << 15;
+
+// Machine operand flags
+// M_LOOK_UP_PTR_REG_CLASS - Set if this operand is a pointer value and it
+// requires a callback to look up its register class.
+const unsigned M_LOOK_UP_PTR_REG_CLASS = 1 << 0;
+
+/// M_PREDICATE_OPERAND - Set if this is one of the operands that made up of the
+/// predicate operand that controls an M_PREDICATED instruction.
+const unsigned M_PREDICATE_OPERAND = 1 << 1;
+
+/// M_OPTIONAL_DEF_OPERAND - Set if this operand is a optional def.
+///
+const unsigned M_OPTIONAL_DEF_OPERAND = 1 << 2;
+
+namespace TOI {
+ // Operand constraints: only "tied_to" for now.
+ enum OperandConstraint {
+ TIED_TO = 0 // Must be allocated the same register as.
+ };
+}
+
+/// TargetOperandInfo - This holds information about one operand of a machine
+/// instruction, indicating the register class for register operands, etc.
+///
+class TargetOperandInfo {
+public:
+ /// RegClass - This specifies the register class enumeration of the operand
+ /// if the operand is a register. If not, this contains 0.
+ unsigned short RegClass;
+ unsigned short Flags;
+ /// Lower 16 bits are used to specify which constraints are set. The higher 16
+ /// bits are used to specify the value of constraints (4 bits each).
+ unsigned int Constraints;
+ /// Currently no other information.
+};
+
+
+class TargetInstrDescriptor {
+public:
+ MachineOpCode Opcode; // The opcode.
+ unsigned short numOperands; // Num of args (may be more if variable_ops).
+ const char * Name; // Assembly language mnemonic for the opcode.
+ InstrSchedClass schedClass; // enum identifying instr sched class
+ unsigned Flags; // flags identifying machine instr class
+ unsigned TSFlags; // Target Specific Flag values
+ const unsigned *ImplicitUses; // Registers implicitly read by this instr
+ const unsigned *ImplicitDefs; // Registers implicitly defined by this instr
+ const TargetOperandInfo *OpInfo; // 'numOperands' entries about operands.
+
+ /// getOperandConstraint - Returns the value of the specific constraint if
+ /// it is set. Returns -1 if it is not set.
+ int getOperandConstraint(unsigned OpNum,
+ TOI::OperandConstraint Constraint) const {
+ assert((OpNum < numOperands || (Flags & M_VARIABLE_OPS)) &&
+ "Invalid operand # of TargetInstrInfo");
+ if (OpNum < numOperands &&
+ (OpInfo[OpNum].Constraints & (1 << Constraint))) {
+ unsigned Pos = 16 + Constraint * 4;
+ return (int)(OpInfo[OpNum].Constraints >> Pos) & 0xf;
+ }
+ return -1;
+ }
+
+ /// findTiedToSrcOperand - Returns the operand that is tied to the specified
+ /// dest operand. Returns -1 if there isn't one.
+ int findTiedToSrcOperand(unsigned OpNum) const;
+};
+
+
+//---------------------------------------------------------------------------
+///
+/// TargetInstrInfo - Interface to description of machine instructions
+///
+class TargetInstrInfo {
+ const TargetInstrDescriptor* desc; // raw array to allow static init'n
+ unsigned NumOpcodes; // number of entries in the desc array
+ unsigned numRealOpCodes; // number of non-dummy op codes
+
+ TargetInstrInfo(const TargetInstrInfo &); // DO NOT IMPLEMENT
+ void operator=(const TargetInstrInfo &); // DO NOT IMPLEMENT
+public:
+ TargetInstrInfo(const TargetInstrDescriptor *desc, unsigned NumOpcodes);
+ virtual ~TargetInstrInfo();
+
+ // Invariant opcodes: All instruction sets have these as their low opcodes.
+ enum {
+ PHI = 0,
+ INLINEASM = 1,
+ LABEL = 2
+ };
+
+ unsigned getNumOpcodes() const { return NumOpcodes; }
+
+ /// get - Return the machine instruction descriptor that corresponds to the
+ /// specified instruction opcode.
+ ///
+ const TargetInstrDescriptor& get(MachineOpCode Opcode) const {
+ assert((unsigned)Opcode < NumOpcodes);
+ return desc[Opcode];
+ }
+
+ const char *getName(MachineOpCode Opcode) const {
+ return get(Opcode).Name;
+ }
+
+ int getNumOperands(MachineOpCode Opcode) const {
+ return get(Opcode).numOperands;
+ }
+
+ InstrSchedClass getSchedClass(MachineOpCode Opcode) const {
+ return get(Opcode).schedClass;
+ }
+
+ const unsigned *getImplicitUses(MachineOpCode Opcode) const {
+ return get(Opcode).ImplicitUses;
+ }
+
+ const unsigned *getImplicitDefs(MachineOpCode Opcode) const {
+ return get(Opcode).ImplicitDefs;
+ }
+
+
+ //
+ // Query instruction class flags according to the machine-independent
+ // flags listed above.
+ //
+ bool isReturn(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_RET_FLAG;
+ }
+
+ bool isCommutableInstr(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_COMMUTABLE;
+ }
+ bool isTerminatorInstr(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_TERMINATOR_FLAG;
+ }
+
+ bool isBranch(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_BRANCH_FLAG;
+ }
+
+ /// isBarrier - Returns true if the specified instruction stops control flow
+ /// from executing the instruction immediately following it. Examples include
+ /// unconditional branches and return instructions.
+ bool isBarrier(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_BARRIER_FLAG;
+ }
+
+ bool isCall(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_CALL_FLAG;
+ }
+ bool isLoad(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_LOAD_FLAG;
+ }
+ bool isStore(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_STORE_FLAG;
+ }
+
+ /// hasDelaySlot - Returns true if the specified instruction has a delay slot
+ /// which must be filled by the code generator.
+ bool hasDelaySlot(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_DELAY_SLOT_FLAG;
+ }
+
+ /// usesCustomDAGSchedInsertionHook - Return true if this instruction requires
+ /// custom insertion support when the DAG scheduler is inserting it into a
+ /// machine basic block.
+ bool usesCustomDAGSchedInsertionHook(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_USES_CUSTOM_DAG_SCHED_INSERTION;
+ }
+
+ bool hasVariableOperands(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_VARIABLE_OPS;
+ }
+
+ bool isPredicable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_PREDICABLE;
+ }
+
+ bool isNotDuplicable(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_NOT_DUPLICABLE;
+ }
+
+ bool hasOptionalDef(MachineOpCode Opcode) const {
+ return get(Opcode).Flags & M_HAS_OPTIONAL_DEF;
+ }
+
+ /// isTriviallyReMaterializable - Return true if the instruction is trivially
+ /// rematerializable, meaning it has no side effects and requires no operands
+ /// that aren't always available.
+ bool isTriviallyReMaterializable(MachineInstr *MI) const {
+ return (MI->getInstrDescriptor()->Flags & M_REMATERIALIZIBLE) &&
+ isReallyTriviallyReMaterializable(MI);
+ }
+
+protected:
+ /// isReallyTriviallyReMaterializable - For instructions with opcodes for
+ /// which the M_REMATERIALIZABLE flag is set, this function tests whether the
+ /// instruction itself is actually trivially rematerializable, considering
+ /// its operands. This is used for targets that have instructions that are
+ /// only trivially rematerializable for specific uses. This predicate must
+ /// return false if the instruction has any side effects other than
+ /// producing a value, or if it requres any address registers that are not
+ /// always available.
+ virtual bool isReallyTriviallyReMaterializable(MachineInstr *MI) const {
+ return true;
+ }
+
+public:
+ /// getOperandConstraint - Returns the value of the specific constraint if
+ /// it is set. Returns -1 if it is not set.
+ int getOperandConstraint(MachineOpCode Opcode, unsigned OpNum,
+ TOI::OperandConstraint Constraint) const {
+ return get(Opcode).getOperandConstraint(OpNum, Constraint);
+ }
+
+ /// Return true if the instruction is a register to register move
+ /// and leave the source and dest operands in the passed parameters.
+ virtual bool isMoveInstr(const MachineInstr& MI,
+ unsigned& sourceReg,
+ unsigned& destReg) const {
+ return false;
+ }
+
+ /// isLoadFromStackSlot - If the specified machine instruction is a direct
+ /// load from a stack slot, return the virtual or physical register number of
+ /// the destination along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than loading from the stack slot.
+ virtual unsigned isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const{
+ return 0;
+ }
+
+ /// isStoreToStackSlot - If the specified machine instruction is a direct
+ /// store to a stack slot, return the virtual or physical register number of
+ /// the source reg along with the FrameIndex of the loaded stack slot. If
+ /// not, return 0. This predicate must return 0 if the instruction has
+ /// any side effects other than storing to the stack slot.
+ virtual unsigned isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
+ return 0;
+ }
+
+ /// convertToThreeAddress - This method must be implemented by targets that
+ /// set the M_CONVERTIBLE_TO_3_ADDR flag. When this flag is set, the target
+ /// may be able to convert a two-address instruction into one or more true
+ /// three-address instructions on demand. This allows the X86 target (for
+ /// example) to convert ADD and SHL instructions into LEA instructions if they
+ /// would require register copies due to two-addressness.
+ ///
+ /// This method returns a null pointer if the transformation cannot be
+ /// performed, otherwise it returns the last new instruction.
+ ///
+ virtual MachineInstr *
+ convertToThreeAddress(MachineFunction::iterator &MFI,
+ MachineBasicBlock::iterator &MBBI, LiveVariables &LV) const {
+ return 0;
+ }
+
+ /// commuteInstruction - If a target has any instructions that are commutable,
+ /// but require converting to a different instruction or making non-trivial
+ /// changes to commute them, this method can overloaded to do this. The
+ /// default implementation of this method simply swaps the first two operands
+ /// of MI and returns it.
+ ///
+ /// If a target wants to make more aggressive changes, they can construct and
+ /// return a new machine instruction. If an instruction cannot commute, it
+ /// can also return null.
+ ///
+ virtual MachineInstr *commuteInstruction(MachineInstr *MI) const;
+
+ /// AnalyzeBranch - Analyze the branching code at the end of MBB, returning
+ /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
+ /// implemented for a target). Upon success, this returns false and returns
+ /// with the following information in various cases:
+ ///
+ /// 1. If this block ends with no branches (it just falls through to its succ)
+ /// just return false, leaving TBB/FBB null.
+ /// 2. If this block ends with only an unconditional branch, it sets TBB to be
+ /// the destination block.
+ /// 3. If this block ends with an conditional branch and it falls through to
+ /// an successor block, it sets TBB to be the branch destination block and a
+ /// list of operands that evaluate the condition. These
+ /// operands can be passed to other TargetInstrInfo methods to create new
+ /// branches.
+ /// 4. If this block ends with an conditional branch and an unconditional
+ /// block, it returns the 'true' destination in TBB, the 'false' destination
+ /// in FBB, and a list of operands that evaluate the condition. These
+ /// operands can be passed to other TargetInstrInfo methods to create new
+ /// branches.
+ ///
+ /// Note that RemoveBranch and InsertBranch must be implemented to support
+ /// cases where this method returns success.
+ ///
+ virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
+ MachineBasicBlock *&FBB,
+ std::vector<MachineOperand> &Cond) const {
+ return true;
+ }
+
+ /// RemoveBranch - Remove the branching code at the end of the specific MBB.
+ /// this is only invoked in cases where AnalyzeBranch returns success. It
+ /// returns the number of instructions that were removed.
+ virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const {
+ assert(0 && "Target didn't implement TargetInstrInfo::RemoveBranch!");
+ return 0;
+ }
+
+ /// InsertBranch - Insert a branch into the end of the specified
+ /// MachineBasicBlock. This operands to this method are the same as those
+ /// returned by AnalyzeBranch. This is invoked in cases where AnalyzeBranch
+ /// returns success and when an unconditional branch (TBB is non-null, FBB is
+ /// null, Cond is empty) needs to be inserted. It returns the number of
+ /// instructions inserted.
+ virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ const std::vector<MachineOperand> &Cond) const {
+ assert(0 && "Target didn't implement TargetInstrInfo::InsertBranch!");
+ return 0;
+ }
+
+ /// BlockHasNoFallThrough - Return true if the specified block does not
+ /// fall-through into its successor block. This is primarily used when a
+ /// branch is unanalyzable. It is useful for things like unconditional
+ /// indirect branches (jump tables).
+ virtual bool BlockHasNoFallThrough(MachineBasicBlock &MBB) const {
+ return false;
+ }
+
+ /// ReverseBranchCondition - Reverses the branch condition of the specified
+ /// condition list, returning false on success and true if it cannot be
+ /// reversed.
+ virtual bool ReverseBranchCondition(std::vector<MachineOperand> &Cond) const {
+ return true;
+ }
+
+ /// insertNoop - Insert a noop into the instruction stream at the specified
+ /// point.
+ virtual void insertNoop(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MI) const {
+ assert(0 && "Target didn't implement insertNoop!");
+ abort();
+ }
+
+ /// isPredicated - Returns true if the instruction is already predicated.
+ ///
+ virtual bool isPredicated(const MachineInstr *MI) const {
+ return false;
+ }
+
+ /// isUnpredicatedTerminator - Returns true if the instruction is a
+ /// terminator instruction that has not been predicated.
+ virtual bool isUnpredicatedTerminator(const MachineInstr *MI) const;
+
+ /// PredicateInstruction - Convert the instruction into a predicated
+ /// instruction. It returns true if the operation was successful.
+ virtual
+ bool PredicateInstruction(MachineInstr *MI,
+ const std::vector<MachineOperand> &Pred) const;
+
+ /// SubsumesPredicate - Returns true if the first specified predicate
+ /// subsumes the second, e.g. GE subsumes GT.
+ virtual
+ bool SubsumesPredicate(const std::vector<MachineOperand> &Pred1,
+ const std::vector<MachineOperand> &Pred2) const {
+ return false;
+ }
+
+ /// DefinesPredicate - If the specified instruction defines any predicate
+ /// or condition code register(s) used for predication, returns true as well
+ /// as the definition predicate(s) by reference.
+ virtual bool DefinesPredicate(MachineInstr *MI,
+ std::vector<MachineOperand> &Pred) const {
+ return false;
+ }
+
+ /// getPointerRegClass - Returns a TargetRegisterClass used for pointer
+ /// values.
+ virtual const TargetRegisterClass *getPointerRegClass() const {
+ assert(0 && "Target didn't implement getPointerRegClass!");
+ abort();
+ return 0; // Must return a value in order to compile with VS 2005
+ }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h
new file mode 100644
index 0000000..ee47443
--- /dev/null
+++ b/include/llvm/Target/TargetInstrItineraries.h
@@ -0,0 +1,84 @@
+//===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the James M. Laskey and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the structures used for instruction itineraries and
+// states. This is used by schedulers to determine instruction states and
+// latencies.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
+#define LLVM_TARGET_TARGETINSTRITINERARIES_H
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+// Instruction stage - These values represent a step in the execution of an
+// instruction. The latency represents the number of discrete time slots used
+// need to complete the stage. Units represent the choice of functional units
+// that can be used to complete the stage. Eg. IntUnit1, IntUnit2.
+//
+struct InstrStage {
+ unsigned Cycles; // Length of stage in machine cycles
+ unsigned Units; // Choice of functional units
+};
+
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary - An itinerary represents a sequential series of steps
+// required to complete an instruction. Itineraries are represented as
+// sequences of instruction stages.
+//
+struct InstrItinerary {
+ unsigned First; // Index of first stage in itinerary
+ unsigned Last; // Index of last + 1 stage in itinerary
+};
+
+
+
+//===----------------------------------------------------------------------===//
+// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
+// used by a target.
+//
+struct InstrItineraryData {
+ InstrStage *Stages; // Array of stages selected
+ InstrItinerary *Itineratries; // Array of itineraries selected
+
+//
+// Ctors.
+//
+ InstrItineraryData() : Stages(0), Itineratries(0) {}
+ InstrItineraryData(InstrStage *S, InstrItinerary *I) : Stages(S), Itineratries(I) {}
+
+ //
+ // isEmpty - Returns true if there are no itineraries.
+ //
+ inline bool isEmpty() const { return Itineratries == 0; }
+
+ //
+ // begin - Return the first stage of the itinerary.
+ //
+ inline InstrStage *begin(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineratries[ItinClassIndx].First;
+ return Stages + StageIdx;
+ }
+
+ //
+ // end - Return the last+1 stage of the itinerary.
+ //
+ inline InstrStage *end(unsigned ItinClassIndx) const {
+ unsigned StageIdx = Itineratries[ItinClassIndx].Last;
+ return Stages + StageIdx;
+ }
+};
+
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h
new file mode 100644
index 0000000..b80b055
--- /dev/null
+++ b/include/llvm/Target/TargetJITInfo.h
@@ -0,0 +1,90 @@
+//===- Target/TargetJITInfo.h - Target Information for JIT ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an abstract interface used by the Just-In-Time code
+// generator to perform target-specific activities, such as emitting stubs. If
+// a TargetMachine supports JIT code generation, it should provide one of these
+// objects through the getJITInfo() method.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETJITINFO_H
+#define LLVM_TARGET_TARGETJITINFO_H
+
+#include <cassert>
+#include <vector>
+
+namespace llvm {
+ class Function;
+ class FunctionPassManager;
+ class MachineBasicBlock;
+ class MachineCodeEmitter;
+ class MachineRelocation;
+
+ /// TargetJITInfo - Target specific information required by the Just-In-Time
+ /// code generator.
+ class TargetJITInfo {
+ public:
+ virtual ~TargetJITInfo() {}
+
+ /// replaceMachineCodeForFunction - Make it so that calling the function
+ /// whose machine code is at OLD turns into a call to NEW, perhaps by
+ /// overwriting OLD with a branch to NEW. This is used for self-modifying
+ /// code.
+ ///
+ virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
+
+ /// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
+ /// small native function that simply calls the function at the specified
+ /// address. Return the address of the resultant function.
+ virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+ assert(0 && "This target doesn't implement emitFunctionStub!");
+ return 0;
+ }
+
+ /// LazyResolverFn - This typedef is used to represent the function that
+ /// unresolved call points should invoke. This is a target specific
+ /// function that knows how to walk the stack and find out which stub the
+ /// call is coming from.
+ typedef void (*LazyResolverFn)();
+
+ /// JITCompilerFn - This typedef is used to represent the JIT function that
+ /// lazily compiles the function corresponding to a stub. The JIT keeps
+ /// track of the mapping between stubs and LLVM Functions, the target
+ /// provides the ability to figure out the address of a stub that is called
+ /// by the LazyResolverFn.
+ typedef void* (*JITCompilerFn)(void *);
+
+ /// getLazyResolverFunction - This method is used to initialize the JIT,
+ /// giving the target the function that should be used to compile a
+ /// function, and giving the JIT the target function used to do the lazy
+ /// resolving.
+ virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn) {
+ assert(0 && "Not implemented for this target!");
+ return 0;
+ }
+
+ /// relocate - Before the JIT can run a block of code that has been emitted,
+ /// it must rewrite the code to contain the actual addresses of any
+ /// referenced global symbols.
+ virtual void relocate(void *Function, MachineRelocation *MR,
+ unsigned NumRelocs, unsigned char* GOTBase) {
+ assert(NumRelocs == 0 && "This target does not have relocations!");
+ }
+
+ /// needsGOT - Allows a target to specify that it would like the
+ // JIT to manage a GOT for it.
+ bool needsGOT() const { return useGOT; }
+
+ protected:
+ bool useGOT;
+ };
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h
new file mode 100644
index 0000000..a95a03b
--- /dev/null
+++ b/include/llvm/Target/TargetLowering.h
@@ -0,0 +1,1153 @@
+//===-- llvm/Target/TargetLowering.h - Target Lowering Info -----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes how to lower LLVM code to machine code. This has two
+// main components:
+//
+// 1. Which ValueTypes are natively supported by the target.
+// 2. Which operations are supported for supported ValueTypes.
+// 3. Cost thresholds for alternative implementations of certain operations.
+//
+// In addition it has a few other components, like information about FP
+// immediates.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETLOWERING_H
+#define LLVM_TARGET_TARGETLOWERING_H
+
+#include "llvm/CodeGen/SelectionDAGNodes.h"
+#include "llvm/CodeGen/RuntimeLibcalls.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+ class Value;
+ class Function;
+ class TargetMachine;
+ class TargetData;
+ class TargetRegisterClass;
+ class SDNode;
+ class SDOperand;
+ class SelectionDAG;
+ class MachineBasicBlock;
+ class MachineInstr;
+ class VectorType;
+
+//===----------------------------------------------------------------------===//
+/// TargetLowering - This class defines information used to lower LLVM code to
+/// legal SelectionDAG operators that the target instruction selector can accept
+/// natively.
+///
+/// This class also defines callbacks that targets must implement to lower
+/// target-specific constructs to SelectionDAG operators.
+///
+class TargetLowering {
+public:
+ /// LegalizeAction - This enum indicates whether operations are valid for a
+ /// target, and if not, what action should be used to make them valid.
+ enum LegalizeAction {
+ Legal, // The target natively supports this operation.
+ Promote, // This operation should be executed in a larger type.
+ Expand, // Try to expand this to other ops, otherwise use a libcall.
+ Custom // Use the LowerOperation hook to implement custom lowering.
+ };
+
+ enum OutOfRangeShiftAmount {
+ Undefined, // Oversized shift amounts are undefined (default).
+ Mask, // Shift amounts are auto masked (anded) to value size.
+ Extend // Oversized shift pulls in zeros or sign bits.
+ };
+
+ enum SetCCResultValue {
+ UndefinedSetCCResult, // SetCC returns a garbage/unknown extend.
+ ZeroOrOneSetCCResult, // SetCC returns a zero extended result.
+ ZeroOrNegativeOneSetCCResult // SetCC returns a sign extended result.
+ };
+
+ enum SchedPreference {
+ SchedulingForLatency, // Scheduling for shortest total latency.
+ SchedulingForRegPressure // Scheduling for lowest register pressure.
+ };
+
+ TargetLowering(TargetMachine &TM);
+ virtual ~TargetLowering();
+
+ TargetMachine &getTargetMachine() const { return TM; }
+ const TargetData *getTargetData() const { return TD; }
+
+ bool isLittleEndian() const { return IsLittleEndian; }
+ MVT::ValueType getPointerTy() const { return PointerTy; }
+ MVT::ValueType getShiftAmountTy() const { return ShiftAmountTy; }
+ OutOfRangeShiftAmount getShiftAmountFlavor() const {return ShiftAmtHandling; }
+
+ /// usesGlobalOffsetTable - Return true if this target uses a GOT for PIC
+ /// codegen.
+ bool usesGlobalOffsetTable() const { return UsesGlobalOffsetTable; }
+
+ /// isSelectExpensive - Return true if the select operation is expensive for
+ /// this target.
+ bool isSelectExpensive() const { return SelectIsExpensive; }
+
+ /// isIntDivCheap() - Return true if integer divide is usually cheaper than
+ /// a sequence of several shifts, adds, and multiplies for this target.
+ bool isIntDivCheap() const { return IntDivIsCheap; }
+
+ /// isPow2DivCheap() - Return true if pow2 div is cheaper than a chain of
+ /// srl/add/sra.
+ bool isPow2DivCheap() const { return Pow2DivIsCheap; }
+
+ /// getSetCCResultTy - Return the ValueType of the result of setcc operations.
+ ///
+ MVT::ValueType getSetCCResultTy() const { return SetCCResultTy; }
+
+ /// getSetCCResultContents - For targets without boolean registers, this flag
+ /// returns information about the contents of the high-bits in the setcc
+ /// result register.
+ SetCCResultValue getSetCCResultContents() const { return SetCCResultContents;}
+
+ /// getSchedulingPreference - Return target scheduling preference.
+ SchedPreference getSchedulingPreference() const {
+ return SchedPreferenceInfo;
+ }
+
+ /// getRegClassFor - Return the register class that should be used for the
+ /// specified value type. This may only be called on legal types.
+ TargetRegisterClass *getRegClassFor(MVT::ValueType VT) const {
+ assert(!MVT::isExtendedVT(VT));
+ TargetRegisterClass *RC = RegClassForVT[VT];
+ assert(RC && "This value type is not natively supported!");
+ return RC;
+ }
+
+ /// isTypeLegal - Return true if the target has native support for the
+ /// specified value type. This means that it has a register that directly
+ /// holds it without promotions or expansions.
+ bool isTypeLegal(MVT::ValueType VT) const {
+ return !MVT::isExtendedVT(VT) && RegClassForVT[VT] != 0;
+ }
+
+ class ValueTypeActionImpl {
+ /// ValueTypeActions - This is a bitvector that contains two bits for each
+ /// value type, where the two bits correspond to the LegalizeAction enum.
+ /// This can be queried with "getTypeAction(VT)".
+ uint32_t ValueTypeActions[2];
+ public:
+ ValueTypeActionImpl() {
+ ValueTypeActions[0] = ValueTypeActions[1] = 0;
+ }
+ ValueTypeActionImpl(const ValueTypeActionImpl &RHS) {
+ ValueTypeActions[0] = RHS.ValueTypeActions[0];
+ ValueTypeActions[1] = RHS.ValueTypeActions[1];
+ }
+
+ LegalizeAction getTypeAction(MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((ValueTypeActions[VT>>4] >> ((2*VT) & 31)) & 3);
+ }
+ void setTypeAction(MVT::ValueType VT, LegalizeAction Action) {
+ assert(!MVT::isExtendedVT(VT));
+ assert(unsigned(VT >> 4) <
+ sizeof(ValueTypeActions)/sizeof(ValueTypeActions[0]));
+ ValueTypeActions[VT>>4] |= Action << ((VT*2) & 31);
+ }
+ };
+
+ const ValueTypeActionImpl &getValueTypeActions() const {
+ return ValueTypeActions;
+ }
+
+ /// getTypeAction - Return how we should legalize values of this type, either
+ /// it is already legal (return 'Legal') or we need to promote it to a larger
+ /// type (return 'Promote'), or we need to expand it into multiple registers
+ /// of smaller integer type (return 'Expand'). 'Custom' is not an option.
+ LegalizeAction getTypeAction(MVT::ValueType VT) const {
+ return ValueTypeActions.getTypeAction(VT);
+ }
+
+ /// getTypeToTransformTo - For types supported by the target, this is an
+ /// identity function. For types that must be promoted to larger types, this
+ /// returns the larger type to promote to. For integer types that are larger
+ /// than the largest integer register, this contains one step in the expansion
+ /// to get to the smaller register. For illegal floating point types, this
+ /// returns the integer type to transform to.
+ MVT::ValueType getTypeToTransformTo(MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT))
+ return MVT::getVectorType(MVT::getVectorElementType(VT),
+ MVT::getVectorNumElements(VT) / 2);
+
+ return TransformToType[VT];
+ }
+
+ /// getTypeToExpandTo - For types supported by the target, this is an
+ /// identity function. For types that must be expanded (i.e. integer types
+ /// that are larger than the largest integer register or illegal floating
+ /// point types), this returns the largest legal type it will be expanded to.
+ MVT::ValueType getTypeToExpandTo(MVT::ValueType VT) const {
+ assert(!MVT::isExtendedVT(VT));
+ while (true) {
+ switch (getTypeAction(VT)) {
+ case Legal:
+ return VT;
+ case Expand:
+ VT = getTypeToTransformTo(VT);
+ break;
+ default:
+ assert(false && "Type is not legal nor is it to be expanded!");
+ return VT;
+ }
+ }
+ return VT;
+ }
+
+ /// getVectorTypeBreakdown - Vector types are broken down into some number of
+ /// legal first class types. For example, MVT::v8f32 maps to 2 MVT::v4f32
+ /// with Altivec or SSE1, or 8 promoted MVT::f64 values with the X86 FP stack.
+ /// Similarly, MVT::v2i64 turns into 4 MVT::i32 values with both PPC and X86.
+ ///
+ /// This method returns the number of registers needed, and the VT for each
+ /// register. It also returns the VT and quantity of the intermediate values
+ /// before they are promoted/expanded.
+ ///
+ unsigned getVectorTypeBreakdown(MVT::ValueType VT,
+ MVT::ValueType &IntermediateVT,
+ unsigned &NumIntermediates,
+ MVT::ValueType &RegisterVT) const;
+
+ typedef std::vector<double>::const_iterator legal_fpimm_iterator;
+ legal_fpimm_iterator legal_fpimm_begin() const {
+ return LegalFPImmediates.begin();
+ }
+ legal_fpimm_iterator legal_fpimm_end() const {
+ return LegalFPImmediates.end();
+ }
+
+ /// isShuffleMaskLegal - Targets can use this to indicate that they only
+ /// support *some* VECTOR_SHUFFLE operations, those with specific masks.
+ /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
+ /// are assumed to be legal.
+ virtual bool isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
+ return true;
+ }
+
+ /// isVectorClearMaskLegal - Similar to isShuffleMaskLegal. This is
+ /// used by Targets can use this to indicate if there is a suitable
+ /// VECTOR_SHUFFLE that can be used to replace a VAND with a constant
+ /// pool entry.
+ virtual bool isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
+ MVT::ValueType EVT,
+ SelectionDAG &DAG) const {
+ return false;
+ }
+
+ /// getOperationAction - Return how this operation should be treated: either
+ /// it is legal, needs to be promoted to a larger size, needs to be
+ /// expanded to some other code sequence, or the target has a custom expander
+ /// for it.
+ LegalizeAction getOperationAction(unsigned Op, MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((OpActions[Op] >> (2*VT)) & 3);
+ }
+
+ /// isOperationLegal - Return true if the specified operation is legal on this
+ /// target.
+ bool isOperationLegal(unsigned Op, MVT::ValueType VT) const {
+ return getOperationAction(Op, VT) == Legal ||
+ getOperationAction(Op, VT) == Custom;
+ }
+
+ /// getLoadXAction - Return how this load with extension should be treated:
+ /// either it is legal, needs to be promoted to a larger size, needs to be
+ /// expanded to some other code sequence, or the target has a custom expander
+ /// for it.
+ LegalizeAction getLoadXAction(unsigned LType, MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((LoadXActions[LType] >> (2*VT)) & 3);
+ }
+
+ /// isLoadXLegal - Return true if the specified load with extension is legal
+ /// on this target.
+ bool isLoadXLegal(unsigned LType, MVT::ValueType VT) const {
+ return getLoadXAction(LType, VT) == Legal ||
+ getLoadXAction(LType, VT) == Custom;
+ }
+
+ /// getStoreXAction - Return how this store with truncation should be treated:
+ /// either it is legal, needs to be promoted to a larger size, needs to be
+ /// expanded to some other code sequence, or the target has a custom expander
+ /// for it.
+ LegalizeAction getStoreXAction(MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((StoreXActions >> (2*VT)) & 3);
+ }
+
+ /// isStoreXLegal - Return true if the specified store with truncation is
+ /// legal on this target.
+ bool isStoreXLegal(MVT::ValueType VT) const {
+ return getStoreXAction(VT) == Legal || getStoreXAction(VT) == Custom;
+ }
+
+ /// getIndexedLoadAction - Return how the indexed load should be treated:
+ /// either it is legal, needs to be promoted to a larger size, needs to be
+ /// expanded to some other code sequence, or the target has a custom expander
+ /// for it.
+ LegalizeAction
+ getIndexedLoadAction(unsigned IdxMode, MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((IndexedModeActions[0][IdxMode] >> (2*VT)) & 3);
+ }
+
+ /// isIndexedLoadLegal - Return true if the specified indexed load is legal
+ /// on this target.
+ bool isIndexedLoadLegal(unsigned IdxMode, MVT::ValueType VT) const {
+ return getIndexedLoadAction(IdxMode, VT) == Legal ||
+ getIndexedLoadAction(IdxMode, VT) == Custom;
+ }
+
+ /// getIndexedStoreAction - Return how the indexed store should be treated:
+ /// either it is legal, needs to be promoted to a larger size, needs to be
+ /// expanded to some other code sequence, or the target has a custom expander
+ /// for it.
+ LegalizeAction
+ getIndexedStoreAction(unsigned IdxMode, MVT::ValueType VT) const {
+ if (MVT::isExtendedVT(VT)) return Expand;
+ return (LegalizeAction)((IndexedModeActions[1][IdxMode] >> (2*VT)) & 3);
+ }
+
+ /// isIndexedStoreLegal - Return true if the specified indexed load is legal
+ /// on this target.
+ bool isIndexedStoreLegal(unsigned IdxMode, MVT::ValueType VT) const {
+ return getIndexedStoreAction(IdxMode, VT) == Legal ||
+ getIndexedStoreAction(IdxMode, VT) == Custom;
+ }
+
+ /// getTypeToPromoteTo - If the action for this operation is to promote, this
+ /// method returns the ValueType to promote to.
+ MVT::ValueType getTypeToPromoteTo(unsigned Op, MVT::ValueType VT) const {
+ assert(getOperationAction(Op, VT) == Promote &&
+ "This operation isn't promoted!");
+
+ // See if this has an explicit type specified.
+ std::map<std::pair<unsigned, MVT::ValueType>,
+ MVT::ValueType>::const_iterator PTTI =
+ PromoteToType.find(std::make_pair(Op, VT));
+ if (PTTI != PromoteToType.end()) return PTTI->second;
+
+ assert((MVT::isInteger(VT) || MVT::isFloatingPoint(VT)) &&
+ "Cannot autopromote this type, add it with AddPromotedToType.");
+
+ MVT::ValueType NVT = VT;
+ do {
+ NVT = (MVT::ValueType)(NVT+1);
+ assert(MVT::isInteger(NVT) == MVT::isInteger(VT) && NVT != MVT::isVoid &&
+ "Didn't find type to promote to!");
+ } while (!isTypeLegal(NVT) ||
+ getOperationAction(Op, NVT) == Promote);
+ return NVT;
+ }
+
+ /// getValueType - Return the MVT::ValueType corresponding to this LLVM type.
+ /// This is fixed by the LLVM operations except for the pointer size. If
+ /// AllowUnknown is true, this will return MVT::Other for types with no MVT
+ /// counterpart (e.g. structs), otherwise it will assert.
+ MVT::ValueType getValueType(const Type *Ty, bool AllowUnknown = false) const {
+ MVT::ValueType VT = MVT::getValueType(Ty, AllowUnknown);
+ return VT == MVT::iPTR ? PointerTy : VT;
+ }
+
+ /// getRegisterType - Return the type of registers that this ValueType will
+ /// eventually require.
+ MVT::ValueType getRegisterType(MVT::ValueType VT) const {
+ if (!MVT::isExtendedVT(VT))
+ return RegisterTypeForVT[VT];
+
+ MVT::ValueType VT1, RegisterVT;
+ unsigned NumIntermediates;
+ (void)getVectorTypeBreakdown(VT, VT1, NumIntermediates, RegisterVT);
+ return RegisterVT;
+ }
+
+ /// getNumRegisters - Return the number of registers that this ValueType will
+ /// eventually require. This is one for any types promoted to live in larger
+ /// registers, but may be more than one for types (like i64) that are split
+ /// into pieces.
+ unsigned getNumRegisters(MVT::ValueType VT) const {
+ if (!MVT::isExtendedVT(VT))
+ return NumRegistersForVT[VT];
+
+ MVT::ValueType VT1, VT2;
+ unsigned NumIntermediates;
+ return getVectorTypeBreakdown(VT, VT1, NumIntermediates, VT2);
+ }
+
+ /// hasTargetDAGCombine - If true, the target has custom DAG combine
+ /// transformations that it can perform for the specified node.
+ bool hasTargetDAGCombine(ISD::NodeType NT) const {
+ return TargetDAGCombineArray[NT >> 3] & (1 << (NT&7));
+ }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memset. The value is set by the target at the
+ /// performance threshold for such a replacement.
+ /// @brief Get maximum # of store operations permitted for llvm.memset
+ unsigned getMaxStoresPerMemset() const { return maxStoresPerMemset; }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memcpy. The value is set by the target at the
+ /// performance threshold for such a replacement.
+ /// @brief Get maximum # of store operations permitted for llvm.memcpy
+ unsigned getMaxStoresPerMemcpy() const { return maxStoresPerMemcpy; }
+
+ /// This function returns the maximum number of store operations permitted
+ /// to replace a call to llvm.memmove. The value is set by the target at the
+ /// performance threshold for such a replacement.
+ /// @brief Get maximum # of store operations permitted for llvm.memmove
+ unsigned getMaxStoresPerMemmove() const { return maxStoresPerMemmove; }
+
+ /// This function returns true if the target allows unaligned memory accesses.
+ /// This is used, for example, in situations where an array copy/move/set is
+ /// converted to a sequence of store operations. It's use helps to ensure that
+ /// such replacements don't generate code that causes an alignment error
+ /// (trap) on the target machine.
+ /// @brief Determine if the target supports unaligned memory accesses.
+ bool allowsUnalignedMemoryAccesses() const {
+ return allowUnalignedMemoryAccesses;
+ }
+
+ /// usesUnderscoreSetJmp - Determine if we should use _setjmp or setjmp
+ /// to implement llvm.setjmp.
+ bool usesUnderscoreSetJmp() const {
+ return UseUnderscoreSetJmp;
+ }
+
+ /// usesUnderscoreLongJmp - Determine if we should use _longjmp or longjmp
+ /// to implement llvm.longjmp.
+ bool usesUnderscoreLongJmp() const {
+ return UseUnderscoreLongJmp;
+ }
+
+ /// getStackPointerRegisterToSaveRestore - If a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ unsigned getStackPointerRegisterToSaveRestore() const {
+ return StackPointerRegisterToSaveRestore;
+ }
+
+ /// getExceptionAddressRegister - If a physical register, this returns
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ unsigned getExceptionAddressRegister() const {
+ return ExceptionPointerRegister;
+ }
+
+ /// getExceptionSelectorRegister - If a physical register, this returns
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ unsigned getExceptionSelectorRegister() const {
+ return ExceptionSelectorRegister;
+ }
+
+ /// getJumpBufSize - returns the target's jmp_buf size in bytes (if never
+ /// set, the default is 200)
+ unsigned getJumpBufSize() const {
+ return JumpBufSize;
+ }
+
+ /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
+ /// (if never set, the default is 0)
+ unsigned getJumpBufAlignment() const {
+ return JumpBufAlignment;
+ }
+
+ /// getIfCvtBlockLimit - returns the target specific if-conversion block size
+ /// limit. Any block whose size is greater should not be predicated.
+ virtual unsigned getIfCvtBlockSizeLimit() const {
+ return IfCvtBlockSizeLimit;
+ }
+
+ /// getIfCvtDupBlockLimit - returns the target specific size limit for a
+ /// block to be considered for duplication. Any block whose size is greater
+ /// should not be duplicated to facilitate its predication.
+ virtual unsigned getIfCvtDupBlockSizeLimit() const {
+ return IfCvtDupBlockSizeLimit;
+ }
+
+ /// getPreIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if the node's address
+ /// can be legally represented as pre-indexed load / store address.
+ virtual bool getPreIndexedAddressParts(SDNode *N, SDOperand &Base,
+ SDOperand &Offset,
+ ISD::MemIndexedMode &AM,
+ SelectionDAG &DAG) {
+ return false;
+ }
+
+ /// getPostIndexedAddressParts - returns true by value, base pointer and
+ /// offset pointer and addressing mode by reference if this node can be
+ /// combined with a load / store to form a post-indexed load / store.
+ virtual bool getPostIndexedAddressParts(SDNode *N, SDNode *Op,
+ SDOperand &Base, SDOperand &Offset,
+ ISD::MemIndexedMode &AM,
+ SelectionDAG &DAG) {
+ return false;
+ }
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Optimization Methods
+ //
+
+ /// TargetLoweringOpt - A convenience struct that encapsulates a DAG, and two
+ /// SDOperands for returning information from TargetLowering to its clients
+ /// that want to combine
+ struct TargetLoweringOpt {
+ SelectionDAG &DAG;
+ SDOperand Old;
+ SDOperand New;
+
+ TargetLoweringOpt(SelectionDAG &InDAG) : DAG(InDAG) {}
+
+ bool CombineTo(SDOperand O, SDOperand N) {
+ Old = O;
+ New = N;
+ return true;
+ }
+
+ /// ShrinkDemandedConstant - Check to see if the specified operand of the
+ /// specified instruction is a constant integer. If so, check to see if there
+ /// are any bits set in the constant that are not demanded. If so, shrink the
+ /// constant and return true.
+ bool ShrinkDemandedConstant(SDOperand Op, uint64_t Demanded);
+ };
+
+ /// SimplifyDemandedBits - Look at Op. At this point, we know that only the
+ /// DemandedMask bits of the result of Op are ever used downstream. If we can
+ /// use this information to simplify Op, create a new simplified DAG node and
+ /// return true, returning the original and new nodes in Old and New.
+ /// Otherwise, analyze the expression and return a mask of KnownOne and
+ /// KnownZero bits for the expression (used to simplify the caller).
+ /// The KnownZero/One bits may only be accurate for those bits in the
+ /// DemandedMask.
+ bool SimplifyDemandedBits(SDOperand Op, uint64_t DemandedMask,
+ uint64_t &KnownZero, uint64_t &KnownOne,
+ TargetLoweringOpt &TLO, unsigned Depth = 0) const;
+
+ /// computeMaskedBitsForTargetNode - Determine which of the bits specified in
+ /// Mask are known to be either zero or one and return them in the
+ /// KnownZero/KnownOne bitsets.
+ virtual void computeMaskedBitsForTargetNode(const SDOperand Op,
+ uint64_t Mask,
+ uint64_t &KnownZero,
+ uint64_t &KnownOne,
+ const SelectionDAG &DAG,
+ unsigned Depth = 0) const;
+
+ /// ComputeNumSignBitsForTargetNode - This method can be implemented by
+ /// targets that want to expose additional information about sign bits to the
+ /// DAG Combiner.
+ virtual unsigned ComputeNumSignBitsForTargetNode(SDOperand Op,
+ unsigned Depth = 0) const;
+
+ struct DAGCombinerInfo {
+ void *DC; // The DAG Combiner object.
+ bool BeforeLegalize;
+ bool CalledByLegalizer;
+ public:
+ SelectionDAG &DAG;
+
+ DAGCombinerInfo(SelectionDAG &dag, bool bl, bool cl, void *dc)
+ : DC(dc), BeforeLegalize(bl), CalledByLegalizer(cl), DAG(dag) {}
+
+ bool isBeforeLegalize() const { return BeforeLegalize; }
+ bool isCalledByLegalizer() const { return CalledByLegalizer; }
+
+ void AddToWorklist(SDNode *N);
+ SDOperand CombineTo(SDNode *N, const std::vector<SDOperand> &To);
+ SDOperand CombineTo(SDNode *N, SDOperand Res);
+ SDOperand CombineTo(SDNode *N, SDOperand Res0, SDOperand Res1);
+ };
+
+ /// SimplifySetCC - Try to simplify a setcc built with the specified operands
+ /// and cc. If it is unable to simplify it, return a null SDOperand.
+ SDOperand SimplifySetCC(MVT::ValueType VT, SDOperand N0, SDOperand N1,
+ ISD::CondCode Cond, bool foldBooleans,
+ DAGCombinerInfo &DCI) const;
+
+ /// PerformDAGCombine - This method will be invoked for all target nodes and
+ /// for any target-independent nodes that the target has registered with
+ /// invoke it for.
+ ///
+ /// The semantics are as follows:
+ /// Return Value:
+ /// SDOperand.Val == 0 - No change was made
+ /// SDOperand.Val == N - N was replaced, is dead, and is already handled.
+ /// otherwise - N should be replaced by the returned Operand.
+ ///
+ /// In addition, methods provided by DAGCombinerInfo may be used to perform
+ /// more complex transformations.
+ ///
+ virtual SDOperand PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const;
+
+ //===--------------------------------------------------------------------===//
+ // TargetLowering Configuration Methods - These methods should be invoked by
+ // the derived class constructor to configure this object for the target.
+ //
+
+protected:
+ /// setUsesGlobalOffsetTable - Specify that this target does or doesn't use a
+ /// GOT for PC-relative code.
+ void setUsesGlobalOffsetTable(bool V) { UsesGlobalOffsetTable = V; }
+
+ /// setShiftAmountType - Describe the type that should be used for shift
+ /// amounts. This type defaults to the pointer type.
+ void setShiftAmountType(MVT::ValueType VT) { ShiftAmountTy = VT; }
+
+ /// setSetCCResultType - Describe the type that shoudl be used as the result
+ /// of a setcc operation. This defaults to the pointer type.
+ void setSetCCResultType(MVT::ValueType VT) { SetCCResultTy = VT; }
+
+ /// setSetCCResultContents - Specify how the target extends the result of a
+ /// setcc operation in a register.
+ void setSetCCResultContents(SetCCResultValue Ty) { SetCCResultContents = Ty; }
+
+ /// setSchedulingPreference - Specify the target scheduling preference.
+ void setSchedulingPreference(SchedPreference Pref) {
+ SchedPreferenceInfo = Pref;
+ }
+
+ /// setShiftAmountFlavor - Describe how the target handles out of range shift
+ /// amounts.
+ void setShiftAmountFlavor(OutOfRangeShiftAmount OORSA) {
+ ShiftAmtHandling = OORSA;
+ }
+
+ /// setUseUnderscoreSetJmp - Indicate whether this target prefers to
+ /// use _setjmp to implement llvm.setjmp or the non _ version.
+ /// Defaults to false.
+ void setUseUnderscoreSetJmp(bool Val) {
+ UseUnderscoreSetJmp = Val;
+ }
+
+ /// setUseUnderscoreLongJmp - Indicate whether this target prefers to
+ /// use _longjmp to implement llvm.longjmp or the non _ version.
+ /// Defaults to false.
+ void setUseUnderscoreLongJmp(bool Val) {
+ UseUnderscoreLongJmp = Val;
+ }
+
+ /// setStackPointerRegisterToSaveRestore - If set to a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ void setStackPointerRegisterToSaveRestore(unsigned R) {
+ StackPointerRegisterToSaveRestore = R;
+ }
+
+ /// setExceptionPointerRegister - If set to a physical register, this sets
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ void setExceptionPointerRegister(unsigned R) {
+ ExceptionPointerRegister = R;
+ }
+
+ /// setExceptionSelectorRegister - If set to a physical register, this sets
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ void setExceptionSelectorRegister(unsigned R) {
+ ExceptionSelectorRegister = R;
+ }
+
+ /// SelectIsExpensive - Tells the code generator not to expand operations
+ /// into sequences that use the select operations if possible.
+ void setSelectIsExpensive() { SelectIsExpensive = true; }
+
+ /// setIntDivIsCheap - Tells the code generator that integer divide is
+ /// expensive, and if possible, should be replaced by an alternate sequence
+ /// of instructions not containing an integer divide.
+ void setIntDivIsCheap(bool isCheap = true) { IntDivIsCheap = isCheap; }
+
+ /// setPow2DivIsCheap - Tells the code generator that it shouldn't generate
+ /// srl/add/sra for a signed divide by power of two, and let the target handle
+ /// it.
+ void setPow2DivIsCheap(bool isCheap = true) { Pow2DivIsCheap = isCheap; }
+
+ /// addRegisterClass - Add the specified register class as an available
+ /// regclass for the specified value type. This indicates the selector can
+ /// handle values of that class natively.
+ void addRegisterClass(MVT::ValueType VT, TargetRegisterClass *RC) {
+ assert(!MVT::isExtendedVT(VT));
+ AvailableRegClasses.push_back(std::make_pair(VT, RC));
+ RegClassForVT[VT] = RC;
+ }
+
+ /// computeRegisterProperties - Once all of the register classes are added,
+ /// this allows us to compute derived properties we expose.
+ void computeRegisterProperties();
+
+ /// setOperationAction - Indicate that the specified operation does not work
+ /// with the specified type and indicate what to do about it.
+ void setOperationAction(unsigned Op, MVT::ValueType VT,
+ LegalizeAction Action) {
+ assert(VT < 32 && Op < sizeof(OpActions)/sizeof(OpActions[0]) &&
+ "Table isn't big enough!");
+ OpActions[Op] &= ~(uint64_t(3UL) << VT*2);
+ OpActions[Op] |= (uint64_t)Action << VT*2;
+ }
+
+ /// setLoadXAction - Indicate that the specified load with extension does not
+ /// work with the with specified type and indicate what to do about it.
+ void setLoadXAction(unsigned ExtType, MVT::ValueType VT,
+ LegalizeAction Action) {
+ assert(VT < 32 && ExtType < sizeof(LoadXActions)/sizeof(LoadXActions[0]) &&
+ "Table isn't big enough!");
+ LoadXActions[ExtType] &= ~(uint64_t(3UL) << VT*2);
+ LoadXActions[ExtType] |= (uint64_t)Action << VT*2;
+ }
+
+ /// setStoreXAction - Indicate that the specified store with truncation does
+ /// not work with the with specified type and indicate what to do about it.
+ void setStoreXAction(MVT::ValueType VT, LegalizeAction Action) {
+ assert(VT < 32 && "Table isn't big enough!");
+ StoreXActions &= ~(uint64_t(3UL) << VT*2);
+ StoreXActions |= (uint64_t)Action << VT*2;
+ }
+
+ /// setIndexedLoadAction - Indicate that the specified indexed load does or
+ /// does not work with the with specified type and indicate what to do abort
+ /// it. NOTE: All indexed mode loads are initialized to Expand in
+ /// TargetLowering.cpp
+ void setIndexedLoadAction(unsigned IdxMode, MVT::ValueType VT,
+ LegalizeAction Action) {
+ assert(VT < 32 && IdxMode <
+ sizeof(IndexedModeActions[0]) / sizeof(IndexedModeActions[0][0]) &&
+ "Table isn't big enough!");
+ IndexedModeActions[0][IdxMode] &= ~(uint64_t(3UL) << VT*2);
+ IndexedModeActions[0][IdxMode] |= (uint64_t)Action << VT*2;
+ }
+
+ /// setIndexedStoreAction - Indicate that the specified indexed store does or
+ /// does not work with the with specified type and indicate what to do about
+ /// it. NOTE: All indexed mode stores are initialized to Expand in
+ /// TargetLowering.cpp
+ void setIndexedStoreAction(unsigned IdxMode, MVT::ValueType VT,
+ LegalizeAction Action) {
+ assert(VT < 32 && IdxMode <
+ sizeof(IndexedModeActions[1]) / sizeof(IndexedModeActions[1][0]) &&
+ "Table isn't big enough!");
+ IndexedModeActions[1][IdxMode] &= ~(uint64_t(3UL) << VT*2);
+ IndexedModeActions[1][IdxMode] |= (uint64_t)Action << VT*2;
+ }
+
+ /// AddPromotedToType - If Opc/OrigVT is specified as being promoted, the
+ /// promotion code defaults to trying a larger integer/fp until it can find
+ /// one that works. If that default is insufficient, this method can be used
+ /// by the target to override the default.
+ void AddPromotedToType(unsigned Opc, MVT::ValueType OrigVT,
+ MVT::ValueType DestVT) {
+ PromoteToType[std::make_pair(Opc, OrigVT)] = DestVT;
+ }
+
+ /// addLegalFPImmediate - Indicate that this target can instruction select
+ /// the specified FP immediate natively.
+ void addLegalFPImmediate(double Imm) {
+ LegalFPImmediates.push_back(Imm);
+ }
+
+ /// setTargetDAGCombine - Targets should invoke this method for each target
+ /// independent node that they want to provide a custom DAG combiner for by
+ /// implementing the PerformDAGCombine virtual method.
+ void setTargetDAGCombine(ISD::NodeType NT) {
+ TargetDAGCombineArray[NT >> 3] |= 1 << (NT&7);
+ }
+
+ /// setJumpBufSize - Set the target's required jmp_buf buffer size (in
+ /// bytes); default is 200
+ void setJumpBufSize(unsigned Size) {
+ JumpBufSize = Size;
+ }
+
+ /// setJumpBufAlignment - Set the target's required jmp_buf buffer
+ /// alignment (in bytes); default is 0
+ void setJumpBufAlignment(unsigned Align) {
+ JumpBufAlignment = Align;
+ }
+
+ /// setIfCvtBlockSizeLimit - Set the target's if-conversion block size
+ /// limit (in number of instructions); default is 2.
+ void setIfCvtBlockSizeLimit(unsigned Limit) {
+ IfCvtBlockSizeLimit = Limit;
+ }
+
+ /// setIfCvtDupBlockSizeLimit - Set the target's block size limit (in number
+ /// of instructions) to be considered for code duplication during
+ /// if-conversion; default is 2.
+ void setIfCvtDupBlockSizeLimit(unsigned Limit) {
+ IfCvtDupBlockSizeLimit = Limit;
+ }
+
+public:
+
+ //===--------------------------------------------------------------------===//
+ // Lowering methods - These methods must be implemented by targets so that
+ // the SelectionDAGLowering code knows how to lower these.
+ //
+
+ /// LowerArguments - This hook must be implemented to indicate how we should
+ /// lower the arguments for the specified function, into the specified DAG.
+ virtual std::vector<SDOperand>
+ LowerArguments(Function &F, SelectionDAG &DAG);
+
+ /// LowerCallTo - This hook lowers an abstract call to a function into an
+ /// actual call. This returns a pair of operands. The first element is the
+ /// return value for the function (if RetTy is not VoidTy). The second
+ /// element is the outgoing token chain.
+ struct ArgListEntry {
+ SDOperand Node;
+ const Type* Ty;
+ bool isSExt;
+ bool isZExt;
+ bool isInReg;
+ bool isSRet;
+
+ ArgListEntry():isSExt(false), isZExt(false), isInReg(false), isSRet(false) { };
+ };
+ typedef std::vector<ArgListEntry> ArgListTy;
+ virtual std::pair<SDOperand, SDOperand>
+ LowerCallTo(SDOperand Chain, const Type *RetTy, bool RetTyIsSigned,
+ bool isVarArg, unsigned CallingConv, bool isTailCall,
+ SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
+
+ /// LowerOperation - This callback is invoked for operations that are
+ /// unsupported by the target, which are registered to use 'custom' lowering,
+ /// and whose defined values are all legal.
+ /// If the target has no operations that require custom lowering, it need not
+ /// implement this. The default implementation of this aborts.
+ virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+
+ /// CustomPromoteOperation - This callback is invoked for operations that are
+ /// unsupported by the target, are registered to use 'custom' lowering, and
+ /// whose type needs to be promoted.
+ virtual SDOperand CustomPromoteOperation(SDOperand Op, SelectionDAG &DAG);
+
+ /// getTargetNodeName() - This method returns the name of a target specific
+ /// DAG node.
+ virtual const char *getTargetNodeName(unsigned Opcode) const;
+
+ //===--------------------------------------------------------------------===//
+ // Inline Asm Support hooks
+ //
+
+ enum ConstraintType {
+ C_Register, // Constraint represents a single register.
+ C_RegisterClass, // Constraint represents one or more registers.
+ C_Memory, // Memory constraint.
+ C_Other, // Something else.
+ C_Unknown // Unsupported constraint.
+ };
+
+ /// getConstraintType - Given a constraint, return the type of constraint it
+ /// is for this target.
+ virtual ConstraintType getConstraintType(const std::string &Constraint) const;
+
+
+ /// getRegClassForInlineAsmConstraint - Given a constraint letter (e.g. "r"),
+ /// return a list of registers that can be used to satisfy the constraint.
+ /// This should only be used for C_RegisterClass constraints.
+ virtual std::vector<unsigned>
+ getRegClassForInlineAsmConstraint(const std::string &Constraint,
+ MVT::ValueType VT) const;
+
+ /// getRegForInlineAsmConstraint - Given a physical register constraint (e.g.
+ /// {edx}), return the register number and the register class for the
+ /// register.
+ ///
+ /// Given a register class constraint, like 'r', if this corresponds directly
+ /// to an LLVM register class, return a register of 0 and the register class
+ /// pointer.
+ ///
+ /// This should only be used for C_Register constraints. On error,
+ /// this returns a register number of 0 and a null register class pointer..
+ virtual std::pair<unsigned, const TargetRegisterClass*>
+ getRegForInlineAsmConstraint(const std::string &Constraint,
+ MVT::ValueType VT) const;
+
+
+ /// isOperandValidForConstraint - Return the specified operand (possibly
+ /// modified) if the specified SDOperand is valid for the specified target
+ /// constraint letter, otherwise return null.
+ virtual SDOperand
+ isOperandValidForConstraint(SDOperand Op, char ConstraintLetter,
+ SelectionDAG &DAG);
+
+ //===--------------------------------------------------------------------===//
+ // Scheduler hooks
+ //
+
+ // InsertAtEndOfBasicBlock - This method should be implemented by targets that
+ // mark instructions with the 'usesCustomDAGSchedInserter' flag. These
+ // instructions are special in various ways, which require special support to
+ // insert. The specified MachineInstr is created but not inserted into any
+ // basic blocks, and the scheduler passes ownership of it to this method.
+ virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI,
+ MachineBasicBlock *MBB);
+
+ //===--------------------------------------------------------------------===//
+ // Addressing mode description hooks (used by LSR etc).
+ //
+
+ /// AddrMode - This represents an addressing mode of:
+ /// BaseGV + BaseOffs + BaseReg + Scale*ScaleReg
+ /// If BaseGV is null, there is no BaseGV.
+ /// If BaseOffs is zero, there is no base offset.
+ /// If HasBaseReg is false, there is no base register.
+ /// If Scale is zero, there is no ScaleReg. Scale of 1 indicates a reg with
+ /// no scale.
+ ///
+ struct AddrMode {
+ GlobalValue *BaseGV;
+ int64_t BaseOffs;
+ bool HasBaseReg;
+ int64_t Scale;
+ AddrMode() : BaseGV(0), BaseOffs(0), HasBaseReg(false), Scale(0) {}
+ };
+
+ /// isLegalAddressingMode - Return true if the addressing mode represented by
+ /// AM is legal for this target, for a load/store of the specified type.
+ /// TODO: Handle pre/postinc as well.
+ virtual bool isLegalAddressingMode(const AddrMode &AM, const Type *Ty) const;
+
+ //===--------------------------------------------------------------------===//
+ // Div utility functions
+ //
+ SDOperand BuildSDIV(SDNode *N, SelectionDAG &DAG,
+ std::vector<SDNode*>* Created) const;
+ SDOperand BuildUDIV(SDNode *N, SelectionDAG &DAG,
+ std::vector<SDNode*>* Created) const;
+
+
+ //===--------------------------------------------------------------------===//
+ // Runtime Library hooks
+ //
+
+ /// setLibcallName - Rename the default libcall routine name for the specified
+ /// libcall.
+ void setLibcallName(RTLIB::Libcall Call, const char *Name) {
+ LibcallRoutineNames[Call] = Name;
+ }
+
+ /// getLibcallName - Get the libcall routine name for the specified libcall.
+ ///
+ const char *getLibcallName(RTLIB::Libcall Call) const {
+ return LibcallRoutineNames[Call];
+ }
+
+ /// setCmpLibcallCC - Override the default CondCode to be used to test the
+ /// result of the comparison libcall against zero.
+ void setCmpLibcallCC(RTLIB::Libcall Call, ISD::CondCode CC) {
+ CmpLibcallCCs[Call] = CC;
+ }
+
+ /// getCmpLibcallCC - Get the CondCode that's to be used to test the result of
+ /// the comparison libcall against zero.
+ ISD::CondCode getCmpLibcallCC(RTLIB::Libcall Call) const {
+ return CmpLibcallCCs[Call];
+ }
+
+private:
+ TargetMachine &TM;
+ const TargetData *TD;
+
+ /// IsLittleEndian - True if this is a little endian target.
+ ///
+ bool IsLittleEndian;
+
+ /// PointerTy - The type to use for pointers, usually i32 or i64.
+ ///
+ MVT::ValueType PointerTy;
+
+ /// UsesGlobalOffsetTable - True if this target uses a GOT for PIC codegen.
+ ///
+ bool UsesGlobalOffsetTable;
+
+ /// ShiftAmountTy - The type to use for shift amounts, usually i8 or whatever
+ /// PointerTy is.
+ MVT::ValueType ShiftAmountTy;
+
+ OutOfRangeShiftAmount ShiftAmtHandling;
+
+ /// SelectIsExpensive - Tells the code generator not to expand operations
+ /// into sequences that use the select operations if possible.
+ bool SelectIsExpensive;
+
+ /// IntDivIsCheap - Tells the code generator not to expand integer divides by
+ /// constants into a sequence of muls, adds, and shifts. This is a hack until
+ /// a real cost model is in place. If we ever optimize for size, this will be
+ /// set to true unconditionally.
+ bool IntDivIsCheap;
+
+ /// Pow2DivIsCheap - Tells the code generator that it shouldn't generate
+ /// srl/add/sra for a signed divide by power of two, and let the target handle
+ /// it.
+ bool Pow2DivIsCheap;
+
+ /// SetCCResultTy - The type that SetCC operations use. This defaults to the
+ /// PointerTy.
+ MVT::ValueType SetCCResultTy;
+
+ /// SetCCResultContents - Information about the contents of the high-bits in
+ /// the result of a setcc comparison operation.
+ SetCCResultValue SetCCResultContents;
+
+ /// SchedPreferenceInfo - The target scheduling preference: shortest possible
+ /// total cycles or lowest register usage.
+ SchedPreference SchedPreferenceInfo;
+
+ /// UseUnderscoreSetJmp - This target prefers to use _setjmp to implement
+ /// llvm.setjmp. Defaults to false.
+ bool UseUnderscoreSetJmp;
+
+ /// UseUnderscoreLongJmp - This target prefers to use _longjmp to implement
+ /// llvm.longjmp. Defaults to false.
+ bool UseUnderscoreLongJmp;
+
+ /// JumpBufSize - The size, in bytes, of the target's jmp_buf buffers
+ unsigned JumpBufSize;
+
+ /// JumpBufAlignment - The alignment, in bytes, of the target's jmp_buf
+ /// buffers
+ unsigned JumpBufAlignment;
+
+ /// IfCvtBlockSizeLimit - The maximum allowed size for a block to be
+ /// if-converted.
+ unsigned IfCvtBlockSizeLimit;
+
+ /// IfCvtDupBlockSizeLimit - The maximum allowed size for a block to be
+ /// duplicated during if-conversion.
+ unsigned IfCvtDupBlockSizeLimit;
+
+ /// StackPointerRegisterToSaveRestore - If set to a physical register, this
+ /// specifies the register that llvm.savestack/llvm.restorestack should save
+ /// and restore.
+ unsigned StackPointerRegisterToSaveRestore;
+
+ /// ExceptionPointerRegister - If set to a physical register, this specifies
+ /// the register that receives the exception address on entry to a landing
+ /// pad.
+ unsigned ExceptionPointerRegister;
+
+ /// ExceptionSelectorRegister - If set to a physical register, this specifies
+ /// the register that receives the exception typeid on entry to a landing
+ /// pad.
+ unsigned ExceptionSelectorRegister;
+
+ /// RegClassForVT - This indicates the default register class to use for
+ /// each ValueType the target supports natively.
+ TargetRegisterClass *RegClassForVT[MVT::LAST_VALUETYPE];
+ unsigned char NumRegistersForVT[MVT::LAST_VALUETYPE];
+ MVT::ValueType RegisterTypeForVT[MVT::LAST_VALUETYPE];
+
+ /// TransformToType - For any value types we are promoting or expanding, this
+ /// contains the value type that we are changing to. For Expanded types, this
+ /// contains one step of the expand (e.g. i64 -> i32), even if there are
+ /// multiple steps required (e.g. i64 -> i16). For types natively supported
+ /// by the system, this holds the same type (e.g. i32 -> i32).
+ MVT::ValueType TransformToType[MVT::LAST_VALUETYPE];
+
+ /// OpActions - For each operation and each value type, keep a LegalizeAction
+ /// that indicates how instruction selection should deal with the operation.
+ /// Most operations are Legal (aka, supported natively by the target), but
+ /// operations that are not should be described. Note that operations on
+ /// non-legal value types are not described here.
+ uint64_t OpActions[156];
+
+ /// LoadXActions - For each load of load extension type and each value type,
+ /// keep a LegalizeAction that indicates how instruction selection should deal
+ /// with the load.
+ uint64_t LoadXActions[ISD::LAST_LOADX_TYPE];
+
+ /// StoreXActions - For each store with truncation of each value type, keep a
+ /// LegalizeAction that indicates how instruction selection should deal with
+ /// the store.
+ uint64_t StoreXActions;
+
+ /// IndexedModeActions - For each indexed mode and each value type, keep a
+ /// pair of LegalizeAction that indicates how instruction selection should
+ /// deal with the load / store.
+ uint64_t IndexedModeActions[2][ISD::LAST_INDEXED_MODE];
+
+ ValueTypeActionImpl ValueTypeActions;
+
+ std::vector<double> LegalFPImmediates;
+
+ std::vector<std::pair<MVT::ValueType,
+ TargetRegisterClass*> > AvailableRegClasses;
+
+ /// TargetDAGCombineArray - Targets can specify ISD nodes that they would
+ /// like PerformDAGCombine callbacks for by calling setTargetDAGCombine(),
+ /// which sets a bit in this array.
+ unsigned char TargetDAGCombineArray[156/(sizeof(unsigned char)*8)];
+
+ /// PromoteToType - For operations that must be promoted to a specific type,
+ /// this holds the destination type. This map should be sparse, so don't hold
+ /// it as an array.
+ ///
+ /// Targets add entries to this map with AddPromotedToType(..), clients access
+ /// this with getTypeToPromoteTo(..).
+ std::map<std::pair<unsigned, MVT::ValueType>, MVT::ValueType> PromoteToType;
+
+ /// LibcallRoutineNames - Stores the name each libcall.
+ ///
+ const char *LibcallRoutineNames[RTLIB::UNKNOWN_LIBCALL];
+
+ /// CmpLibcallCCs - The ISD::CondCode that should be used to test the result
+ /// of each of the comparison libcall against zero.
+ ISD::CondCode CmpLibcallCCs[RTLIB::UNKNOWN_LIBCALL];
+
+protected:
+ /// When lowering %llvm.memset this field specifies the maximum number of
+ /// store operations that may be substituted for the call to memset. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memset will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, storing 9 bytes on a 32-bit machine
+ /// with 16-bit alignment would result in four 2-byte stores and one 1-byte
+ /// store. This only applies to setting a constant array of a constant size.
+ /// @brief Specify maximum number of store instructions per memset call.
+ unsigned maxStoresPerMemset;
+
+ /// When lowering %llvm.memcpy this field specifies the maximum number of
+ /// store operations that may be substituted for a call to memcpy. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memcpy will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, storing 7 bytes on a 32-bit machine
+ /// with 32-bit alignment would result in one 4-byte store, a one 2-byte store
+ /// and one 1-byte store. This only applies to copying a constant array of
+ /// constant size.
+ /// @brief Specify maximum bytes of store instructions per memcpy call.
+ unsigned maxStoresPerMemcpy;
+
+ /// When lowering %llvm.memmove this field specifies the maximum number of
+ /// store instructions that may be substituted for a call to memmove. Targets
+ /// must set this value based on the cost threshold for that target. Targets
+ /// should assume that the memmove will be done using as many of the largest
+ /// store operations first, followed by smaller ones, if necessary, per
+ /// alignment restrictions. For example, moving 9 bytes on a 32-bit machine
+ /// with 8-bit alignment would result in nine 1-byte stores. This only
+ /// applies to copying a constant array of constant size.
+ /// @brief Specify maximum bytes of store instructions per memmove call.
+ unsigned maxStoresPerMemmove;
+
+ /// This field specifies whether the target machine permits unaligned memory
+ /// accesses. This is used, for example, to determine the size of store
+ /// operations when copying small arrays and other similar tasks.
+ /// @brief Indicate whether the target permits unaligned memory accesses.
+ bool allowUnalignedMemoryAccesses;
+};
+} // end llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetMachOWriterInfo.h b/include/llvm/Target/TargetMachOWriterInfo.h
new file mode 100644
index 0000000..b37b454
--- /dev/null
+++ b/include/llvm/Target/TargetMachOWriterInfo.h
@@ -0,0 +1,112 @@
+//===-- llvm/Target/TargetMachOWriterInfo.h - MachO Writer Info--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Bill Wendling and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetMachOWriterInfo class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETMACHOWRITERINFO_H
+#define LLVM_TARGET_TARGETMACHOWRITERINFO_H
+
+#include "llvm/CodeGen/MachineRelocation.h"
+
+namespace llvm {
+
+ class MachineBasicBlock;
+ class OutputBuffer;
+
+ //===--------------------------------------------------------------------===//
+ // TargetMachOWriterInfo
+ //===--------------------------------------------------------------------===//
+
+ class TargetMachOWriterInfo {
+ uint32_t CPUType; // CPU specifier
+ uint32_t CPUSubType; // Machine specifier
+ public:
+ // The various CPU_TYPE_* constants are already defined by at least one
+ // system header file and create compilation errors if not respected.
+#if !defined(CPU_TYPE_I386)
+#define CPU_TYPE_I386 7
+#endif
+#if !defined(CPU_TYPE_X86_64)
+#define CPU_TYPE_X86_64 (CPU_TYPE_I386 | 0x1000000)
+#endif
+#if !defined(CPU_TYPE_ARM)
+#define CPU_TYPE_ARM 12
+#endif
+#if !defined(CPU_TYPE_SPARC)
+#define CPU_TYPE_SPARC 14
+#endif
+#if !defined(CPU_TYPE_POWERPC)
+#define CPU_TYPE_POWERPC 18
+#endif
+#if !defined(CPU_TYPE_POWERPC64)
+#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | 0x1000000)
+#endif
+
+ // Constants for the cputype field
+ // see <mach/machine.h>
+ enum {
+ HDR_CPU_TYPE_I386 = CPU_TYPE_I386,
+ HDR_CPU_TYPE_X86_64 = CPU_TYPE_X86_64,
+ HDR_CPU_TYPE_ARM = CPU_TYPE_ARM,
+ HDR_CPU_TYPE_SPARC = CPU_TYPE_SPARC,
+ HDR_CPU_TYPE_POWERPC = CPU_TYPE_POWERPC,
+ HDR_CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC64
+ };
+
+#if !defined(CPU_SUBTYPE_I386_ALL)
+#define CPU_SUBTYPE_I386_ALL 3
+#endif
+#if !defined(CPU_SUBTYPE_X86_64_ALL)
+#define CPU_SUBTYPE_X86_64_ALL 3
+#endif
+#if !defined(CPU_SUBTYPE_ARM_ALL)
+#define CPU_SUBTYPE_ARM_ALL 0
+#endif
+#if !defined(CPU_SUBTYPE_SPARC_ALL)
+#define CPU_SUBTYPE_SPARC_ALL 0
+#endif
+#if !defined(CPU_SUBTYPE_POWERPC_ALL)
+#define CPU_SUBTYPE_POWERPC_ALL 0
+#endif
+
+ // Constants for the cpusubtype field
+ // see <mach/machine.h>
+ enum {
+ HDR_CPU_SUBTYPE_I386_ALL = CPU_SUBTYPE_I386_ALL,
+ HDR_CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_X86_64_ALL,
+ HDR_CPU_SUBTYPE_ARM_ALL = CPU_SUBTYPE_ARM_ALL,
+ HDR_CPU_SUBTYPE_SPARC_ALL = CPU_SUBTYPE_SPARC_ALL,
+ HDR_CPU_SUBTYPE_POWERPC_ALL = CPU_SUBTYPE_POWERPC_ALL
+ };
+
+ TargetMachOWriterInfo(uint32_t cputype, uint32_t cpusubtype)
+ : CPUType(cputype), CPUSubType(cpusubtype) {}
+ virtual ~TargetMachOWriterInfo();
+
+ virtual MachineRelocation GetJTRelocation(unsigned Offset,
+ MachineBasicBlock *MBB) const;
+
+ virtual unsigned GetTargetRelocation(MachineRelocation &MR,
+ unsigned FromIdx,
+ unsigned ToAddr,
+ unsigned ToIdx,
+ OutputBuffer &RelocOut,
+ OutputBuffer &SecOut,
+ bool Scattered,
+ bool Extern) const { return 0; }
+
+ uint32_t getCPUType() const { return CPUType; }
+ uint32_t getCPUSubType() const { return CPUSubType; }
+ };
+
+} // end llvm namespace
+
+#endif // LLVM_TARGET_TARGETMACHOWRITERINFO_H
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
new file mode 100644
index 0000000..e7f211b
--- /dev/null
+++ b/include/llvm/Target/TargetMachine.h
@@ -0,0 +1,330 @@
+//===-- llvm/Target/TargetMachine.h - Target Information --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the TargetMachine and LLVMTargetMachine classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETMACHINE_H
+#define LLVM_TARGET_TARGETMACHINE_H
+
+#include "llvm/Target/TargetInstrItineraries.h"
+#include <cassert>
+#include <string>
+
+namespace llvm {
+
+class TargetAsmInfo;
+class TargetData;
+class TargetSubtarget;
+class TargetInstrInfo;
+class TargetInstrDescriptor;
+class TargetJITInfo;
+class TargetLowering;
+class TargetFrameInfo;
+class MachineCodeEmitter;
+class MRegisterInfo;
+class Module;
+class FunctionPassManager;
+class PassManager;
+class Pass;
+class TargetMachOWriterInfo;
+class TargetELFWriterInfo;
+
+// Relocation model types.
+namespace Reloc {
+ enum Model {
+ Default,
+ Static,
+ PIC_, // Cannot be named PIC due to collision with -DPIC
+ DynamicNoPIC
+ };
+}
+
+// Code model types.
+namespace CodeModel {
+ enum Model {
+ Default,
+ Small,
+ Kernel,
+ Medium,
+ Large
+ };
+}
+
+namespace FileModel {
+ enum Model {
+ Error,
+ None,
+ AsmFile,
+ MachOFile,
+ ElfFile
+ };
+}
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetMachine - Primary interface to the complete machine description for
+/// the target machine. All target-specific information should be accessible
+/// through this interface.
+///
+class TargetMachine {
+ TargetMachine(const TargetMachine &); // DO NOT IMPLEMENT
+ void operator=(const TargetMachine &); // DO NOT IMPLEMENT
+protected: // Can only create subclasses.
+ TargetMachine() : AsmInfo(NULL) { }
+
+ /// getSubtargetImpl - virtual method implemented by subclasses that returns
+ /// a reference to that target's TargetSubtarget-derived member variable.
+ virtual const TargetSubtarget *getSubtargetImpl() const { return 0; }
+
+ /// AsmInfo - Contains target specific asm information.
+ ///
+ mutable const TargetAsmInfo *AsmInfo;
+
+ /// createTargetAsmInfo - Create a new instance of target specific asm
+ /// information.
+ virtual const TargetAsmInfo *createTargetAsmInfo() const { return NULL; }
+
+public:
+ virtual ~TargetMachine();
+
+ /// getModuleMatchQuality - This static method should be implemented by
+ /// targets to indicate how closely they match the specified module. This is
+ /// used by the LLC tool to determine which target to use when an explicit
+ /// -march option is not specified. If a target returns zero, it will never
+ /// be chosen without an explicit -march option.
+ static unsigned getModuleMatchQuality(const Module &M) { return 0; }
+
+ /// getJITMatchQuality - This static method should be implemented by targets
+ /// that provide JIT capabilities to indicate how suitable they are for
+ /// execution on the current host. If a value of 0 is returned, the target
+ /// will not be used unless an explicit -march option is used.
+ static unsigned getJITMatchQuality() { return 0; }
+
+ // Interfaces to the major aspects of target machine information:
+ // -- Instruction opcode and operand information
+ // -- Pipelines and scheduling information
+ // -- Stack frame information
+ // -- Selection DAG lowering information
+ //
+ virtual const TargetInstrInfo *getInstrInfo() const { return 0; }
+ virtual const TargetFrameInfo *getFrameInfo() const { return 0; }
+ virtual TargetLowering *getTargetLowering() const { return 0; }
+ virtual const TargetData *getTargetData() const { return 0; }
+
+
+ /// getTargetAsmInfo - Return target specific asm information.
+ ///
+ const TargetAsmInfo *getTargetAsmInfo() const {
+ if (!AsmInfo) AsmInfo = createTargetAsmInfo();
+ return AsmInfo;
+ }
+
+ /// getSubtarget - This method returns a pointer to the specified type of
+ /// TargetSubtarget. In debug builds, it verifies that the object being
+ /// returned is of the correct type.
+ template<typename STC> const STC &getSubtarget() const {
+ const TargetSubtarget *TST = getSubtargetImpl();
+ assert(TST && dynamic_cast<const STC*>(TST) &&
+ "Not the right kind of subtarget!");
+ return *static_cast<const STC*>(TST);
+ }
+
+ /// getRegisterInfo - If register information is available, return it. If
+ /// not, return null. This is kept separate from RegInfo until RegInfo has
+ /// details of graph coloring register allocation removed from it.
+ ///
+ virtual const MRegisterInfo *getRegisterInfo() const { return 0; }
+
+ /// getJITInfo - If this target supports a JIT, return information for it,
+ /// otherwise return null.
+ ///
+ virtual TargetJITInfo *getJITInfo() { return 0; }
+
+ /// getInstrItineraryData - Returns instruction itinerary data for the target
+ /// or specific subtarget.
+ ///
+ virtual const InstrItineraryData getInstrItineraryData() const {
+ return InstrItineraryData();
+ }
+
+ /// getMachOWriterInfo - If this target supports a Mach-O writer, return
+ /// information for it, otherwise return null.
+ ///
+ virtual const TargetMachOWriterInfo *getMachOWriterInfo() const { return 0; }
+
+ /// getELFWriterInfo - If this target supports an ELF writer, return
+ /// information for it, otherwise return null.
+ ///
+ virtual const TargetELFWriterInfo *getELFWriterInfo() const { return 0; }
+
+ /// getRelocationModel - Returns the code generation relocation model. The
+ /// choices are static, PIC, and dynamic-no-pic, and target default.
+ static Reloc::Model getRelocationModel();
+
+ /// setRelocationModel - Sets the code generation relocation model.
+ static void setRelocationModel(Reloc::Model Model);
+
+ /// getCodeModel - Returns the code model. The choices are small, kernel,
+ /// medium, large, and target default.
+ static CodeModel::Model getCodeModel();
+
+ /// setCodeModel - Sets the code model.
+ static void setCodeModel(CodeModel::Model Model);
+
+ /// CodeGenFileType - These enums are meant to be passed into
+ /// addPassesToEmitFile to indicate what type of file to emit.
+ enum CodeGenFileType {
+ AssemblyFile, ObjectFile, DynamicLibrary
+ };
+
+ /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
+ /// on this target. User flag overrides.
+ virtual const bool getEnableTailMergeDefault() const { return true; }
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+ /// specified file emitted. Typically this will involve several steps of code
+ /// generation. If Fast is set to true, the code generator should emit code
+ /// as fast as possible, without regard for compile time. This method should
+ /// return FileModel::Error if emission of this file type is not supported.
+ ///
+ virtual FileModel::Model addPassesToEmitFile(FunctionPassManager &PM,
+ std::ostream &Out,
+ CodeGenFileType FileType,
+ bool Fast) {
+ return FileModel::None;
+ }
+
+ /// addPassesToEmitFileFinish - If the passes to emit the specified file had
+ /// to be split up (e.g., to add an object writer pass), this method can be
+ /// used to finish up adding passes to emit the file, if necessary.
+ ///
+ virtual bool addPassesToEmitFileFinish(FunctionPassManager &PM,
+ MachineCodeEmitter *MCE, bool Fast) {
+ return true;
+ }
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+ MachineCodeEmitter &MCE, bool Fast) {
+ return true;
+ }
+
+ /// addPassesToEmitWholeFile - This method can be implemented by targets that
+ /// require having the entire module at once. This is not recommended, do not
+ /// use this.
+ virtual bool WantsWholeFile() const { return false; }
+ virtual bool addPassesToEmitWholeFile(PassManager &PM, std::ostream &Out,
+ CodeGenFileType FileType, bool Fast) {
+ return true;
+ }
+};
+
+/// LLVMTargetMachine - This class describes a target machine that is
+/// implemented with the LLVM target-independent code generator.
+///
+class LLVMTargetMachine : public TargetMachine {
+protected: // Can only create subclasses.
+ LLVMTargetMachine() { }
+public:
+
+ /// addPassesToEmitFile - Add passes to the specified pass manager to get the
+ /// specified file emitted. Typically this will involve several steps of code
+ /// generation. If Fast is set to true, the code generator should emit code
+ /// as fast as possible, without regard for compile time. This method should
+ /// return FileModel::Error if emission of this file type is not supported.
+ ///
+ /// The default implementation of this method adds components from the
+ /// LLVM retargetable code generator, invoking the methods below to get
+ /// target-specific passes in standard locations.
+ ///
+ virtual FileModel::Model addPassesToEmitFile(FunctionPassManager &PM,
+ std::ostream &Out,
+ CodeGenFileType FileType,
+ bool Fast);
+
+ /// addPassesToEmitFileFinish - If the passes to emit the specified file had
+ /// to be split up (e.g., to add an object writer pass), this method can be
+ /// used to finish up adding passes to emit the file, if necessary.
+ ///
+ virtual bool addPassesToEmitFileFinish(FunctionPassManager &PM,
+ MachineCodeEmitter *MCE, bool Fast);
+
+ /// addPassesToEmitMachineCode - Add passes to the specified pass manager to
+ /// get machine code emitted. This uses a MachineCodeEmitter object to handle
+ /// actually outputting the machine code and resolving things like the address
+ /// of functions. This method returns true if machine code emission is
+ /// not supported.
+ ///
+ virtual bool addPassesToEmitMachineCode(FunctionPassManager &PM,
+ MachineCodeEmitter &MCE, bool Fast);
+
+ /// Target-Independent Code Generator Pass Configuration Options.
+
+ /// addInstSelector - This method should add any "last minute" LLVM->LLVM
+ /// passes, then install an instruction selector pass, which converts from
+ /// LLVM code to machine instructions.
+ virtual bool addInstSelector(FunctionPassManager &PM, bool Fast) {
+ return true;
+ }
+
+ /// addPostRegAllocPasses - This method may be implemented by targets that
+ /// want to run passes after register allocation but before prolog-epilog
+ /// insertion. This should return true if -print-machineinstrs should print
+ /// after these passes.
+ virtual bool addPostRegAlloc(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+ /// addPreEmitPass - This pass may be implemented by targets that want to run
+ /// passes immediately before machine code is emitted. This should return
+ /// true if -print-machineinstrs should print out the code after the passes.
+ virtual bool addPreEmitPass(FunctionPassManager &PM, bool Fast) {
+ return false;
+ }
+
+
+ /// addAssemblyEmitter - This pass should be overridden by the target to add
+ /// the asmprinter, if asm emission is supported. If this is not supported,
+ /// 'true' should be returned.
+ virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
+ std::ostream &Out) {
+ return true;
+ }
+
+ /// addCodeEmitter - This pass should be overridden by the target to add a
+ /// code emitter, if supported. If this is not supported, 'true' should be
+ /// returned.
+ virtual bool addCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
+ return true;
+ }
+
+ /// addSimpleCodeEmitter - This pass should be overridden by the target to add
+ /// a code emitter (without setting flags), if supported. If this is not
+ /// supported, 'true' should be returned.
+ virtual bool addSimpleCodeEmitter(FunctionPassManager &PM, bool Fast,
+ MachineCodeEmitter &MCE) {
+ return true;
+ }
+
+ /// getEnableTailMergeDefault - the default setting for -enable-tail-merge
+ /// on this target. User flag overrides.
+ virtual const bool getEnableTailMergeDefault() const { return true; }
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetMachineRegistry.h b/include/llvm/Target/TargetMachineRegistry.h
new file mode 100644
index 0000000..dd3ed7d
--- /dev/null
+++ b/include/llvm/Target/TargetMachineRegistry.h
@@ -0,0 +1,128 @@
+//===-- Target/TargetMachineRegistry.h - Target Registration ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes two classes: the TargetMachineRegistry class, which allows
+// tools to inspect all of registered targets, and the RegisterTarget class,
+// which TargetMachine implementations should use to register themselves with
+// the system.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETMACHINEREGISTRY_H
+#define LLVM_TARGET_TARGETMACHINEREGISTRY_H
+
+#include "llvm/Support/CommandLine.h"
+
+namespace llvm {
+ class Module;
+ class TargetMachine;
+
+ struct TargetMachineRegistry {
+ struct Entry;
+
+ /// TargetMachineRegistry::getList - This static method returns the list of
+ /// target machines that are registered with the system.
+ static const Entry *getList() { return List; }
+
+ /// getClosestStaticTargetForModule - Given an LLVM module, pick the best
+ /// target that is compatible with the module. If no close target can be
+ /// found, this returns null and sets the Error string to a reason.
+ static const Entry *getClosestStaticTargetForModule(const Module &M,
+ std::string &Error);
+
+ /// getClosestTargetForJIT - Given an LLVM module, pick the best target that
+ /// is compatible with the current host and the specified module. If no
+ /// close target can be found, this returns null and sets the Error string
+ /// to a reason.
+ static const Entry *getClosestTargetForJIT(std::string &Error);
+
+
+ /// Entry - One instance of this struct is created for each target that is
+ /// registered.
+ struct Entry {
+ const char *Name;
+ const char *ShortDesc;
+ TargetMachine *(*CtorFn)(const Module &, const std::string &);
+ unsigned (*ModuleMatchQualityFn)(const Module &M);
+ unsigned (*JITMatchQualityFn)();
+
+ const Entry *getNext() const { return Next; }
+
+ protected:
+ Entry(const char *N, const char *SD,
+ TargetMachine *(*CF)(const Module &, const std::string &),
+ unsigned (*MMF)(const Module &M), unsigned (*JMF)());
+ private:
+ const Entry *Next; // Next entry in the linked list.
+ };
+
+ private:
+ static const Entry *List;
+ };
+
+ //===--------------------------------------------------------------------===//
+ /// RegisterTarget - This class is used to make targets automatically register
+ /// themselves with the tool they are linked. Targets should define an
+ /// instance of this and implement the static methods described in the
+ /// TargetMachine comments.
+ /// The type 'TargetMachineImpl' should provide a constructor with two
+ /// parameters:
+ /// - const Module& M: the module that is being compiled:
+ /// - const std::string& FS: target-specific string describing target
+ /// flavour.
+
+ template<class TargetMachineImpl>
+ struct RegisterTarget : public TargetMachineRegistry::Entry {
+ RegisterTarget(const char *Name, const char *ShortDesc) :
+ TargetMachineRegistry::Entry(Name, ShortDesc, &Allocator,
+ &TargetMachineImpl::getModuleMatchQuality,
+ &TargetMachineImpl::getJITMatchQuality) {
+ }
+ private:
+ static TargetMachine *Allocator(const Module &M, const std::string &FS) {
+ return new TargetMachineImpl(M, FS);
+ }
+ };
+
+ /// TargetRegistrationListener - This class allows code to listen for targets
+ /// that are dynamically registered, and be notified of it when they are.
+ class TargetRegistrationListener {
+ TargetRegistrationListener **Prev, *Next;
+ public:
+ TargetRegistrationListener();
+ virtual ~TargetRegistrationListener();
+
+ TargetRegistrationListener *getNext() const { return Next; }
+
+ virtual void targetRegistered(const TargetMachineRegistry::Entry *E) = 0;
+ };
+
+
+ //===--------------------------------------------------------------------===//
+ /// TargetNameParser - This option can be used to provide a command line
+ /// option to choose among the various registered targets (commonly -march).
+ class TargetNameParser : public TargetRegistrationListener,
+ public cl::parser<const TargetMachineRegistry::Entry*> {
+ public:
+ void initialize(cl::Option &O) {
+ for (const TargetMachineRegistry::Entry *E =
+ TargetMachineRegistry::getList(); E; E = E->getNext())
+ Values.push_back(std::make_pair(E->Name,
+ std::make_pair(E, E->ShortDesc)));
+ cl::parser<const TargetMachineRegistry::Entry*>::initialize(O);
+ }
+
+ virtual void targetRegistered(const TargetMachineRegistry::Entry *E) {
+ Values.push_back(std::make_pair(E->Name,
+ std::make_pair(E, E->ShortDesc)));
+ }
+ };
+}
+
+#endif
diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h
new file mode 100644
index 0000000..76f2d55
--- /dev/null
+++ b/include/llvm/Target/TargetOptions.h
@@ -0,0 +1,79 @@
+//===-- llvm/Target/TargetOptions.h - Target Options ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines command line option flags that are shared across various
+// targets.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETOPTIONS_H
+#define LLVM_TARGET_TARGETOPTIONS_H
+
+namespace llvm {
+ /// PrintMachineCode - This flag is enabled when the -print-machineinstrs
+ /// option is specified on the command line, and should enable debugging
+ /// output from the code generator.
+ extern bool PrintMachineCode;
+
+ /// NoFramePointerElim - This flag is enabled when the -disable-fp-elim is
+ /// specified on the command line. If the target supports the frame pointer
+ /// elimination optimization, this option should disable it.
+ extern bool NoFramePointerElim;
+
+ /// NoExcessFPPrecision - This flag is enabled when the
+ /// -disable-excess-fp-precision flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is allowed to produce
+ /// results that are "more precise" than IEEE allows. This includes use of
+ /// FMA-like operations and use of the X86 FP registers without rounding all
+ /// over the place.
+ extern bool NoExcessFPPrecision;
+
+ /// UnsafeFPMath - This flag is enabled when the
+ /// -enable-unsafe-fp-math flag is specified on the command line. When
+ /// this flag is off (the default), the code generator is not allowed to
+ /// produce results that are "less precise" than IEEE allows. This includes
+ /// use of X86 instructions like FSIN and FCOS instead of libcalls.
+ /// UnsafeFPMath implies FiniteOnlyFPMath.
+ extern bool UnsafeFPMath;
+
+ /// FiniteOnlyFPMath - This returns true when the -enable-finite-only-fp-math
+ /// option is specified on the command line. If this returns false (default),
+ /// the code generator is not allowed to assume that FP arithmetic arguments
+ /// and results are never NaNs or +-Infs.
+ extern bool FiniteOnlyFPMathOption;
+ extern bool FiniteOnlyFPMath();
+
+ /// HonorSignDependentRoundingFPMath - This returns true when the
+ /// -enable-sign-dependent-rounding-fp-math is specified. If this returns
+ /// false (the default), the code generator is allowed to assume that the
+ /// rounding behavior is the default (round-to-zero for all floating point to
+ /// integer conversions, and round-to-nearest for all other arithmetic
+ /// truncations). If this is enabled (set to true), the code generator must
+ /// assume that the rounding mode may dynamically change.
+ extern bool HonorSignDependentRoundingFPMathOption;
+ extern bool HonorSignDependentRoundingFPMath();
+
+ /// UseSoftFloat - This flag is enabled when the -soft-float flag is specified
+ /// on the command line. When this flag is on, the code generator will
+ /// generate libcalls to the software floating point library instead of
+ /// target FP instructions.
+ extern bool UseSoftFloat;
+
+ /// NoZerosInBSS - By default some codegens place zero-initialized data to
+ /// .bss section. This flag disables such behaviour (necessary, e.g. for
+ /// crt*.o compiling).
+ extern bool NoZerosInBSS;
+
+ /// ExceptionHandling - This flag indicates that exception information should
+ /// be emitted.
+ extern bool ExceptionHandling;
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Target/TargetSubtarget.h b/include/llvm/Target/TargetSubtarget.h
new file mode 100644
index 0000000..3b174c2
--- /dev/null
+++ b/include/llvm/Target/TargetSubtarget.h
@@ -0,0 +1,36 @@
+//==-- llvm/Target/TargetSubtarget.h - Target Information --------*- C++ -*-==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Nate Begeman and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the subtarget options of a Target machine.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TARGET_TARGETSUBTARGET_H
+#define LLVM_TARGET_TARGETSUBTARGET_H
+
+namespace llvm {
+
+//===----------------------------------------------------------------------===//
+///
+/// TargetSubtarget - Generic base class for all target subtargets. All
+/// Target-specific options that control code generation and printing should
+/// be exposed through a TargetSubtarget-derived class.
+///
+class TargetSubtarget {
+ TargetSubtarget(const TargetSubtarget&); // DO NOT IMPLEMENT
+ void operator=(const TargetSubtarget&); // DO NOT IMPLEMENT
+protected: // Can only create subclasses...
+ TargetSubtarget();
+public:
+ virtual ~TargetSubtarget();
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h
new file mode 100644
index 0000000..6ab6d7b
--- /dev/null
+++ b/include/llvm/Transforms/IPO.h
@@ -0,0 +1,173 @@
+//===- llvm/Transforms/IPO.h - Interprocedural Transformations --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the IPO transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_H
+#define LLVM_TRANSFORMS_IPO_H
+
+#include <vector>
+
+namespace llvm {
+
+class FunctionPass;
+class ModulePass;
+class Pass;
+class Function;
+class BasicBlock;
+
+//===----------------------------------------------------------------------===//
+//
+// These functions removes symbols from functions and modules. If OnlyDebugInfo
+// is true, only debugging information is removed from the module.
+//
+ModulePass *createStripSymbolsPass(bool OnlyDebugInfo = false);
+
+//===----------------------------------------------------------------------===//
+/// createLowerSetJmpPass - This function lowers the setjmp/longjmp intrinsics
+/// to invoke/unwind instructions. This should really be part of the C/C++
+/// front-end, but it's so much easier to write transformations in LLVM proper.
+///
+ModulePass* createLowerSetJmpPass();
+
+//===----------------------------------------------------------------------===//
+/// createConstantMergePass - This function returns a new pass that merges
+/// duplicate global constants together into a single constant that is shared.
+/// This is useful because some passes (ie TraceValues) insert a lot of string
+/// constants into the program, regardless of whether or not they duplicate an
+/// existing string.
+///
+ModulePass *createConstantMergePass();
+
+
+//===----------------------------------------------------------------------===//
+/// createGlobalOptimizerPass - This function returns a new pass that optimizes
+/// non-address taken internal globals.
+///
+ModulePass *createGlobalOptimizerPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createRaiseAllocationsPass - Return a new pass that transforms malloc and
+/// free function calls into malloc and free instructions.
+///
+ModulePass *createRaiseAllocationsPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createDeadTypeEliminationPass - Return a new pass that eliminates symbol
+/// table entries for types that are never used.
+///
+ModulePass *createDeadTypeEliminationPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createGlobalDCEPass - This transform is designed to eliminate unreachable
+/// internal globals (functions or global variables)
+///
+ModulePass *createGlobalDCEPass();
+
+
+//===----------------------------------------------------------------------===//
+/// createFunctionExtractionPass - If deleteFn is true, this pass deletes as
+/// the specified function. Otherwise, it deletes as much of the module as
+/// possible, except for the function specified.
+///
+ModulePass *createFunctionExtractionPass(Function *F, bool deleteFn = false,
+ bool relinkCallees = false);
+
+
+//===----------------------------------------------------------------------===//
+/// createFunctionInliningPass - Return a new pass object that uses a heuristic
+/// to inline direct function calls to small functions.
+///
+Pass *createFunctionInliningPass();
+
+//===----------------------------------------------------------------------===//
+/// createPruneEHPass - Return a new pass object which transforms invoke
+/// instructions into calls, if the callee can _not_ unwind the stack.
+///
+Pass *createPruneEHPass();
+
+//===----------------------------------------------------------------------===//
+/// createInternalizePass - This pass loops over all of the functions in the
+/// input module, looking for a main function. If a list of symbols is
+/// specified with the -internalize-public-api-* command line options, those
+/// symbols are internalized. Otherwise if InternalizeEverything is set and
+/// the main function is found, all other globals are marked as internal.
+///
+ModulePass *createInternalizePass(bool InternalizeEverything);
+ModulePass *createInternalizePass(const std::vector<const char *> &exportList);
+
+//===----------------------------------------------------------------------===//
+/// createDeadArgEliminationPass - This pass removes arguments from functions
+/// which are not used by the body of the function.
+///
+ModulePass *createDeadArgEliminationPass();
+
+/// DeadArgHacking pass - Same as DAE, but delete arguments of external
+/// functions as well. This is definitely not safe, and should only be used by
+/// bugpoint.
+ModulePass *createDeadArgHackingPass();
+
+//===----------------------------------------------------------------------===//
+/// createArgumentPromotionPass - This pass promotes "by reference" arguments to
+/// be passed by value.
+///
+Pass *createArgumentPromotionPass();
+
+//===----------------------------------------------------------------------===//
+/// createIPConstantPropagationPass - This pass propagates constants from call
+/// sites into the bodies of functions.
+///
+ModulePass *createIPConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+/// createIPSCCPPass - This pass propagates constants from call sites into the
+/// bodies of functions, and keeps track of whether basic blocks are executable
+/// in the process.
+///
+ModulePass *createIPSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+/// createLoopExtractorPass - This pass extracts all natural loops from the
+/// program into a function if it can.
+///
+FunctionPass *createLoopExtractorPass();
+
+/// createSingleLoopExtractorPass - This pass extracts one natural loop from the
+/// program into a function if it can. This is used by bugpoint.
+///
+FunctionPass *createSingleLoopExtractorPass();
+
+/// createBlockExtractorPass - This pass extracts all blocks (except those
+/// specified in the argument list) from the functions in the module.
+///
+ModulePass *createBlockExtractorPass(std::vector<BasicBlock*> &BTNE);
+
+/// createOptimizeWellKnownCallsPass - This pass optimizes specific calls to
+/// specific well-known (library) functions.
+ModulePass *createSimplifyLibCallsPass();
+
+
+/// createIndMemRemPass - This pass removes potential indirect calls of
+/// malloc and free
+ModulePass *createIndMemRemPass();
+
+/// createStripDeadPrototypesPass - This pass removes any function declarations
+/// (prototypes) that are not used.
+ModulePass *createStripDeadPrototypesPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/IPO/InlinerPass.h b/include/llvm/Transforms/IPO/InlinerPass.h
new file mode 100644
index 0000000..01f1aff
--- /dev/null
+++ b/include/llvm/Transforms/IPO/InlinerPass.h
@@ -0,0 +1,64 @@
+//===- InlinerPass.h - Code common to all inliners --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a simple policy-based bottom-up inliner. This file
+// implements all of the boring mechanics of the bottom-up inlining, while the
+// subclass determines WHAT to inline, which is the much more interesting
+// component.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INLINER_H
+#define INLINER_H
+
+#include "llvm/CallGraphSCCPass.h"
+
+namespace llvm {
+ class CallSite;
+
+/// Inliner - This class contains all of the helper code which is used to
+/// perform the inlining operations that does not depend on the policy.
+///
+struct Inliner : public CallGraphSCCPass {
+ Inliner(const void *ID);
+
+ /// getAnalysisUsage - For this class, we declare that we require and preserve
+ /// the call graph. If the derived class implements this method, it should
+ /// always explicitly call the implementation here.
+ virtual void getAnalysisUsage(AnalysisUsage &Info) const;
+
+ // Main run interface method, this implements the interface required by the
+ // Pass class.
+ virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
+
+ // doFinalization - Remove now-dead linkonce functions at the end of
+ // processing to avoid breaking the SCC traversal.
+ virtual bool doFinalization(CallGraph &CG);
+
+
+ /// This method returns the value specified by the -inline-threshold value,
+ /// specified on the command line. This is typically not directly needed.
+ ///
+ unsigned getInlineThreshold() const { return InlineThreshold; }
+
+ /// getInlineCost - This method must be implemented by the subclass to
+ /// determine the cost of inlining the specified call site. If the cost
+ /// returned is greater than the current inline threshold, the call site is
+ /// not inlined.
+ ///
+ virtual int getInlineCost(CallSite CS) = 0;
+
+private:
+ // InlineThreshold - Cache the value here for easy access.
+ unsigned InlineThreshold;
+};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Instrumentation.h b/include/llvm/Transforms/Instrumentation.h
new file mode 100644
index 0000000..82e4676
--- /dev/null
+++ b/include/llvm/Transforms/Instrumentation.h
@@ -0,0 +1,37 @@
+//===- Transforms/Instrumentation.h - Instrumentation passes ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files defines constructor functions for instrumentation passes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H
+#define LLVM_TRANSFORMS_INSTRUMENTATION_H
+
+namespace llvm {
+
+class ModulePass;
+class FunctionPass;
+
+// Insert function profiling instrumentation
+ModulePass *createFunctionProfilerPass();
+
+// Insert block profiling instrumentation
+ModulePass *createBlockProfilerPass();
+
+// Insert edge profiling instrumentation
+ModulePass *createEdgeProfilerPass();
+
+// Random Sampling Profiling Framework
+ModulePass* createNullProfilerRSPass();
+FunctionPass* createRSProfilingPass();
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/RSProfiling.h b/include/llvm/Transforms/RSProfiling.h
new file mode 100644
index 0000000..b5cb302
--- /dev/null
+++ b/include/llvm/Transforms/RSProfiling.h
@@ -0,0 +1,33 @@
+//===- RSProfiling.cpp - Various profiling using random sampling ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the abstract interface that a profiler must implement to
+// support the random profiling transform.
+//
+//===----------------------------------------------------------------------===//
+
+namespace llvm {
+ //===--------------------------------------------------------------------===//
+ /// RSProfilers - The basic Random Sampling Profiler Interface Any profiler
+ /// that implements this interface can be transformed by the random sampling
+ /// pass to be sample based rather than always on.
+ ///
+ /// The only exposed function can be queried to find out if an instruction
+ /// was original or if it was inserted by the profiler. Implementations of
+ /// this interface are expected to chain to other implementations, such that
+ /// multiple profilers can be support simultaniously.
+ struct RSProfilers : public ModulePass {
+ static char ID; // Pass identification, replacement for typeinfo
+ RSProfilers() : ModulePass((intptr_t)&ID) {}
+
+ /// isProfiling - This method returns true if the value passed it was
+ /// inserted by the profiler.
+ virtual bool isProfiling(Value* v) = 0;
+ };
+}
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
new file mode 100644
index 0000000..4fea3f7
--- /dev/null
+++ b/include/llvm/Transforms/Scalar.h
@@ -0,0 +1,341 @@
+//===-- Scalar.h - Scalar Transformations -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header file defines prototypes for accessor functions that expose passes
+// in the Scalar transformations library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_SCALAR_H
+#define LLVM_TRANSFORMS_SCALAR_H
+
+#include <cstdlib>
+
+namespace llvm {
+
+class FunctionPass;
+class LoopPass;
+class Pass;
+class GetElementPtrInst;
+class PassInfo;
+class TerminatorInst;
+class TargetLowering;
+
+//===----------------------------------------------------------------------===//
+//
+// ConstantPropagation - A worklist driven constant propagation pass
+//
+FunctionPass *createConstantPropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// SCCP - Sparse conditional constant propagation.
+//
+FunctionPass *createSCCPPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadInstElimination - This pass quickly removes trivially dead instructions
+// without modifying the CFG of the function. It is a BasicBlockPass, so it
+// runs efficiently when queued next to other BasicBlockPass's.
+//
+Pass *createDeadInstEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadCodeElimination - This pass is more powerful than DeadInstElimination,
+// because it is worklist driven that can potentially revisit instructions when
+// their other instructions become dead, to eliminate chains of dead
+// computations.
+//
+FunctionPass *createDeadCodeEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// DeadStoreElimination - This pass deletes stores that are post-dominated by
+// must-aliased stores and are not loaded used between the stores.
+//
+FunctionPass *createDeadStoreEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// AggressiveDCE - This pass uses the SSA based Aggressive DCE algorithm. This
+// algorithm assumes instructions are dead until proven otherwise, which makes
+// it more successful are removing non-obviously dead instructions.
+//
+FunctionPass *createAggressiveDCEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// ScalarReplAggregates - Break up alloca's of aggregates into multiple allocas
+// if possible.
+//
+FunctionPass *createScalarReplAggregatesPass(signed Threshold = -1);
+
+//===----------------------------------------------------------------------===//
+//
+// GCSE - This pass is designed to be a very quick global transformation that
+// eliminates global common subexpressions from a function. It does this by
+// examining the SSA value graph of the function, instead of doing slow
+// bit-vector computations.
+//
+FunctionPass *createGCSEPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InductionVariableSimplify - Transform induction variables in a program to all
+// use a single canonical induction variable per loop.
+//
+LoopPass *createIndVarSimplifyPass();
+
+//===----------------------------------------------------------------------===//
+//
+// InstructionCombining - Combine instructions to form fewer, simple
+// instructions. This pass does not modify the CFG, and has a tendency to make
+// instructions dead, so a subsequent DCE pass is useful.
+//
+// This pass combines things like:
+// %Y = add int 1, %X
+// %Z = add int 1, %Y
+// into:
+// %Z = add int 2, %X
+//
+FunctionPass *createInstructionCombiningPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LICM - This pass is a loop invariant code motion and memory promotion pass.
+//
+LoopPass *createLICMPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopStrengthReduce - This pass is strength reduces GEP instructions that use
+// a loop's canonical induction variable as one of their indices. It takes an
+// optional parameter used to consult the target machine whether certain
+// transformations are profitable.
+//
+LoopPass *createLoopStrengthReducePass(const TargetLowering *TLI = 0);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnswitch - This pass is a simple loop unswitching pass.
+//
+LoopPass *createLoopUnswitchPass(bool OptimizeForSize = false);
+
+//===----------------------------------------------------------------------===//
+//
+// LoopUnroll - This pass is a simple loop unrolling pass.
+//
+LoopPass *createLoopUnrollPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LoopRotate - This pass is a simple loop rotating pass.
+//
+LoopPass *createLoopRotatePass();
+
+
+//===----------------------------------------------------------------------===//
+//
+// PromoteMemoryToRegister - This pass is used to promote memory references to
+// be register references. A simple example of the transformation performed by
+// this pass is:
+//
+// FROM CODE TO CODE
+// %X = alloca int, uint 1 ret int 42
+// store int 42, int *%X
+// %Y = load int* %X
+// ret int %Y
+//
+FunctionPass *createPromoteMemoryToRegisterPass();
+extern const PassInfo *PromoteMemoryToRegisterID;
+
+//===----------------------------------------------------------------------===//
+//
+// DemoteRegisterToMemoryPass - This pass is used to demote registers to memory
+// references. In basically undoes the PromoteMemoryToRegister pass to make cfg
+// hacking easier.
+//
+FunctionPass *createDemoteRegisterToMemoryPass();
+extern const PassInfo *DemoteRegisterToMemoryID;
+
+//===----------------------------------------------------------------------===//
+//
+// Reassociate - This pass reassociates commutative expressions in an order that
+// is designed to promote better constant propagation, GCSE, LICM, PRE...
+//
+// For example: 4 + (x + 5) -> x + (4 + 5)
+//
+FunctionPass *createReassociatePass();
+
+//===----------------------------------------------------------------------===//
+//
+// CorrelatedExpressionElimination - This pass eliminates correlated
+// conditions, such as these:
+// if (X == 0)
+// if (X > 2) ; // Known false
+// else
+// Y = X * Z; // = 0
+//
+FunctionPass *createCorrelatedExpressionEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CondPropagationPass - This pass propagates information about conditional
+// expressions through the program, allowing it to eliminate conditional
+// branches in some cases.
+//
+FunctionPass *createCondPropagationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// TailDuplication - Eliminate unconditional branches through controlled code
+// duplication, creating simpler CFG structures.
+//
+FunctionPass *createTailDuplicationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CFGSimplification - Merge basic blocks, eliminate unreachable blocks,
+// simplify terminator instructions, etc...
+//
+FunctionPass *createCFGSimplificationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// BreakCriticalEdges - Break all of the critical edges in the CFG by inserting
+// a dummy basic block. This pass may be "required" by passes that cannot deal
+// with critical edges. For this usage, a pass must call:
+//
+// AU.addRequiredID(BreakCriticalEdgesID);
+//
+// This pass obviously invalidates the CFG, but can update forward dominator
+// (set, immediate dominators, tree, and frontier) information.
+//
+FunctionPass *createBreakCriticalEdgesPass();
+extern const PassInfo *BreakCriticalEdgesID;
+
+//===----------------------------------------------------------------------===//
+//
+// LoopSimplify - Insert Pre-header blocks into the CFG for every function in
+// the module. This pass updates dominator information, loop information, and
+// does not add critical edges to the CFG.
+//
+// AU.addRequiredID(LoopSimplifyID);
+//
+FunctionPass *createLoopSimplifyPass();
+extern const PassInfo *LoopSimplifyID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerSelect - This pass converts SelectInst instructions into conditional
+// branch and PHI instructions. If the OnlyFP flag is set to true, then only
+// floating point select instructions are lowered.
+//
+FunctionPass *createLowerSelectPass(bool OnlyFP = false);
+extern const PassInfo *LowerSelectID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerAllocations - Turn malloc and free instructions into %malloc and %free
+// calls.
+//
+// AU.addRequiredID(LowerAllocationsID);
+//
+Pass *createLowerAllocationsPass(bool LowerMallocArgToInteger = false);
+extern const PassInfo *LowerAllocationsID;
+
+//===----------------------------------------------------------------------===//
+//
+// TailCallElimination - This pass eliminates call instructions to the current
+// function which occur immediately before return instructions.
+//
+FunctionPass *createTailCallEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerSwitch - This pass converts SwitchInst instructions into a sequence of
+// chained binary branch instructions.
+//
+FunctionPass *createLowerSwitchPass();
+extern const PassInfo *LowerSwitchID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerPacked - This pass converts VectorType operations into low-level scalar
+// operations.
+//
+FunctionPass *createLowerPackedPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LowerInvoke - This pass converts invoke and unwind instructions to use sjlj
+// exception handling mechanisms. Note that after this pass runs the CFG is not
+// entirely accurate (exceptional control flow edges are not correct anymore) so
+// only very simple things should be done after the lowerinvoke pass has run
+// (like generation of native code). This should *NOT* be used as a general
+// purpose "my LLVM-to-LLVM pass doesn't support the invoke instruction yet"
+// lowering pass.
+//
+FunctionPass *createLowerInvokePass(const TargetLowering *TLI = NULL);
+extern const PassInfo *LowerInvokePassID;
+
+//===----------------------------------------------------------------------===//
+//
+// LowerGCPass - This function returns an instance of the "lowergc" pass, which
+// lowers garbage collection intrinsics to normal LLVM code.
+//
+FunctionPass *createLowerGCPass();
+
+//===----------------------------------------------------------------------===//
+//
+// BlockPlacement - This pass reorders basic blocks in order to increase the
+// number of fall-through conditional branches.
+//
+FunctionPass *createBlockPlacementPass();
+
+//===----------------------------------------------------------------------===//
+//
+// LCSSA - This pass inserts phi nodes at loop boundaries to simplify other loop
+// optimizations.
+//
+LoopPass *createLCSSAPass();
+extern const PassInfo *LCSSAID;
+
+//===----------------------------------------------------------------------===//
+//
+// PredicateSimplifier - This pass collapses duplicate variables into one
+// canonical form, and tries to simplify expressions along the way.
+//
+FunctionPass *createPredicateSimplifierPass();
+
+//===----------------------------------------------------------------------===//
+//
+// GVN-PRE - This pass performs global value numbering and partial redundancy
+// elimination.
+//
+FunctionPass *createGVNPREPass();
+
+//===----------------------------------------------------------------------===//
+//
+// FastDeadStoreElimination - This pass deletes stores that are post-dominated by
+// must-aliased stores and are not loaded used between the stores.
+//
+FunctionPass *createFastDeadStoreEliminationPass();
+
+//===----------------------------------------------------------------------===//
+//
+// CodeGenPrepare - This pass prepares a function for instruction selection.
+//
+FunctionPass *createCodeGenPreparePass(const TargetLowering *TLI = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/BasicBlockUtils.h b/include/llvm/Transforms/Utils/BasicBlockUtils.h
new file mode 100644
index 0000000..47bbcbe
--- /dev/null
+++ b/include/llvm/Transforms/Utils/BasicBlockUtils.h
@@ -0,0 +1,123 @@
+//===-- Transform/Utils/BasicBlockUtils.h - BasicBlock Utils ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform manipulations on basic blocks, and
+// instructions contained within basic blocks.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
+#define LLVM_TRANSFORMS_UTILS_BASICBLOCK_H
+
+// FIXME: Move to this file: BasicBlock::removePredecessor, BB::splitBasicBlock
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Support/CFG.h"
+
+namespace llvm {
+
+class Instruction;
+class Pass;
+
+// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
+// with a value, then remove and delete the original instruction.
+//
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+ BasicBlock::iterator &BI, Value *V);
+
+// ReplaceInstWithInst - Replace the instruction specified by BI with the
+// instruction specified by I. The original instruction is deleted and BI is
+// updated to point to the new instruction.
+//
+void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
+ BasicBlock::iterator &BI, Instruction *I);
+
+// ReplaceInstWithInst - Replace the instruction specified by From with the
+// instruction specified by To.
+//
+void ReplaceInstWithInst(Instruction *From, Instruction *To);
+
+
+// RemoveSuccessor - Change the specified terminator instruction such that its
+// successor #SuccNum no longer exists. Because this reduces the outgoing
+// degree of the current basic block, the actual terminator instruction itself
+// may have to be changed. In the case where the last successor of the block is
+// deleted, a return instruction is inserted in its place which can cause a
+// suprising change in program behavior if it is not expected.
+//
+void RemoveSuccessor(TerminatorInst *TI, unsigned SuccNum);
+
+/// isCriticalEdge - Return true if the specified edge is a critical edge.
+/// Critical edges are edges from a block with multiple successors to a block
+/// with multiple predecessors.
+///
+bool isCriticalEdge(const TerminatorInst *TI, unsigned SuccNum,
+ bool AllowIdenticalEdges = false);
+
+/// SplitCriticalEdge - If this edge is a critical edge, insert a new node to
+/// split the critical edge. This will update DominatorTree, and DominatorFrontier
+/// information if it is available, thus calling this pass will not invalidate
+/// either of them. This returns true if the edge was split, false otherwise.
+/// If MergeIdenticalEdges is true (the default), *all* edges from TI to the
+/// specified successor will be merged into the same critical edge block.
+/// This is most commonly interesting with switch instructions, which may
+/// have many edges to any one destination. This ensures that all edges to that
+/// dest go to one block instead of each going to a different block, but isn't
+/// the standard definition of a "critical edge".
+///
+bool SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P = 0,
+ bool MergeIdenticalEdges = false);
+
+inline bool SplitCriticalEdge(BasicBlock *BB, succ_iterator SI, Pass *P = 0) {
+ return SplitCriticalEdge(BB->getTerminator(), SI.getSuccessorIndex(), P);
+}
+
+/// SplitCriticalEdge - If the edge from *PI to BB is not critical, return
+/// false. Otherwise, split all edges between the two blocks and return true.
+/// This updates all of the same analyses as the other SplitCriticalEdge
+/// function. If P is specified, it updates the analyses
+/// described above.
+inline bool SplitCriticalEdge(BasicBlock *Succ, pred_iterator PI, Pass *P = 0) {
+ bool MadeChange = false;
+ TerminatorInst *TI = (*PI)->getTerminator();
+ for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i)
+ if (TI->getSuccessor(i) == Succ)
+ MadeChange |= SplitCriticalEdge(TI, i, P);
+ return MadeChange;
+}
+
+/// SplitCriticalEdge - If an edge from Src to Dst is critical, split the edge
+/// and return true, otherwise return false. This method requires that there be
+/// an edge between the two blocks. If P is specified, it updates the analyses
+/// described above.
+inline bool SplitCriticalEdge(BasicBlock *Src, BasicBlock *Dst, Pass *P = 0,
+ bool MergeIdenticalEdges = false) {
+ TerminatorInst *TI = Src->getTerminator();
+ unsigned i = 0;
+ while (1) {
+ assert(i != TI->getNumSuccessors() && "Edge doesn't exist!");
+ if (TI->getSuccessor(i) == Dst)
+ return SplitCriticalEdge(TI, i, P, MergeIdenticalEdges);
+ ++i;
+ }
+}
+
+/// SplitEdge - Split the edge connecting specified block. Pass P must
+/// not be NULL.
+BasicBlock *SplitEdge(BasicBlock *From, BasicBlock *To, Pass *P);
+
+/// SplitBlock - Split the specified block at the specified instruction - every
+/// thing before SplitPt stays in Old and everything starting with SplitPt moves
+/// to a new block. The two blocks are joined by an unconditional branch and
+/// the loop info is updated.
+///
+BasicBlock *SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P);
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h
new file mode 100644
index 0000000..9f1aad7
--- /dev/null
+++ b/include/llvm/Transforms/Utils/Cloning.h
@@ -0,0 +1,181 @@
+//===- Cloning.h - Clone various parts of LLVM programs ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines various functions that are used to clone chunks of LLVM
+// code for various purposes. This varies from copying whole modules into new
+// modules, to cloning functions with different arguments, to inlining
+// functions, to copying basic blocks to support loop unrolling or superblock
+// formation, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CLONING_H
+#define LLVM_TRANSFORMS_UTILS_CLONING_H
+
+#include <vector>
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+
+class Module;
+class Function;
+class BasicBlock;
+class Value;
+class CallInst;
+class InvokeInst;
+class ReturnInst;
+class CallSite;
+class Trace;
+class CallGraph;
+class TargetData;
+
+/// CloneModule - Return an exact copy of the specified module
+///
+Module *CloneModule(const Module *M);
+Module *CloneModule(const Module *M, DenseMap<const Value*, Value*> &ValueMap);
+
+/// ClonedCodeInfo - This struct can be used to capture information about code
+/// being cloned, while it is being cloned.
+struct ClonedCodeInfo {
+ /// ContainsCalls - This is set to true if the cloned code contains a normal
+ /// call instruction.
+ bool ContainsCalls;
+
+ /// ContainsUnwinds - This is set to true if the cloned code contains an
+ /// unwind instruction.
+ bool ContainsUnwinds;
+
+ /// ContainsDynamicAllocas - This is set to true if the cloned code contains
+ /// a 'dynamic' alloca. Dynamic allocas are allocas that are either not in
+ /// the entry block or they are in the entry block but are not a constant
+ /// size.
+ bool ContainsDynamicAllocas;
+
+ ClonedCodeInfo() {
+ ContainsCalls = false;
+ ContainsUnwinds = false;
+ ContainsDynamicAllocas = false;
+ }
+};
+
+
+/// CloneBasicBlock - Return a copy of the specified basic block, but without
+/// embedding the block into a particular function. The block returned is an
+/// exact copy of the specified basic block, without any remapping having been
+/// performed. Because of this, this is only suitable for applications where
+/// the basic block will be inserted into the same function that it was cloned
+/// from (loop unrolling would use this, for example).
+///
+/// Also, note that this function makes a direct copy of the basic block, and
+/// can thus produce illegal LLVM code. In particular, it will copy any PHI
+/// nodes from the original block, even though there are no predecessors for the
+/// newly cloned block (thus, phi nodes will have to be updated). Also, this
+/// block will branch to the old successors of the original block: these
+/// successors will have to have any PHI nodes updated to account for the new
+/// incoming edges.
+///
+/// The correlation between instructions in the source and result basic blocks
+/// is recorded in the ValueMap map.
+///
+/// If you have a particular suffix you'd like to use to add to any cloned
+/// names, specify it as the optional third parameter.
+///
+/// If you would like the basic block to be auto-inserted into the end of a
+/// function, you can specify it as the optional fourth parameter.
+///
+/// If you would like to collect additional information about the cloned
+/// function, you can specify a ClonedCodeInfo object with the optional fifth
+/// parameter.
+///
+BasicBlock *CloneBasicBlock(const BasicBlock *BB,
+ DenseMap<const Value*, Value*> &ValueMap,
+ const char *NameSuffix = "", Function *F = 0,
+ ClonedCodeInfo *CodeInfo = 0);
+
+
+/// CloneFunction - Return a copy of the specified function, but without
+/// embedding the function into another module. Also, any references specified
+/// in the ValueMap are changed to refer to their mapped value instead of the
+/// original one. If any of the arguments to the function are in the ValueMap,
+/// the arguments are deleted from the resultant function. The ValueMap is
+/// updated to include mappings from all of the instructions and basicblocks in
+/// the function from their old to new values. The final argument captures
+/// information about the cloned code if non-null.
+///
+Function *CloneFunction(const Function *F,
+ DenseMap<const Value*, Value*> &ValueMap,
+ ClonedCodeInfo *CodeInfo = 0);
+
+/// CloneFunction - Version of the function that doesn't need the ValueMap.
+///
+inline Function *CloneFunction(const Function *F, ClonedCodeInfo *CodeInfo = 0){
+ DenseMap<const Value*, Value*> ValueMap;
+ return CloneFunction(F, ValueMap, CodeInfo);
+}
+
+/// Clone OldFunc into NewFunc, transforming the old arguments into references
+/// to ArgMap values. Note that if NewFunc already has basic blocks, the ones
+/// cloned into it will be added to the end of the function. This function
+/// fills in a list of return instructions, and can optionally append the
+/// specified suffix to all values cloned.
+///
+void CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
+ DenseMap<const Value*, Value*> &ValueMap,
+ std::vector<ReturnInst*> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = 0);
+
+/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
+/// except that it does some simple constant prop and DCE on the fly. The
+/// effect of this is to copy significantly less code in cases where (for
+/// example) a function call with constant arguments is inlined, and those
+/// constant arguments cause a significant amount of code in the callee to be
+/// dead. Since this doesn't produce an exactly copy of the input, it can't be
+/// used for things like CloneFunction or CloneModule.
+void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
+ DenseMap<const Value*, Value*> &ValueMap,
+ std::vector<ReturnInst*> &Returns,
+ const char *NameSuffix = "",
+ ClonedCodeInfo *CodeInfo = 0,
+ const TargetData *TD = 0);
+
+
+/// CloneTraceInto - Clone T into NewFunc. Original<->clone mapping is
+/// saved in ValueMap.
+///
+void CloneTraceInto(Function *NewFunc, Trace &T,
+ DenseMap<const Value*, Value*> &ValueMap,
+ const char *NameSuffix);
+
+/// CloneTrace - Returns a copy of the specified trace.
+/// It takes a vector of basic blocks clones the basic blocks, removes internal
+/// phi nodes, adds it to the same function as the original (although there is
+/// no jump to it) and returns the new vector of basic blocks.
+std::vector<BasicBlock *> CloneTrace(const std::vector<BasicBlock*> &origTrace);
+
+/// InlineFunction - This function inlines the called function into the basic
+/// block of the caller. This returns false if it is not possible to inline
+/// this call. The program is still in a well defined state if this occurs
+/// though.
+///
+/// Note that this only does one level of inlining. For example, if the
+/// instruction 'call B' is inlined, and 'B' calls 'C', then the call to 'C' now
+/// exists in the instruction stream. Similiarly this will inline a recursive
+/// function by one level.
+///
+/// If a non-null callgraph pointer is provided, these functions update the
+/// CallGraph to represent the program after inlining.
+///
+bool InlineFunction(CallInst *C, CallGraph *CG = 0, const TargetData *TD = 0);
+bool InlineFunction(InvokeInst *II, CallGraph *CG = 0, const TargetData *TD =0);
+bool InlineFunction(CallSite CS, CallGraph *CG = 0, const TargetData *TD = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/FunctionUtils.h b/include/llvm/Transforms/Utils/FunctionUtils.h
new file mode 100644
index 0000000..cf8abdf
--- /dev/null
+++ b/include/llvm/Transforms/Utils/FunctionUtils.h
@@ -0,0 +1,41 @@
+//===-- Transform/Utils/FunctionUtils.h - Function Utils --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of transformations manipulate LLVM functions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_FUNCTION_H
+#define LLVM_TRANSFORMS_UTILS_FUNCTION_H
+
+#include <llvm/Analysis/Dominators.h>
+#include <vector>
+
+namespace llvm {
+ class BasicBlock;
+ class Function;
+ class Loop;
+
+ /// ExtractCodeRegion - rip out a sequence of basic blocks into a new function
+ ///
+ Function* ExtractCodeRegion(DominatorTree& DT,
+ const std::vector<BasicBlock*> &code,
+ bool AggregateArgs = false);
+
+ /// ExtractLoop - rip out a natural loop into a new function
+ ///
+ Function* ExtractLoop(DominatorTree& DT, Loop *L,
+ bool AggregateArgs = false);
+
+ /// ExtractBasicBlock - rip out a basic block into a new function
+ ///
+ Function* ExtractBasicBlock(BasicBlock *BB, bool AggregateArgs = false);
+}
+
+#endif
diff --git a/include/llvm/Transforms/Utils/Local.h b/include/llvm/Transforms/Utils/Local.h
new file mode 100644
index 0000000..c2b95db
--- /dev/null
+++ b/include/llvm/Transforms/Utils/Local.h
@@ -0,0 +1,90 @@
+//===-- Local.h - Functions to perform local transformations ----*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions perform various local transformations to the
+// program.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_LOCAL_H
+#define LLVM_TRANSFORMS_UTILS_LOCAL_H
+
+#include "llvm/Function.h"
+
+namespace llvm {
+
+class Pass;
+class PHINode;
+class AllocaInst;
+class ConstantExpr;
+class TargetData;
+
+//===----------------------------------------------------------------------===//
+// Local constant propagation...
+//
+
+/// doConstantPropagation - Constant prop a specific instruction. Returns true
+/// and potentially moves the iterator if constant propagation was performed.
+///
+bool doConstantPropagation(BasicBlock::iterator &I, const TargetData *TD = 0);
+
+/// ConstantFoldTerminator - If a terminator instruction is predicated on a
+/// constant value, convert it into an unconditional branch to the constant
+/// destination. This is a nontrivial operation because the successors of this
+/// basic block must have their PHI nodes updated.
+///
+bool ConstantFoldTerminator(BasicBlock *BB);
+
+//===----------------------------------------------------------------------===//
+// Local dead code elimination...
+//
+
+/// isInstructionTriviallyDead - Return true if the result produced by the
+/// instruction is not used, and the instruction has no side effects.
+///
+bool isInstructionTriviallyDead(Instruction *I);
+
+
+/// dceInstruction - Inspect the instruction at *BBI and figure out if it
+/// isTriviallyDead. If so, remove the instruction and update the iterator to
+/// point to the instruction that immediately succeeded the original
+/// instruction.
+///
+bool dceInstruction(BasicBlock::iterator &BBI);
+
+//===----------------------------------------------------------------------===//
+// Control Flow Graph Restructuring...
+//
+
+/// SimplifyCFG - This function is used to do simplification of a CFG. For
+/// example, it adjusts branches to branches to eliminate the extra hop, it
+/// eliminates unreachable basic blocks, and does other "peephole" optimization
+/// of the CFG. It returns true if a modification was made, possibly deleting
+/// the basic block that was pointed to.
+///
+/// WARNING: The entry node of a method may not be simplified.
+///
+bool SimplifyCFG(BasicBlock *BB);
+
+/// DemoteRegToStack - This function takes a virtual register computed by an
+/// Instruction and replaces it with a slot in the stack frame, allocated via
+/// alloca. This allows the CFG to be changed around without fear of
+/// invalidating the SSA information for the value. It returns the pointer to
+/// the alloca inserted to create a stack slot for X.
+///
+AllocaInst *DemoteRegToStack(Instruction &X, bool VolatileLoads = false);
+
+/// DemotePHIToStack - This function takes a virtual register computed by a phi
+/// node and replaces it with a slot in the stack frame, allocated via alloca.
+/// The phi node is deleted and it returns the pointer to the alloca inserted.
+AllocaInst *DemotePHIToStack(PHINode *P);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/PromoteMemToReg.h b/include/llvm/Transforms/Utils/PromoteMemToReg.h
new file mode 100644
index 0000000..4e8bfeb
--- /dev/null
+++ b/include/llvm/Transforms/Utils/PromoteMemToReg.h
@@ -0,0 +1,46 @@
+//===- PromoteMemToReg.h - Promote Allocas to Scalars -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file exposes an interface to promote alloca instructions to SSA
+// registers, by using the SSA construction algorithm.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+#define TRANSFORMS_UTILS_PROMOTEMEMTOREG_H
+
+#include <vector>
+
+namespace llvm {
+
+class AllocaInst;
+class DominatorTree;
+class DominanceFrontier;
+class AliasSetTracker;
+
+/// isAllocaPromotable - Return true if this alloca is legal for promotion.
+/// This is true if there are only loads and stores to the alloca...
+///
+bool isAllocaPromotable(const AllocaInst *AI);
+
+/// PromoteMemToReg - Promote the specified list of alloca instructions into
+/// scalar registers, inserting PHI nodes as appropriate. This function makes
+/// use of DominanceFrontier information. This function does not modify the CFG
+/// of the function at all. All allocas must be from the same function.
+///
+/// If AST is specified, the specified tracker is updated to reflect changes
+/// made to the IR.
+///
+void PromoteMemToReg(const std::vector<AllocaInst*> &Allocas,
+ DominatorTree &DT, DominanceFrontier &DF,
+ AliasSetTracker *AST = 0);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
new file mode 100644
index 0000000..1898c30
--- /dev/null
+++ b/include/llvm/Transforms/Utils/UnifyFunctionExitNodes.h
@@ -0,0 +1,55 @@
+//===-- UnifyFunctionExitNodes.h - Ensure fn's have one return --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to ensure that functions have at most one return and one
+// unwind instruction in them. Additionally, it keeps track of which node is
+// the new exit node of the CFG. If there are no return or unwind instructions
+// in the function, the getReturnBlock/getUnwindBlock methods will return a null
+// pointer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+#define LLVM_TRANSFORMS_UNIFYFUNCTIONEXITNODES_H
+
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+struct UnifyFunctionExitNodes : public FunctionPass {
+ BasicBlock *ReturnBlock, *UnwindBlock, *UnreachableBlock;
+public:
+ static char ID; // Pass identification, replacement for typeid
+ UnifyFunctionExitNodes() : FunctionPass((intptr_t)&ID),
+ ReturnBlock(0), UnwindBlock(0) {}
+
+ // We can preserve non-critical-edgeness when we unify function exit nodes
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ // getReturn|Unwind|UnreachableBlock - Return the new single (or nonexistant)
+ // return, unwind, or unreachable basic blocks in the CFG.
+ //
+ BasicBlock *getReturnBlock() const { return ReturnBlock; }
+ BasicBlock *getUnwindBlock() const { return UnwindBlock; }
+ BasicBlock *getUnreachableBlock() const { return UnreachableBlock; }
+
+ virtual bool runOnFunction(Function &F);
+
+ // Force linking the impl of this class into anything that uses this header.
+ static int stub;
+};
+
+Pass *createUnifyFunctionExitNodesPass();
+
+static IncludeFile
+UNIFY_FUNCTION_EXIT_NODES_INCLUDE_FILE(&UnifyFunctionExitNodes::stub);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Type.h b/include/llvm/Type.h
new file mode 100644
index 0000000..cf1c64f
--- /dev/null
+++ b/include/llvm/Type.h
@@ -0,0 +1,403 @@
+//===-- llvm/Type.h - Classes for handling data types -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+
+#ifndef LLVM_TYPE_H
+#define LLVM_TYPE_H
+
+#include "llvm/AbstractTypeUser.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/GraphTraits.h"
+#include "llvm/ADT/iterator"
+#include <string>
+#include <vector>
+
+namespace llvm {
+
+class DerivedType;
+class PointerType;
+class IntegerType;
+class TypeMapBase;
+
+/// This file contains the declaration of the Type class. For more "Type" type
+/// stuff, look in DerivedTypes.h.
+///
+/// The instances of the Type class are immutable: once they are created,
+/// they are never changed. Also note that only one instance of a particular
+/// type is ever created. Thus seeing if two types are equal is a matter of
+/// doing a trivial pointer comparison. To enforce that no two equal instances
+/// are created, Type instances can only be created via static factory methods
+/// in class Type and in derived classes.
+///
+/// Once allocated, Types are never free'd, unless they are an abstract type
+/// that is resolved to a more concrete type.
+///
+/// Types themself don't have a name, and can be named either by:
+/// - using SymbolTable instance, typically from some Module,
+/// - using convenience methods in the Module class (which uses module's
+/// SymbolTable too).
+///
+/// Opaque types are simple derived types with no state. There may be many
+/// different Opaque type objects floating around, but two are only considered
+/// identical if they are pointer equals of each other. This allows us to have
+/// two opaque types that end up resolving to different concrete types later.
+///
+/// Opaque types are also kinda weird and scary and different because they have
+/// to keep a list of uses of the type. When, through linking, parsing, or
+/// bitcode reading, they become resolved, they need to find and update all
+/// users of the unknown type, causing them to reference a new, more concrete
+/// type. Opaque types are deleted when their use list dwindles to zero users.
+///
+/// @brief Root of type hierarchy
+class Type : public AbstractTypeUser {
+public:
+ //===-------------------------------------------------------------------===//
+ /// Definitions of all of the base types for the Type system. Based on this
+ /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
+ /// Note: If you add an element to this, you need to add an element to the
+ /// Type::getPrimitiveType function, or else things will break!
+ ///
+ enum TypeID {
+ // PrimitiveTypes .. make sure LastPrimitiveTyID stays up to date
+ VoidTyID = 0, ///< 0: type with no size
+ FloatTyID, ///< 1: 32 bit floating point type
+ DoubleTyID, ///< 2: 64 bit floating point type
+ LabelTyID, ///< 3: Labels
+
+ // Derived types... see DerivedTypes.h file...
+ // Make sure FirstDerivedTyID stays up to date!!!
+ IntegerTyID, ///< 4: Arbitrary bit width integers
+ FunctionTyID, ///< 5: Functions
+ StructTyID, ///< 6: Structures
+ PackedStructTyID,///< 7: Packed Structure. This is for bitcode only
+ ArrayTyID, ///< 8: Arrays
+ PointerTyID, ///< 9: Pointers
+ OpaqueTyID, ///< 10: Opaque: type with unknown structure
+ VectorTyID, ///< 11: SIMD 'packed' format, or other vector type
+
+ NumTypeIDs, // Must remain as last defined ID
+ LastPrimitiveTyID = LabelTyID,
+ FirstDerivedTyID = IntegerTyID
+ };
+
+private:
+ TypeID ID : 8; // The current base type of this type.
+ bool Abstract : 1; // True if type contains an OpaqueType
+ unsigned SubclassData : 23; //Space for subclasses to store data
+
+ /// RefCount - This counts the number of PATypeHolders that are pointing to
+ /// this type. When this number falls to zero, if the type is abstract and
+ /// has no AbstractTypeUsers, the type is deleted. This is only sensical for
+ /// derived types.
+ ///
+ mutable unsigned RefCount;
+
+ const Type *getForwardedTypeInternal() const;
+
+ // Some Type instances are allocated as arrays, some aren't. So we provide
+ // this method to get the right kind of destruction for the type of Type.
+ void destroy() const; // const is a lie, this does "delete this"!
+
+protected:
+ explicit Type(TypeID id) : ID(id), Abstract(false), SubclassData(0),
+ RefCount(0), ForwardType(0), NumContainedTys(0),
+ ContainedTys(0) {}
+ virtual ~Type() {
+ assert(AbstractTypeUsers.empty() && "Abstract types remain");
+ }
+
+ /// Types can become nonabstract later, if they are refined.
+ ///
+ inline void setAbstract(bool Val) { Abstract = Val; }
+
+ unsigned getRefCount() const { return RefCount; }
+
+ unsigned getSubclassData() const { return SubclassData; }
+ void setSubclassData(unsigned val) { SubclassData = val; }
+
+ /// ForwardType - This field is used to implement the union find scheme for
+ /// abstract types. When types are refined to other types, this field is set
+ /// to the more refined type. Only abstract types can be forwarded.
+ mutable const Type *ForwardType;
+
+
+ /// AbstractTypeUsers - Implement a list of the users that need to be notified
+ /// if I am a type, and I get resolved into a more concrete type.
+ ///
+ mutable std::vector<AbstractTypeUser *> AbstractTypeUsers;
+
+ /// NumContainedTys - Keeps track of how many PATypeHandle instances there
+ /// are at the end of this type instance for the list of contained types. It
+ /// is the subclasses responsibility to set this up. Set to 0 if there are no
+ /// contained types in this type.
+ unsigned NumContainedTys;
+
+ /// ContainedTys - A pointer to the array of Types (PATypeHandle) contained
+ /// by this Type. For example, this includes the arguments of a function
+ /// type, the elements of a structure, the pointee of a pointer, the element
+ /// type of an array, etc. This pointer may be 0 for types that don't
+ /// contain other types (Integer, Double, Float). In general, the subclass
+ /// should arrange for space for the PATypeHandles to be included in the
+ /// allocation of the type object and set this pointer to the address of the
+ /// first element. This allows the Type class to manipulate the ContainedTys
+ /// without understanding the subclass's placement for this array. keeping
+ /// it here also allows the subtype_* members to be implemented MUCH more
+ /// efficiently, and dynamically very few types do not contain any elements.
+ PATypeHandle *ContainedTys;
+
+public:
+ void print(std::ostream &O) const;
+ void print(std::ostream *O) const { if (O) print(*O); }
+
+ /// @brief Debugging support: print to stderr
+ void dump() const;
+
+ //===--------------------------------------------------------------------===//
+ // Property accessors for dealing with types... Some of these virtual methods
+ // are defined in private classes defined in Type.cpp for primitive types.
+ //
+
+ /// getTypeID - Return the type id for the type. This will return one
+ /// of the TypeID enum elements defined above.
+ ///
+ inline TypeID getTypeID() const { return ID; }
+
+ /// getDescription - Return the string representation of the type...
+ const std::string &getDescription() const;
+
+ /// isInteger - True if this is an instance of IntegerType.
+ ///
+ bool isInteger() const { return ID == IntegerTyID; }
+
+ /// isFloatingPoint - Return true if this is one of the two floating point
+ /// types
+ bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
+
+ /// isFPOrFPVector - Return true if this is a FP type or a vector of FP types.
+ ///
+ bool isFPOrFPVector() const;
+
+ /// isAbstract - True if the type is either an Opaque type, or is a derived
+ /// type that includes an opaque type somewhere in it.
+ ///
+ inline bool isAbstract() const { return Abstract; }
+
+ /// canLosslesslyBitCastTo - Return true if this type could be converted
+ /// with a lossless BitCast to type 'Ty'. For example, uint to int. BitCasts
+ /// are valid for types of the same size only where no re-interpretation of
+ /// the bits is done.
+ /// @brief Determine if this type could be losslessly bitcast to Ty
+ bool canLosslesslyBitCastTo(const Type *Ty) const;
+
+
+ /// Here are some useful little methods to query what type derived types are
+ /// Note that all other types can just compare to see if this == Type::xxxTy;
+ ///
+ inline bool isPrimitiveType() const { return ID <= LastPrimitiveTyID; }
+ inline bool isDerivedType() const { return ID >= FirstDerivedTyID; }
+
+ /// isFirstClassType - Return true if the value is holdable in a register.
+ ///
+ inline bool isFirstClassType() const {
+ return (ID != VoidTyID && ID <= LastPrimitiveTyID) ||
+ ID == IntegerTyID || ID == PointerTyID || ID == VectorTyID;
+ }
+
+ /// isSized - Return true if it makes sense to take the size of this type. To
+ /// get the actual size for a particular target, it is reasonable to use the
+ /// TargetData subsystem to do this.
+ ///
+ bool isSized() const {
+ // If it's a primitive, it is always sized.
+ if (ID == IntegerTyID || isFloatingPoint() || ID == PointerTyID)
+ return true;
+ // If it is not something that can have a size (e.g. a function or label),
+ // it doesn't have a size.
+ if (ID != StructTyID && ID != ArrayTyID && ID != VectorTyID &&
+ ID != PackedStructTyID)
+ return false;
+ // If it is something that can have a size and it's concrete, it definitely
+ // has a size, otherwise we have to try harder to decide.
+ return !isAbstract() || isSizedDerivedType();
+ }
+
+ /// getPrimitiveSizeInBits - Return the basic size of this type if it is a
+ /// primitive type. These are fixed by LLVM and are not target dependent.
+ /// This will return zero if the type does not have a size or is not a
+ /// primitive type.
+ ///
+ unsigned getPrimitiveSizeInBits() const;
+
+ /// getForwaredType - Return the type that this type has been resolved to if
+ /// it has been resolved to anything. This is used to implement the
+ /// union-find algorithm for type resolution, and shouldn't be used by general
+ /// purpose clients.
+ const Type *getForwardedType() const {
+ if (!ForwardType) return 0;
+ return getForwardedTypeInternal();
+ }
+
+ /// getVAArgsPromotedType - Return the type an argument of this type
+ /// will be promoted to if passed through a variable argument
+ /// function.
+ const Type *getVAArgsPromotedType() const;
+
+ //===--------------------------------------------------------------------===//
+ // Type Iteration support
+ //
+ typedef PATypeHandle *subtype_iterator;
+ subtype_iterator subtype_begin() const { return ContainedTys; }
+ subtype_iterator subtype_end() const { return &ContainedTys[NumContainedTys];}
+
+ /// getContainedType - This method is used to implement the type iterator
+ /// (defined a the end of the file). For derived types, this returns the
+ /// types 'contained' in the derived type.
+ ///
+ const Type *getContainedType(unsigned i) const {
+ assert(i < NumContainedTys && "Index out of range!");
+ return ContainedTys[i].get();
+ }
+
+ /// getNumContainedTypes - Return the number of types in the derived type.
+ ///
+ unsigned getNumContainedTypes() const { return NumContainedTys; }
+
+ //===--------------------------------------------------------------------===//
+ // Static members exported by the Type class itself. Useful for getting
+ // instances of Type.
+ //
+
+ /// getPrimitiveType - Return a type based on an identifier.
+ static const Type *getPrimitiveType(TypeID IDNumber);
+
+ //===--------------------------------------------------------------------===//
+ // These are the builtin types that are always available...
+ //
+ static const Type *VoidTy, *LabelTy, *FloatTy, *DoubleTy;
+ static const IntegerType *Int1Ty, *Int8Ty, *Int16Ty, *Int32Ty, *Int64Ty;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Type *T) { return true; }
+
+ void addRef() const {
+ assert(isAbstract() && "Cannot add a reference to a non-abstract type!");
+ ++RefCount;
+ }
+
+ void dropRef() const {
+ assert(isAbstract() && "Cannot drop a reference to a non-abstract type!");
+ assert(RefCount && "No objects are currently referencing this object!");
+
+ // If this is the last PATypeHolder using this object, and there are no
+ // PATypeHandles using it, the type is dead, delete it now.
+ if (--RefCount == 0 && AbstractTypeUsers.empty())
+ this->destroy();
+ }
+
+ /// addAbstractTypeUser - Notify an abstract type that there is a new user of
+ /// it. This function is called primarily by the PATypeHandle class.
+ ///
+ void addAbstractTypeUser(AbstractTypeUser *U) const {
+ assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
+ AbstractTypeUsers.push_back(U);
+ }
+
+ /// removeAbstractTypeUser - Notify an abstract type that a user of the class
+ /// no longer has a handle to the type. This function is called primarily by
+ /// the PATypeHandle class. When there are no users of the abstract type, it
+ /// is annihilated, because there is no way to get a reference to it ever
+ /// again.
+ ///
+ void removeAbstractTypeUser(AbstractTypeUser *U) const;
+
+private:
+ /// isSizedDerivedType - Derived types like structures and arrays are sized
+ /// iff all of the members of the type are sized as well. Since asking for
+ /// their size is relatively uncommon, move this operation out of line.
+ bool isSizedDerivedType() const;
+
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+protected:
+ // PromoteAbstractToConcrete - This is an internal method used to calculate
+ // change "Abstract" from true to false when types are refined.
+ void PromoteAbstractToConcrete();
+ friend class TypeMapBase;
+};
+
+//===----------------------------------------------------------------------===//
+// Define some inline methods for the AbstractTypeUser.h:PATypeHandle class.
+// These are defined here because they MUST be inlined, yet are dependent on
+// the definition of the Type class.
+//
+inline void PATypeHandle::addUser() {
+ assert(Ty && "Type Handle has a null type!");
+ if (Ty->isAbstract())
+ Ty->addAbstractTypeUser(User);
+}
+inline void PATypeHandle::removeUser() {
+ if (Ty->isAbstract())
+ Ty->removeAbstractTypeUser(User);
+}
+
+// Define inline methods for PATypeHolder...
+
+inline void PATypeHolder::addRef() {
+ if (Ty->isAbstract())
+ Ty->addRef();
+}
+
+inline void PATypeHolder::dropRef() {
+ if (Ty->isAbstract())
+ Ty->dropRef();
+}
+
+
+//===----------------------------------------------------------------------===//
+// Provide specializations of GraphTraits to be able to treat a type as a
+// graph of sub types...
+
+template <> struct GraphTraits<Type*> {
+ typedef Type NodeType;
+ typedef Type::subtype_iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(Type *T) { return T; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->subtype_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->subtype_end();
+ }
+};
+
+template <> struct GraphTraits<const Type*> {
+ typedef const Type NodeType;
+ typedef Type::subtype_iterator ChildIteratorType;
+
+ static inline NodeType *getEntryNode(const Type *T) { return T; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return N->subtype_begin();
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return N->subtype_end();
+ }
+};
+
+template <> inline bool isa_impl<PointerType, Type>(const Type &Ty) {
+ return Ty.getTypeID() == Type::PointerTyID;
+}
+
+std::ostream &operator<<(std::ostream &OS, const Type &T);
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/TypeSymbolTable.h b/include/llvm/TypeSymbolTable.h
new file mode 100644
index 0000000..abe312e
--- /dev/null
+++ b/include/llvm/TypeSymbolTable.h
@@ -0,0 +1,137 @@
+//===-- llvm/TypeSymbolTable.h - Implement a Type Symtab --------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer. It is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the name/type symbol table for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TYPE_SYMBOL_TABLE_H
+#define LLVM_TYPE_SYMBOL_TABLE_H
+
+#include "llvm/Type.h"
+#include <map>
+
+namespace llvm {
+
+/// This class provides a symbol table of name/type pairs with operations to
+/// support constructing, searching and iterating over the symbol table. The
+/// class derives from AbstractTypeUser so that the contents of the symbol
+/// table can be updated when abstract types become concrete.
+class TypeSymbolTable : public AbstractTypeUser {
+
+/// @name Types
+/// @{
+public:
+
+ /// @brief A mapping of names to types.
+ typedef std::map<const std::string, const Type*> TypeMap;
+
+ /// @brief An iterator over the TypeMap.
+ typedef TypeMap::iterator iterator;
+
+ /// @brief A const_iterator over the TypeMap.
+ typedef TypeMap::const_iterator const_iterator;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+
+ TypeSymbolTable() {}
+ ~TypeSymbolTable();
+
+/// @}
+/// @name Accessors
+/// @{
+public:
+
+ /// Generates a unique name for a type based on the \p BaseName by
+ /// incrementing an integer and appending it to the name, if necessary
+ /// @returns the unique name
+ /// @brief Get a unique name for a type
+ std::string getUniqueName(const std::string &BaseName) const;
+
+ /// This method finds the type with the given \p name in the type map
+ /// and returns it.
+ /// @returns null if the name is not found, otherwise the Type
+ /// associated with the \p name.
+ /// @brief Lookup a type by name.
+ Type* lookup(const std::string& name) const;
+
+ /// @returns true iff the symbol table is empty.
+ /// @brief Determine if the symbol table is empty
+ inline bool empty() const { return tmap.empty(); }
+
+ /// @returns the size of the symbol table
+ /// @brief The number of name/type pairs is returned.
+ inline unsigned size() const { return unsigned(tmap.size()); }
+
+ /// This function can be used from the debugger to display the
+ /// content of the symbol table while debugging.
+ /// @brief Print out symbol table on stderr
+ void dump() const;
+
+/// @}
+/// @name Iteration
+/// @{
+public:
+ /// Get an iterator to the start of the symbol table
+ inline iterator begin() { return tmap.begin(); }
+
+ /// @brief Get a const_iterator to the start of the symbol table
+ inline const_iterator begin() const { return tmap.begin(); }
+
+ /// Get an iterator to the end of the symbol talbe.
+ inline iterator end() { return tmap.end(); }
+
+ /// Get a const_iterator to the end of the symbol table.
+ inline const_iterator end() const { return tmap.end(); }
+
+/// @}
+/// @name Mutators
+/// @{
+public:
+
+ /// Inserts a type into the symbol table with the specified name. There can be
+ /// a many-to-one mapping between names and types. This method allows a type
+ /// with an existing entry in the symbol table to get a new name.
+ /// @brief Insert a type under a new name.
+ void insert(const std::string &Name, const Type *Typ);
+
+ /// Remove a type at the specified position in the symbol table.
+ /// @returns the removed Type.
+ /// @returns the Type that was erased from the symbol table.
+ Type* remove(iterator TI);
+
+/// @}
+/// @name AbstractTypeUser Methods
+/// @{
+private:
+ /// This function is called when one of the types in the type plane
+ /// is refined.
+ virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
+
+ /// This function markes a type as being concrete (defined).
+ virtual void typeBecameConcrete(const DerivedType *AbsTy);
+
+/// @}
+/// @name Internal Data
+/// @{
+private:
+ TypeMap tmap; ///< This is the mapping of names to types.
+ mutable uint32_t LastUnique; ///< Counter for tracking unique names
+
+/// @}
+
+};
+
+} // End llvm namespace
+
+#endif
+
diff --git a/include/llvm/Use.h b/include/llvm/Use.h
new file mode 100644
index 0000000..c88d41f
--- /dev/null
+++ b/include/llvm/Use.h
@@ -0,0 +1,176 @@
+//===-- llvm/Use.h - Definition of the Use class ----------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines the Use class. The Use class represents the operand of an
+// instruction or some other User instance which refers to a Value. The Use
+// class keeps the "use list" of the referenced value up to date.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_USE_H
+#define LLVM_USE_H
+
+#include "llvm/Support/Casting.h"
+#include "llvm/ADT/iterator"
+
+namespace llvm {
+
+class Value;
+class User;
+
+
+//===----------------------------------------------------------------------===//
+// Use Class
+//===----------------------------------------------------------------------===//
+
+// Use is here to make keeping the "use" list of a Value up-to-date really easy.
+//
+class Use {
+public:
+ inline void init(Value *V, User *U);
+
+ Use(Value *V, User *U) { init(V, U); }
+ Use(const Use &U) { init(U.Val, U.U); }
+ inline ~Use();
+
+ /// Default ctor - This leaves the Use completely unitialized. The only thing
+ /// that is valid to do with this use is to call the "init" method.
+ inline Use() : Val(0) {}
+
+
+ operator Value*() const { return Val; }
+ Value *get() const { return Val; }
+ User *getUser() const { return U; }
+
+ inline void set(Value *Val);
+
+ Value *operator=(Value *RHS) {
+ set(RHS);
+ return RHS;
+ }
+ const Use &operator=(const Use &RHS) {
+ set(RHS.Val);
+ return *this;
+ }
+
+ Value *operator->() { return Val; }
+ const Value *operator->() const { return Val; }
+
+ Use *getNext() const { return Next; }
+private:
+ Use *Next, **Prev;
+ Value *Val;
+ User *U;
+
+ void addToList(Use **List) {
+ Next = *List;
+ if (Next) Next->Prev = &Next;
+ Prev = List;
+ *List = this;
+ }
+ void removeFromList() {
+ *Prev = Next;
+ if (Next) Next->Prev = Prev;
+ }
+
+ friend class Value;
+};
+
+// simplify_type - Allow clients to treat uses just like values when using
+// casting operators.
+template<> struct simplify_type<Use> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const Use &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+template<> struct simplify_type<const Use> {
+ typedef Value* SimpleType;
+ static SimpleType getSimplifiedValue(const Use &Val) {
+ return static_cast<SimpleType>(Val.get());
+ }
+};
+
+
+
+template<typename UserTy> // UserTy == 'User' or 'const User'
+class value_use_iterator : public forward_iterator<UserTy*, ptrdiff_t> {
+ typedef forward_iterator<UserTy*, ptrdiff_t> super;
+ typedef value_use_iterator<UserTy> _Self;
+
+ Use *U;
+ value_use_iterator(Use *u) : U(u) {}
+ friend class Value;
+public:
+ typedef typename super::reference reference;
+ typedef typename super::pointer pointer;
+
+ value_use_iterator(const _Self &I) : U(I.U) {}
+ value_use_iterator() {}
+
+ bool operator==(const _Self &x) const {
+ return U == x.U;
+ }
+ bool operator!=(const _Self &x) const {
+ return !operator==(x);
+ }
+
+ // Iterator traversal: forward iteration only
+ _Self &operator++() { // Preincrement
+ assert(U && "Cannot increment end iterator!");
+ U = U->getNext();
+ return *this;
+ }
+ _Self operator++(int) { // Postincrement
+ _Self tmp = *this; ++*this; return tmp;
+ }
+
+ // Retrieve a reference to the current SCC
+ UserTy *operator*() const {
+ assert(U && "Cannot increment end iterator!");
+ return U->getUser();
+ }
+
+ UserTy *operator->() const { return operator*(); }
+
+ Use &getUse() const { return *U; }
+
+ /// getOperandNo - Return the operand # of this use in its User. Defined in
+ /// User.h
+ ///
+ unsigned getOperandNo() const;
+};
+
+
+template<> struct simplify_type<value_use_iterator<User> > {
+ typedef User* SimpleType;
+
+ static SimpleType getSimplifiedValue(const value_use_iterator<User> &Val) {
+ return *Val;
+ }
+};
+
+template<> struct simplify_type<const value_use_iterator<User> >
+ : public simplify_type<value_use_iterator<User> > {};
+
+template<> struct simplify_type<value_use_iterator<const User> > {
+ typedef const User* SimpleType;
+
+ static SimpleType getSimplifiedValue(const
+ value_use_iterator<const User> &Val) {
+ return *Val;
+ }
+};
+
+template<> struct simplify_type<const value_use_iterator<const User> >
+ : public simplify_type<value_use_iterator<const User> > {};
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/User.h b/include/llvm/User.h
new file mode 100644
index 0000000..1ea5e18
--- /dev/null
+++ b/include/llvm/User.h
@@ -0,0 +1,122 @@
+//===-- llvm/User.h - User class definition ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines the interface that one who 'use's a Value must implement.
+// Each instance of the Value class keeps track of what User's have handles
+// to it.
+//
+// * Instructions are the largest class of User's.
+// * Constants may be users of other constants (think arrays and stuff)
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_USER_H
+#define LLVM_USER_H
+
+#include "llvm/Value.h"
+
+namespace llvm {
+
+class User : public Value {
+ User(const User &); // Do not implement
+protected:
+ /// OperandList - This is a pointer to the array of Users for this operand.
+ /// For nodes of fixed arity (e.g. a binary operator) this array will live
+ /// embedded into the derived class. For nodes of variable arity
+ /// (e.g. ConstantArrays, CallInst, PHINodes, etc), this memory will be
+ /// dynamically allocated and should be destroyed by the classes virtual dtor.
+ Use *OperandList;
+
+ /// NumOperands - The number of values used by this User.
+ ///
+ unsigned NumOperands;
+
+public:
+ User(const Type *Ty, unsigned vty, Use *OpList, unsigned NumOps)
+ : Value(Ty, vty), OperandList(OpList), NumOperands(NumOps) {}
+
+ Value *getOperand(unsigned i) const {
+ assert(i < NumOperands && "getOperand() out of range!");
+ return OperandList[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < NumOperands && "setOperand() out of range!");
+ OperandList[i] = Val;
+ }
+ unsigned getNumOperands() const { return NumOperands; }
+
+ // ---------------------------------------------------------------------------
+ // Operand Iterator interface...
+ //
+ typedef Use* op_iterator;
+ typedef const Use* const_op_iterator;
+
+ inline op_iterator op_begin() { return OperandList; }
+ inline const_op_iterator op_begin() const { return OperandList; }
+ inline op_iterator op_end() { return OperandList+NumOperands; }
+ inline const_op_iterator op_end() const { return OperandList+NumOperands; }
+
+ // dropAllReferences() - This function is in charge of "letting go" of all
+ // objects that this User refers to. This allows one to
+ // 'delete' a whole class at a time, even though there may be circular
+ // references... first all references are dropped, and all use counts go to
+ // zero. Then everything is delete'd for real. Note that no operations are
+ // valid on an object that has "dropped all references", except operator
+ // delete.
+ //
+ void dropAllReferences() {
+ Use *OL = OperandList;
+ for (unsigned i = 0, e = NumOperands; i != e; ++i)
+ OL[i].set(0);
+ }
+
+ /// replaceUsesOfWith - Replaces all references to the "From" definition with
+ /// references to the "To" definition.
+ ///
+ void replaceUsesOfWith(Value *From, Value *To);
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const User *) { return true; }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) || isa<Constant>(V);
+ }
+};
+
+template<> struct simplify_type<User::op_iterator> {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::op_iterator &Val) {
+ return static_cast<SimpleType>(Val->get());
+ }
+};
+
+template<> struct simplify_type<const User::op_iterator>
+ : public simplify_type<User::op_iterator> {};
+
+template<> struct simplify_type<User::const_op_iterator> {
+ typedef Value* SimpleType;
+
+ static SimpleType getSimplifiedValue(const User::const_op_iterator &Val) {
+ return static_cast<SimpleType>(Val->get());
+ }
+};
+
+template<> struct simplify_type<const User::const_op_iterator>
+ : public simplify_type<User::const_op_iterator> {};
+
+
+// value_use_iterator::getOperandNo - Requires the definition of the User class.
+template<typename UserTy>
+unsigned value_use_iterator<UserTy>::getOperandNo() const {
+ return U - U->getUser()->op_begin();
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/Value.h b/include/llvm/Value.h
new file mode 100644
index 0000000..44c4453
--- /dev/null
+++ b/include/llvm/Value.h
@@ -0,0 +1,262 @@
+//===-- llvm/Value.h - Definition of the Value class ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the Value class.
+// This file also defines the Use<> template for users of value.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_VALUE_H
+#define LLVM_VALUE_H
+
+#include "llvm/AbstractTypeUser.h"
+#include "llvm/Use.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Streams.h"
+#include <string>
+
+namespace llvm {
+
+class Constant;
+class Argument;
+class Instruction;
+class BasicBlock;
+class GlobalValue;
+class Function;
+class GlobalVariable;
+class GlobalAlias;
+class InlineAsm;
+class ValueSymbolTable;
+class TypeSymbolTable;
+template<typename ValueTy> class StringMapEntry;
+typedef StringMapEntry<Value*> ValueName;
+
+//===----------------------------------------------------------------------===//
+// Value Class
+//===----------------------------------------------------------------------===//
+
+/// This is a very important LLVM class. It is the base class of all values
+/// computed by a program that may be used as operands to other values. Value is
+/// the super class of other important classes such as Instruction and Function.
+/// All Values have a Type. Type is not a subclass of Value. All types can have
+/// a name and they should belong to some Module. Setting the name on the Value
+/// automatically update's the module's symbol table.
+///
+/// Every value has a "use list" that keeps track of which other Values are
+/// using this Value.
+/// @brief LLVM Value Representation
+class Value {
+ const unsigned short SubclassID; // Subclass identifier (for isa/dyn_cast)
+protected:
+ /// SubclassData - 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.
+ unsigned short SubclassData;
+private:
+ PATypeHolder Ty;
+ Use *UseList;
+
+ friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name.
+ friend class SymbolTable; // Allow SymbolTable to directly poke Name.
+ ValueName *Name;
+
+ void operator=(const Value &); // Do not implement
+ Value(const Value &); // Do not implement
+
+public:
+ Value(const Type *Ty, unsigned scid);
+ virtual ~Value();
+
+ /// dump - Support for debugging, callable in GDB: V->dump()
+ //
+ virtual void dump() const;
+
+ /// print - Implement operator<< on Value...
+ ///
+ virtual void print(std::ostream &O) const = 0;
+ void print(std::ostream *O) const { if (O) print(*O); }
+
+ /// All values are typed, get the type of this value.
+ ///
+ inline const Type *getType() const { return Ty; }
+
+ // All values can potentially be named...
+ inline bool hasName() const { return Name != 0; }
+ std::string getName() const { return getNameStr(); }
+ std::string getNameStr() const;
+ ValueName *getValueName() const { return Name; }
+
+ void setName(const std::string &name);
+ void setName(const char *Name, unsigned NameLen);
+ void setName(const char *Name); // Takes a null-terminated string.
+
+
+ /// takeName - transfer the name from V to this value, setting V's name to
+ /// empty. It is an error to call V->takeName(V).
+ void takeName(Value *V);
+
+ /// replaceAllUsesWith - Go through the uses list for this definition and make
+ /// each use point to "V" instead of "this". After this completes, 'this's
+ /// use list is guaranteed to be empty.
+ ///
+ void replaceAllUsesWith(Value *V);
+
+ // uncheckedReplaceAllUsesWith - Just like replaceAllUsesWith but dangerous.
+ // Only use when in type resolution situations!
+ void uncheckedReplaceAllUsesWith(Value *V);
+
+ //----------------------------------------------------------------------
+ // Methods for handling the vector of uses of this Value.
+ //
+ typedef value_use_iterator<User> use_iterator;
+ typedef value_use_iterator<const User> use_const_iterator;
+
+ bool use_empty() const { return UseList == 0; }
+ use_iterator use_begin() { return use_iterator(UseList); }
+ use_const_iterator use_begin() const { return use_const_iterator(UseList); }
+ use_iterator use_end() { return use_iterator(0); }
+ use_const_iterator use_end() const { return use_const_iterator(0); }
+ User *use_back() { return *use_begin(); }
+ const User *use_back() const { return *use_begin(); }
+
+ /// hasOneUse - Return true if there is exactly one user of this value. This
+ /// is specialized because it is a common request and does not require
+ /// traversing the whole use list.
+ ///
+ bool hasOneUse() const {
+ use_const_iterator I = use_begin(), E = use_end();
+ if (I == E) return false;
+ return ++I == E;
+ }
+
+ /// hasNUses - Return true if this Value has exactly N users.
+ ///
+ bool hasNUses(unsigned N) const;
+
+ /// hasNUsesOrMore - Return true if this value has N users or more. This is
+ /// logically equivalent to getNumUses() >= N.
+ ///
+ bool hasNUsesOrMore(unsigned N) const;
+
+ /// getNumUses - This method computes the number of uses of this Value. This
+ /// is a linear time operation. Use hasOneUse, hasNUses, or hasMoreThanNUses
+ /// to check for specific values.
+ unsigned getNumUses() const;
+
+ /// addUse/killUse - These two methods should only be used by the Use class.
+ ///
+ void addUse(Use &U) { U.addToList(&UseList); }
+
+ /// An enumeration for keeping track of the concrete subclass of Value that
+ /// is actually instantiated. Values of this enumeration are kept in the
+ /// Value classes SubclassID field. They are used for concrete type
+ /// identification.
+ enum ValueTy {
+ ArgumentVal, // This is an instance of Argument
+ BasicBlockVal, // This is an instance of BasicBlock
+ FunctionVal, // This is an instance of Function
+ GlobalAliasVal, // This is an instance of GlobalAlias
+ GlobalVariableVal, // This is an instance of GlobalVariable
+ UndefValueVal, // This is an instance of UndefValue
+ ConstantExprVal, // This is an instance of ConstantExpr
+ ConstantAggregateZeroVal, // This is an instance of ConstantAggregateNull
+ ConstantIntVal, // This is an instance of ConstantInt
+ ConstantFPVal, // This is an instance of ConstantFP
+ ConstantArrayVal, // This is an instance of ConstantArray
+ ConstantStructVal, // This is an instance of ConstantStruct
+ ConstantVectorVal, // This is an instance of ConstantVector
+ ConstantPointerNullVal, // This is an instance of ConstantPointerNull
+ InlineAsmVal, // This is an instance of InlineAsm
+ InstructionVal, // This is an instance of Instruction
+
+ // Markers:
+ ConstantFirstVal = FunctionVal,
+ ConstantLastVal = ConstantPointerNullVal
+ };
+
+ /// getValueID - Return an ID for the concrete type of this object. This is
+ /// used to implement the classof checks. This should not be used for any
+ /// other purpose, as the values may change as LLVM evolves. Also, note that
+ /// for instructions, the Instruction's opcode is added to InstructionVal. So
+ /// this means three things:
+ /// # there is no value with code InstructionVal (no opcode==0).
+ /// # there are more possible values for the value type than in ValueTy enum.
+ /// # the InstructionVal enumerator must be the highest valued enumerator in
+ /// the ValueTy enum.
+ unsigned getValueID() const {
+ return SubclassID;
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Value *) {
+ return true; // Values are always values.
+ }
+
+ /// getRawType - This should only be used to implement the vmcore library.
+ ///
+ const Type *getRawType() const { return Ty.getRawType(); }
+};
+
+inline std::ostream &operator<<(std::ostream &OS, const Value &V) {
+ V.print(OS);
+ return OS;
+}
+
+void Use::init(Value *v, User *user) {
+ Val = v;
+ U = user;
+ if (Val) Val->addUse(*this);
+}
+
+Use::~Use() {
+ if (Val) removeFromList();
+}
+
+void Use::set(Value *V) {
+ if (Val) removeFromList();
+ Val = V;
+ if (V) V->addUse(*this);
+}
+
+
+// isa - Provide some specializations of isa so that we don't have to include
+// the subtype header files to test to see if the value is a subclass...
+//
+template <> inline bool isa_impl<Constant, Value>(const Value &Val) {
+ return Val.getValueID() >= Value::ConstantFirstVal &&
+ Val.getValueID() <= Value::ConstantLastVal;
+}
+template <> inline bool isa_impl<Argument, Value>(const Value &Val) {
+ return Val.getValueID() == Value::ArgumentVal;
+}
+template <> inline bool isa_impl<InlineAsm, Value>(const Value &Val) {
+ return Val.getValueID() == Value::InlineAsmVal;
+}
+template <> inline bool isa_impl<Instruction, Value>(const Value &Val) {
+ return Val.getValueID() >= Value::InstructionVal;
+}
+template <> inline bool isa_impl<BasicBlock, Value>(const Value &Val) {
+ return Val.getValueID() == Value::BasicBlockVal;
+}
+template <> inline bool isa_impl<Function, Value>(const Value &Val) {
+ return Val.getValueID() == Value::FunctionVal;
+}
+template <> inline bool isa_impl<GlobalVariable, Value>(const Value &Val) {
+ return Val.getValueID() == Value::GlobalVariableVal;
+}
+template <> inline bool isa_impl<GlobalAlias, Value>(const Value &Val) {
+ return Val.getValueID() == Value::GlobalAliasVal;
+}
+template <> inline bool isa_impl<GlobalValue, Value>(const Value &Val) {
+ return isa<GlobalVariable>(Val) || isa<Function>(Val) || isa<GlobalAlias>(Val);
+}
+
+} // End llvm namespace
+
+#endif
diff --git a/include/llvm/ValueSymbolTable.h b/include/llvm/ValueSymbolTable.h
new file mode 100644
index 0000000..a695ee8
--- /dev/null
+++ b/include/llvm/ValueSymbolTable.h
@@ -0,0 +1,137 @@
+//===-- llvm/ValueSymbolTable.h - Implement a Value Symtab ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the name/Value symbol table for LLVM.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_VALUE_SYMBOL_TABLE_H
+#define LLVM_VALUE_SYMBOL_TABLE_H
+
+#include "llvm/Value.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/DataTypes.h"
+
+namespace llvm {
+ template<typename ValueSubClass, typename ItemParentClass>
+ class SymbolTableListTraits;
+ class BasicBlock;
+ class Function;
+ class Module;
+
+/// This class provides a symbol table of name/value pairs. It is essentially
+/// a std::map<std::string,Value*> but has a controlled interface provided by
+/// LLVM as well as ensuring uniqueness of names.
+///
+class ValueSymbolTable {
+ friend class Value;
+ friend class SymbolTableListTraits<Argument, Function>;
+ friend class SymbolTableListTraits<BasicBlock, Function>;
+ friend class SymbolTableListTraits<Instruction, BasicBlock>;
+ friend class SymbolTableListTraits<Function, Module>;
+ friend class SymbolTableListTraits<GlobalVariable, Module>;
+ friend class SymbolTableListTraits<GlobalAlias, Module>;
+/// @name Types
+/// @{
+public:
+ /// @brief A mapping of names to values.
+ typedef StringMap<Value*> ValueMap;
+
+ /// @brief An iterator over a ValueMap.
+ typedef ValueMap::iterator iterator;
+
+ /// @brief A const_iterator over a ValueMap.
+ typedef ValueMap::const_iterator const_iterator;
+
+/// @}
+/// @name Constructors
+/// @{
+public:
+
+ ValueSymbolTable() : vmap(0), LastUnique(0) {}
+ ~ValueSymbolTable();
+
+/// @}
+/// @name Accessors
+/// @{
+public:
+
+ /// This method finds the value with the given \p name in the
+ /// the symbol table.
+ /// @returns the value associated with the \p name
+ /// @brief Lookup a named Value.
+ Value *lookup(const std::string &name) const;
+
+ /// @returns true iff the symbol table is empty
+ /// @brief Determine if the symbol table is empty
+ inline bool empty() const { return vmap.empty(); }
+
+ /// @brief The number of name/type pairs is returned.
+ inline unsigned size() const { return unsigned(vmap.size()); }
+
+ /// Given a base name, return a string that is either equal to it or
+ /// derived from it that does not already occur in the symbol table
+ /// for the specified type.
+ /// @brief Get a name unique to this symbol table
+ std::string getUniqueName(const std::string &BaseName) const;
+
+ /// This function can be used from the debugger to display the
+ /// content of the symbol table while debugging.
+ /// @brief Print out symbol table on stderr
+ void dump() const;
+
+/// @}
+/// @name Iteration
+/// @{
+public:
+ /// @brief Get an iterator that from the beginning of the symbol table.
+ inline iterator begin() { return vmap.begin(); }
+
+ /// @brief Get a const_iterator that from the beginning of the symbol table.
+ inline const_iterator begin() const { return vmap.begin(); }
+
+ /// @brief Get an iterator to the end of the symbol table.
+ inline iterator end() { return vmap.end(); }
+
+ /// @brief Get a const_iterator to the end of the symbol table.
+ inline const_iterator end() const { return vmap.end(); }
+
+/// @}
+/// @name Mutators
+/// @{
+private:
+ /// This method adds the provided value \p N to the symbol table. The Value
+ /// must have a name which is used to place the value in the symbol table.
+ /// If the inserted name conflicts, this renames the value.
+ /// @brief Add a named value to the symbol table
+ void reinsertValue(Value *V);
+
+ /// createValueName - This method attempts to create a value name and insert
+ /// it into the symbol table with the specified name. If it conflicts, it
+ /// auto-renames the name and returns that instead.
+ ValueName *createValueName(const char *NameStart, unsigned NameLen, Value *V);
+
+ /// This method removes a value from the symbol table. It leaves the
+ /// ValueName attached to the value, but it is no longer inserted in the
+ /// symtab.
+ void removeValueName(ValueName *V);
+
+/// @}
+/// @name Internal Data
+/// @{
+private:
+ ValueMap vmap; ///< The map that holds the symbol table.
+ mutable uint32_t LastUnique; ///< Counter for tracking unique names
+
+/// @}
+};
+
+} // End llvm namespace
+
+#endif