summaryrefslogtreecommitdiff
path: root/gnu/llvm/lib
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2017-01-14 20:04:09 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2017-01-14 20:04:09 +0000
commit86d685a17b1e4f8b57c4d5bd48e0a5429f3028e3 (patch)
treedfd6da3109a33a451fb87ff4ca62c59945430ad5 /gnu/llvm/lib
parentca82c85029ae0befb17bc14a4faa9f3d51dd72b3 (diff)
Merge LLVM 3.9.1
Diffstat (limited to 'gnu/llvm/lib')
-rw-r--r--gnu/llvm/lib/Analysis/CFLAliasAnalysis.cpp1119
-rw-r--r--gnu/llvm/lib/Analysis/Makefile15
-rw-r--r--gnu/llvm/lib/AsmParser/Makefile14
-rw-r--r--gnu/llvm/lib/AsmParser/module.modulemap1
-rw-r--r--gnu/llvm/lib/Bitcode/Makefile14
-rw-r--r--gnu/llvm/lib/Bitcode/Reader/Makefile15
-rw-r--r--gnu/llvm/lib/Bitcode/Writer/Makefile15
-rw-r--r--gnu/llvm/lib/Bitcode/module.modulemap1
-rw-r--r--gnu/llvm/lib/CodeGen/AsmPrinter/Makefile13
-rw-r--r--gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp411
-rw-r--r--gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h138
-rw-r--r--gnu/llvm/lib/CodeGen/CoreCLRGC.cpp54
-rw-r--r--gnu/llvm/lib/CodeGen/ErlangGC.cpp46
-rw-r--r--gnu/llvm/lib/CodeGen/MIRParser/Makefile13
-rw-r--r--gnu/llvm/lib/CodeGen/Makefile22
-rw-r--r--gnu/llvm/lib/CodeGen/OcamlGC.cpp36
-rw-r--r--gnu/llvm/lib/CodeGen/Passes.cpp817
-rw-r--r--gnu/llvm/lib/CodeGen/SelectionDAG/Makefile13
-rw-r--r--gnu/llvm/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp19
-rw-r--r--gnu/llvm/lib/CodeGen/ShadowStackGC.cpp55
-rw-r--r--gnu/llvm/lib/CodeGen/StackProtector.cpp202
-rw-r--r--gnu/llvm/lib/CodeGen/StatepointExampleGC.cpp55
-rw-r--r--gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp235
-rw-r--r--gnu/llvm/lib/CodeGen/module.modulemap1
-rw-r--r--gnu/llvm/lib/DebugInfo/CodeView/Makefile14
-rw-r--r--gnu/llvm/lib/DebugInfo/DWARF/Makefile14
-rw-r--r--gnu/llvm/lib/DebugInfo/DWARF/module.modulemap1
-rw-r--r--gnu/llvm/lib/DebugInfo/Makefile15
-rw-r--r--gnu/llvm/lib/DebugInfo/PDB/Makefile14
-rw-r--r--gnu/llvm/lib/DebugInfo/Symbolize/Makefile15
-rw-r--r--gnu/llvm/lib/ExecutionEngine/IntelJITEvents/Makefile18
-rw-r--r--gnu/llvm/lib/ExecutionEngine/Interpreter/Makefile13
-rw-r--r--gnu/llvm/lib/ExecutionEngine/MCJIT/Makefile13
-rw-r--r--gnu/llvm/lib/ExecutionEngine/Makefile24
-rw-r--r--gnu/llvm/lib/ExecutionEngine/OProfileJIT/Makefile18
-rw-r--r--gnu/llvm/lib/ExecutionEngine/Orc/Makefile13
-rw-r--r--gnu/llvm/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp171
-rw-r--r--gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp43
-rw-r--r--gnu/llvm/lib/ExecutionEngine/RuntimeDyld/Makefile13
-rw-r--r--gnu/llvm/lib/Fuzzer/FuzzerInterface.cpp30
-rw-r--r--gnu/llvm/lib/Fuzzer/FuzzerSanitizerOptions.cpp19
-rwxr-xr-xgnu/llvm/lib/Fuzzer/pull_and_push_fuzz_corpus.sh17
-rw-r--r--gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp51
-rw-r--r--gnu/llvm/lib/IR/FunctionInfo.cpp67
-rw-r--r--gnu/llvm/lib/IR/Makefile61
-rw-r--r--gnu/llvm/lib/IR/module.modulemap1
-rw-r--r--gnu/llvm/lib/IRReader/Makefile14
-rw-r--r--gnu/llvm/lib/LTO/Makefile15
-rw-r--r--gnu/llvm/lib/LibDriver/Makefile20
-rw-r--r--gnu/llvm/lib/LineEditor/Makefile15
-rw-r--r--gnu/llvm/lib/Linker/Makefile15
-rw-r--r--gnu/llvm/lib/MC/MCCodeGenInfo.cpp23
-rw-r--r--gnu/llvm/lib/MC/MCDisassembler/Makefile14
-rw-r--r--gnu/llvm/lib/MC/MCParser/Makefile15
-rw-r--r--gnu/llvm/lib/MC/MCSymbolizer.cpp15
-rw-r--r--gnu/llvm/lib/MC/Makefile16
-rw-r--r--gnu/llvm/lib/MC/YAML.cpp65
-rw-r--r--gnu/llvm/lib/Makefile17
-rw-r--r--gnu/llvm/lib/Object/COFFYAML.cpp503
-rw-r--r--gnu/llvm/lib/Object/ELFYAML.cpp809
-rw-r--r--gnu/llvm/lib/Object/FunctionIndexObjectFile.cpp143
-rw-r--r--gnu/llvm/lib/Object/Makefile14
-rw-r--r--gnu/llvm/lib/Option/Makefile14
-rw-r--r--gnu/llvm/lib/Passes/Makefile14
-rw-r--r--gnu/llvm/lib/ProfileData/CoverageMapping.cpp522
-rw-r--r--gnu/llvm/lib/ProfileData/CoverageMappingReader.cpp547
-rw-r--r--gnu/llvm/lib/ProfileData/CoverageMappingWriter.cpp183
-rw-r--r--gnu/llvm/lib/ProfileData/Makefile14
-rw-r--r--gnu/llvm/lib/Support/Makefile23
-rw-r--r--gnu/llvm/lib/TableGen/Makefile14
-rw-r--r--gnu/llvm/lib/TableGen/module.modulemap1
-rw-r--r--gnu/llvm/lib/Target/AArch64/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AArch64/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/AArch64/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AArch64/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/AArch64/Makefile25
-rw-r--r--gnu/llvm/lib/Target/AArch64/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AArch64/Utils/Makefile16
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.cpp26
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.h48
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/Makefile23
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/R600TextureIntrinsicsReplacer.cpp303
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/SIFixSGPRLiveRanges.cpp219
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AMDGPU/Utils/Makefile16
-rw-r--r--gnu/llvm/lib/Target/ARM/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/ARM/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/ARM/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/ARM/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/ARM/Makefile24
-rw-r--r--gnu/llvm/lib/Target/ARM/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/AVR/AVRConfig.h15
-rw-r--r--gnu/llvm/lib/Target/AVR/Makefile19
-rw-r--r--gnu/llvm/lib/Target/AVR/TargetInfo/Makefile16
-rw-r--r--gnu/llvm/lib/Target/BPF/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/BPF/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/BPF/Makefile21
-rw-r--r--gnu/llvm/lib/Target/BPF/TargetInfo/Makefile16
-rw-r--r--gnu/llvm/lib/Target/CppBackend/CMakeLists.txt5
-rw-r--r--gnu/llvm/lib/Target/CppBackend/CPPBackend.cpp2143
-rw-r--r--gnu/llvm/lib/Target/CppBackend/CPPTargetMachine.h44
-rw-r--r--gnu/llvm/lib/Target/CppBackend/LLVMBuild.txt31
-rw-r--r--gnu/llvm/lib/Target/CppBackend/Makefile16
-rw-r--r--gnu/llvm/lib/Target/CppBackend/TargetInfo/CMakeLists.txt3
-rw-r--r--gnu/llvm/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp29
-rw-r--r--gnu/llvm/lib/Target/CppBackend/TargetInfo/LLVMBuild.txt23
-rw-r--r--gnu/llvm/lib/Target/CppBackend/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Hexagon/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Hexagon/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp357
-rw-r--r--gnu/llvm/lib/Target/Hexagon/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Hexagon/Makefile26
-rw-r--r--gnu/llvm/lib/Target/Hexagon/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/MSP430/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/MSP430/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/MSP430/Makefile23
-rw-r--r--gnu/llvm/lib/Target/MSP430/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Makefile20
-rw-r--r--gnu/llvm/lib/Target/Mips/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Mips/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Mips/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Mips/MCTargetDesc/Makefile17
-rw-r--r--gnu/llvm/lib/Target/Mips/Makefile25
-rw-r--r--gnu/llvm/lib/Target/Mips/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/NVPTX/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/NVPTX/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/NVPTX/Makefile23
-rw-r--r--gnu/llvm/lib/Target/NVPTX/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/PowerPC/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/PowerPC/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/PowerPC/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/PowerPC/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/PowerPC/Makefile24
-rw-r--r--gnu/llvm/lib/Target/PowerPC/PPCLoopDataPrefetch.cpp233
-rw-r--r--gnu/llvm/lib/Target/PowerPC/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Sparc/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/Sparc/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Sparc/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Sparc/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/Sparc/Makefile24
-rw-r--r--gnu/llvm/lib/Target/Sparc/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/SystemZ/AsmParser/Makefile16
-rw-r--r--gnu/llvm/lib/Target/SystemZ/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/SystemZ/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/SystemZ/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/SystemZ/Makefile28
-rw-r--r--gnu/llvm/lib/Target/SystemZ/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/Makefile26
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/Relooper.cpp984
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/Relooper.h186
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/TargetInfo/Makefile15
-rw-r--r--gnu/llvm/lib/Target/WebAssembly/WebAssemblyPEI.cpp1066
-rw-r--r--gnu/llvm/lib/Target/X86/AsmParser/Makefile15
-rw-r--r--gnu/llvm/lib/Target/X86/Disassembler/Makefile18
-rw-r--r--gnu/llvm/lib/Target/X86/Disassembler/X86Disassembler.h112
-rw-r--r--gnu/llvm/lib/Target/X86/InstPrinter/Makefile15
-rw-r--r--gnu/llvm/lib/Target/X86/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp141
-rw-r--r--gnu/llvm/lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp119
-rw-r--r--gnu/llvm/lib/Target/X86/Makefile23
-rw-r--r--gnu/llvm/lib/Target/X86/TargetInfo/Makefile16
-rw-r--r--gnu/llvm/lib/Target/X86/Utils/Makefile15
-rw-r--r--gnu/llvm/lib/Target/XCore/Disassembler/Makefile16
-rw-r--r--gnu/llvm/lib/Target/XCore/InstPrinter/Makefile16
-rw-r--r--gnu/llvm/lib/Target/XCore/MCTargetDesc/Makefile16
-rw-r--r--gnu/llvm/lib/Target/XCore/Makefile23
-rw-r--r--gnu/llvm/lib/Target/XCore/TargetInfo/Makefile16
-rw-r--r--gnu/llvm/lib/Transforms/Hello/Makefile24
-rw-r--r--gnu/llvm/lib/Transforms/IPO/LowerBitSets.cpp1055
-rw-r--r--gnu/llvm/lib/Transforms/IPO/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/InstCombine/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/Instrumentation/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/Instrumentation/SafeStack.cpp760
-rw-r--r--gnu/llvm/lib/Transforms/Makefile20
-rw-r--r--gnu/llvm/lib/Transforms/ObjCARC/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/Scalar/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp2630
-rw-r--r--gnu/llvm/lib/Transforms/Utils/Makefile15
-rw-r--r--gnu/llvm/lib/Transforms/Vectorize/Makefile15
185 files changed, 270 insertions, 18834 deletions
diff --git a/gnu/llvm/lib/Analysis/CFLAliasAnalysis.cpp b/gnu/llvm/lib/Analysis/CFLAliasAnalysis.cpp
deleted file mode 100644
index 4843ed6587a..00000000000
--- a/gnu/llvm/lib/Analysis/CFLAliasAnalysis.cpp
+++ /dev/null
@@ -1,1119 +0,0 @@
-//===- CFLAliasAnalysis.cpp - CFL-Based Alias Analysis Implementation ------==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a CFL-based context-insensitive alias analysis
-// algorithm. It does not depend on types. The algorithm is a mixture of the one
-// described in "Demand-driven alias analysis for C" by Xin Zheng and Radu
-// Rugina, and "Fast algorithms for Dyck-CFL-reachability with applications to
-// Alias Analysis" by Zhang Q, Lyu M R, Yuan H, and Su Z. -- to summarize the
-// papers, we build a graph of the uses of a variable, where each node is a
-// memory location, and each edge is an action that happened on that memory
-// location. The "actions" can be one of Dereference, Reference, or Assign.
-//
-// Two variables are considered as aliasing iff you can reach one value's node
-// from the other value's node and the language formed by concatenating all of
-// the edge labels (actions) conforms to a context-free grammar.
-//
-// Because this algorithm requires a graph search on each query, we execute the
-// algorithm outlined in "Fast algorithms..." (mentioned above)
-// in order to transform the graph into sets of variables that may alias in
-// ~nlogn time (n = number of variables.), which makes queries take constant
-// time.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/CFLAliasAnalysis.h"
-#include "StratifiedSets.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstVisitor.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <memory>
-#include <tuple>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "cfl-aa"
-
-CFLAAResult::CFLAAResult(const TargetLibraryInfo &TLI) : AAResultBase(TLI) {}
-CFLAAResult::CFLAAResult(CFLAAResult &&Arg) : AAResultBase(std::move(Arg)) {}
-
-// \brief Information we have about a function and would like to keep around
-struct CFLAAResult::FunctionInfo {
- StratifiedSets<Value *> Sets;
- // Lots of functions have < 4 returns. Adjust as necessary.
- SmallVector<Value *, 4> ReturnedValues;
-
- FunctionInfo(StratifiedSets<Value *> &&S, SmallVector<Value *, 4> &&RV)
- : Sets(std::move(S)), ReturnedValues(std::move(RV)) {}
-};
-
-// Try to go from a Value* to a Function*. Never returns nullptr.
-static Optional<Function *> parentFunctionOfValue(Value *);
-
-// Returns possible functions called by the Inst* into the given
-// SmallVectorImpl. Returns true if targets found, false otherwise.
-// This is templated because InvokeInst/CallInst give us the same
-// set of functions that we care about, and I don't like repeating
-// myself.
-template <typename Inst>
-static bool getPossibleTargets(Inst *, SmallVectorImpl<Function *> &);
-
-// Some instructions need to have their users tracked. Instructions like
-// `add` require you to get the users of the Instruction* itself, other
-// instructions like `store` require you to get the users of the first
-// operand. This function gets the "proper" value to track for each
-// type of instruction we support.
-static Optional<Value *> getTargetValue(Instruction *);
-
-// There are certain instructions (i.e. FenceInst, etc.) that we ignore.
-// This notes that we should ignore those.
-static bool hasUsefulEdges(Instruction *);
-
-const StratifiedIndex StratifiedLink::SetSentinel =
- std::numeric_limits<StratifiedIndex>::max();
-
-namespace {
-// StratifiedInfo Attribute things.
-typedef unsigned StratifiedAttr;
-LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
-LLVM_CONSTEXPR unsigned AttrAllIndex = 0;
-LLVM_CONSTEXPR unsigned AttrGlobalIndex = 1;
-LLVM_CONSTEXPR unsigned AttrUnknownIndex = 2;
-LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 3;
-LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex;
-LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
-
-LLVM_CONSTEXPR StratifiedAttr AttrNone = 0;
-LLVM_CONSTEXPR StratifiedAttr AttrUnknown = 1 << AttrUnknownIndex;
-LLVM_CONSTEXPR StratifiedAttr AttrAll = ~AttrNone;
-
-// \brief StratifiedSets call for knowledge of "direction", so this is how we
-// represent that locally.
-enum class Level { Same, Above, Below };
-
-// \brief Edges can be one of four "weights" -- each weight must have an inverse
-// weight (Assign has Assign; Reference has Dereference).
-enum class EdgeType {
- // The weight assigned when assigning from or to a value. For example, in:
- // %b = getelementptr %a, 0
- // ...The relationships are %b assign %a, and %a assign %b. This used to be
- // two edges, but having a distinction bought us nothing.
- Assign,
-
- // The edge used when we have an edge going from some handle to a Value.
- // Examples of this include:
- // %b = load %a (%b Dereference %a)
- // %b = extractelement %a, 0 (%a Dereference %b)
- Dereference,
-
- // The edge used when our edge goes from a value to a handle that may have
- // contained it at some point. Examples:
- // %b = load %a (%a Reference %b)
- // %b = extractelement %a, 0 (%b Reference %a)
- Reference
-};
-
-// \brief Encodes the notion of a "use"
-struct Edge {
- // \brief Which value the edge is coming from
- Value *From;
-
- // \brief Which value the edge is pointing to
- Value *To;
-
- // \brief Edge weight
- EdgeType Weight;
-
- // \brief Whether we aliased any external values along the way that may be
- // invisible to the analysis (i.e. landingpad for exceptions, calls for
- // interprocedural analysis, etc.)
- StratifiedAttrs AdditionalAttrs;
-
- Edge(Value *From, Value *To, EdgeType W, StratifiedAttrs A)
- : From(From), To(To), Weight(W), AdditionalAttrs(A) {}
-};
-
-// \brief Gets the edges our graph should have, based on an Instruction*
-class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
- CFLAAResult &AA;
- SmallVectorImpl<Edge> &Output;
-
-public:
- GetEdgesVisitor(CFLAAResult &AA, SmallVectorImpl<Edge> &Output)
- : AA(AA), Output(Output) {}
-
- void visitInstruction(Instruction &) {
- llvm_unreachable("Unsupported instruction encountered");
- }
-
- void visitPtrToIntInst(PtrToIntInst &Inst) {
- auto *Ptr = Inst.getOperand(0);
- Output.push_back(Edge(Ptr, Ptr, EdgeType::Assign, AttrUnknown));
- }
-
- void visitIntToPtrInst(IntToPtrInst &Inst) {
- auto *Ptr = &Inst;
- Output.push_back(Edge(Ptr, Ptr, EdgeType::Assign, AttrUnknown));
- }
-
- void visitCastInst(CastInst &Inst) {
- Output.push_back(
- Edge(&Inst, Inst.getOperand(0), EdgeType::Assign, AttrNone));
- }
-
- void visitBinaryOperator(BinaryOperator &Inst) {
- auto *Op1 = Inst.getOperand(0);
- auto *Op2 = Inst.getOperand(1);
- Output.push_back(Edge(&Inst, Op1, EdgeType::Assign, AttrNone));
- Output.push_back(Edge(&Inst, Op2, EdgeType::Assign, AttrNone));
- }
-
- void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
- auto *Ptr = Inst.getPointerOperand();
- auto *Val = Inst.getNewValOperand();
- Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
- }
-
- void visitAtomicRMWInst(AtomicRMWInst &Inst) {
- auto *Ptr = Inst.getPointerOperand();
- auto *Val = Inst.getValOperand();
- Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
- }
-
- void visitPHINode(PHINode &Inst) {
- for (Value *Val : Inst.incoming_values()) {
- Output.push_back(Edge(&Inst, Val, EdgeType::Assign, AttrNone));
- }
- }
-
- void visitGetElementPtrInst(GetElementPtrInst &Inst) {
- auto *Op = Inst.getPointerOperand();
- Output.push_back(Edge(&Inst, Op, EdgeType::Assign, AttrNone));
- for (auto I = Inst.idx_begin(), E = Inst.idx_end(); I != E; ++I)
- Output.push_back(Edge(&Inst, *I, EdgeType::Assign, AttrNone));
- }
-
- void visitSelectInst(SelectInst &Inst) {
- // Condition is not processed here (The actual statement producing
- // the condition result is processed elsewhere). For select, the
- // condition is evaluated, but not loaded, stored, or assigned
- // simply as a result of being the condition of a select.
-
- auto *TrueVal = Inst.getTrueValue();
- Output.push_back(Edge(&Inst, TrueVal, EdgeType::Assign, AttrNone));
- auto *FalseVal = Inst.getFalseValue();
- Output.push_back(Edge(&Inst, FalseVal, EdgeType::Assign, AttrNone));
- }
-
- void visitAllocaInst(AllocaInst &) {}
-
- void visitLoadInst(LoadInst &Inst) {
- auto *Ptr = Inst.getPointerOperand();
- auto *Val = &Inst;
- Output.push_back(Edge(Val, Ptr, EdgeType::Reference, AttrNone));
- }
-
- void visitStoreInst(StoreInst &Inst) {
- auto *Ptr = Inst.getPointerOperand();
- auto *Val = Inst.getValueOperand();
- Output.push_back(Edge(Ptr, Val, EdgeType::Dereference, AttrNone));
- }
-
- void visitVAArgInst(VAArgInst &Inst) {
- // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does
- // two things:
- // 1. Loads a value from *((T*)*Ptr).
- // 2. Increments (stores to) *Ptr by some target-specific amount.
- // For now, we'll handle this like a landingpad instruction (by placing the
- // result in its own group, and having that group alias externals).
- auto *Val = &Inst;
- Output.push_back(Edge(Val, Val, EdgeType::Assign, AttrAll));
- }
-
- static bool isFunctionExternal(Function *Fn) {
- return Fn->isDeclaration() || !Fn->hasLocalLinkage();
- }
-
- // Gets whether the sets at Index1 above, below, or equal to the sets at
- // Index2. Returns None if they are not in the same set chain.
- static Optional<Level> getIndexRelation(const StratifiedSets<Value *> &Sets,
- StratifiedIndex Index1,
- StratifiedIndex Index2) {
- if (Index1 == Index2)
- return Level::Same;
-
- const auto *Current = &Sets.getLink(Index1);
- while (Current->hasBelow()) {
- if (Current->Below == Index2)
- return Level::Below;
- Current = &Sets.getLink(Current->Below);
- }
-
- Current = &Sets.getLink(Index1);
- while (Current->hasAbove()) {
- if (Current->Above == Index2)
- return Level::Above;
- Current = &Sets.getLink(Current->Above);
- }
-
- return NoneType();
- }
-
- bool
- tryInterproceduralAnalysis(const SmallVectorImpl<Function *> &Fns,
- Value *FuncValue,
- const iterator_range<User::op_iterator> &Args) {
- const unsigned ExpectedMaxArgs = 8;
- const unsigned MaxSupportedArgs = 50;
- assert(Fns.size() > 0);
-
- // I put this here to give us an upper bound on time taken by IPA. Is it
- // really (realistically) needed? Keep in mind that we do have an n^2 algo.
- if (std::distance(Args.begin(), Args.end()) > (int)MaxSupportedArgs)
- return false;
-
- // Exit early if we'll fail anyway
- for (auto *Fn : Fns) {
- if (isFunctionExternal(Fn) || Fn->isVarArg())
- return false;
- auto &MaybeInfo = AA.ensureCached(Fn);
- if (!MaybeInfo.hasValue())
- return false;
- }
-
- SmallVector<Value *, ExpectedMaxArgs> Arguments(Args.begin(), Args.end());
- SmallVector<StratifiedInfo, ExpectedMaxArgs> Parameters;
- for (auto *Fn : Fns) {
- auto &Info = *AA.ensureCached(Fn);
- auto &Sets = Info.Sets;
- auto &RetVals = Info.ReturnedValues;
-
- Parameters.clear();
- for (auto &Param : Fn->args()) {
- auto MaybeInfo = Sets.find(&Param);
- // Did a new parameter somehow get added to the function/slip by?
- if (!MaybeInfo.hasValue())
- return false;
- Parameters.push_back(*MaybeInfo);
- }
-
- // Adding an edge from argument -> return value for each parameter that
- // may alias the return value
- for (unsigned I = 0, E = Parameters.size(); I != E; ++I) {
- auto &ParamInfo = Parameters[I];
- auto &ArgVal = Arguments[I];
- bool AddEdge = false;
- StratifiedAttrs Externals;
- for (unsigned X = 0, XE = RetVals.size(); X != XE; ++X) {
- auto MaybeInfo = Sets.find(RetVals[X]);
- if (!MaybeInfo.hasValue())
- return false;
-
- auto &RetInfo = *MaybeInfo;
- auto RetAttrs = Sets.getLink(RetInfo.Index).Attrs;
- auto ParamAttrs = Sets.getLink(ParamInfo.Index).Attrs;
- auto MaybeRelation =
- getIndexRelation(Sets, ParamInfo.Index, RetInfo.Index);
- if (MaybeRelation.hasValue()) {
- AddEdge = true;
- Externals |= RetAttrs | ParamAttrs;
- }
- }
- if (AddEdge)
- Output.push_back(Edge(FuncValue, ArgVal, EdgeType::Assign,
- StratifiedAttrs().flip()));
- }
-
- if (Parameters.size() != Arguments.size())
- return false;
-
- // Adding edges between arguments for arguments that may end up aliasing
- // each other. This is necessary for functions such as
- // void foo(int** a, int** b) { *a = *b; }
- // (Technically, the proper sets for this would be those below
- // Arguments[I] and Arguments[X], but our algorithm will produce
- // extremely similar, and equally correct, results either way)
- for (unsigned I = 0, E = Arguments.size(); I != E; ++I) {
- auto &MainVal = Arguments[I];
- auto &MainInfo = Parameters[I];
- auto &MainAttrs = Sets.getLink(MainInfo.Index).Attrs;
- for (unsigned X = I + 1; X != E; ++X) {
- auto &SubInfo = Parameters[X];
- auto &SubVal = Arguments[X];
- auto &SubAttrs = Sets.getLink(SubInfo.Index).Attrs;
- auto MaybeRelation =
- getIndexRelation(Sets, MainInfo.Index, SubInfo.Index);
-
- if (!MaybeRelation.hasValue())
- continue;
-
- auto NewAttrs = SubAttrs | MainAttrs;
- Output.push_back(Edge(MainVal, SubVal, EdgeType::Assign, NewAttrs));
- }
- }
- }
- return true;
- }
-
- template <typename InstT> void visitCallLikeInst(InstT &Inst) {
- // TODO: Add support for noalias args/all the other fun function attributes
- // that we can tack on.
- SmallVector<Function *, 4> Targets;
- if (getPossibleTargets(&Inst, Targets)) {
- if (tryInterproceduralAnalysis(Targets, &Inst, Inst.arg_operands()))
- return;
- // Cleanup from interprocedural analysis
- Output.clear();
- }
-
- // Because the function is opaque, we need to note that anything
- // could have happened to the arguments, and that the result could alias
- // just about anything, too.
- // The goal of the loop is in part to unify many Values into one set, so we
- // don't care if the function is void there.
- for (Value *V : Inst.arg_operands())
- Output.push_back(Edge(&Inst, V, EdgeType::Assign, AttrAll));
- if (Inst.getNumArgOperands() == 0 &&
- Inst.getType() != Type::getVoidTy(Inst.getContext()))
- Output.push_back(Edge(&Inst, &Inst, EdgeType::Assign, AttrAll));
- }
-
- void visitCallInst(CallInst &Inst) { visitCallLikeInst(Inst); }
-
- void visitInvokeInst(InvokeInst &Inst) { visitCallLikeInst(Inst); }
-
- // Because vectors/aggregates are immutable and unaddressable,
- // there's nothing we can do to coax a value out of them, other
- // than calling Extract{Element,Value}. We can effectively treat
- // them as pointers to arbitrary memory locations we can store in
- // and load from.
- void visitExtractElementInst(ExtractElementInst &Inst) {
- auto *Ptr = Inst.getVectorOperand();
- auto *Val = &Inst;
- Output.push_back(Edge(Val, Ptr, EdgeType::Reference, AttrNone));
- }
-
- void visitInsertElementInst(InsertElementInst &Inst) {
- auto *Vec = Inst.getOperand(0);
- auto *Val = Inst.getOperand(1);
- Output.push_back(Edge(&Inst, Vec, EdgeType::Assign, AttrNone));
- Output.push_back(Edge(&Inst, Val, EdgeType::Dereference, AttrNone));
- }
-
- void visitLandingPadInst(LandingPadInst &Inst) {
- // Exceptions come from "nowhere", from our analysis' perspective.
- // So we place the instruction its own group, noting that said group may
- // alias externals
- Output.push_back(Edge(&Inst, &Inst, EdgeType::Assign, AttrAll));
- }
-
- void visitInsertValueInst(InsertValueInst &Inst) {
- auto *Agg = Inst.getOperand(0);
- auto *Val = Inst.getOperand(1);
- Output.push_back(Edge(&Inst, Agg, EdgeType::Assign, AttrNone));
- Output.push_back(Edge(&Inst, Val, EdgeType::Dereference, AttrNone));
- }
-
- void visitExtractValueInst(ExtractValueInst &Inst) {
- auto *Ptr = Inst.getAggregateOperand();
- Output.push_back(Edge(&Inst, Ptr, EdgeType::Reference, AttrNone));
- }
-
- void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
- auto *From1 = Inst.getOperand(0);
- auto *From2 = Inst.getOperand(1);
- Output.push_back(Edge(&Inst, From1, EdgeType::Assign, AttrNone));
- Output.push_back(Edge(&Inst, From2, EdgeType::Assign, AttrNone));
- }
-
- void visitConstantExpr(ConstantExpr *CE) {
- switch (CE->getOpcode()) {
- default:
- llvm_unreachable("Unknown instruction type encountered!");
-// Build the switch statement using the Instruction.def file.
-#define HANDLE_INST(NUM, OPCODE, CLASS) \
- case Instruction::OPCODE: \
- visit##OPCODE(*(CLASS *)CE); \
- break;
-#include "llvm/IR/Instruction.def"
- }
- }
-};
-
-// For a given instruction, we need to know which Value* to get the
-// users of in order to build our graph. In some cases (i.e. add),
-// we simply need the Instruction*. In other cases (i.e. store),
-// finding the users of the Instruction* is useless; we need to find
-// the users of the first operand. This handles determining which
-// value to follow for us.
-//
-// Note: we *need* to keep this in sync with GetEdgesVisitor. Add
-// something to GetEdgesVisitor, add it here -- remove something from
-// GetEdgesVisitor, remove it here.
-class GetTargetValueVisitor
- : public InstVisitor<GetTargetValueVisitor, Value *> {
-public:
- Value *visitInstruction(Instruction &Inst) { return &Inst; }
-
- Value *visitStoreInst(StoreInst &Inst) { return Inst.getPointerOperand(); }
-
- Value *visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
- return Inst.getPointerOperand();
- }
-
- Value *visitAtomicRMWInst(AtomicRMWInst &Inst) {
- return Inst.getPointerOperand();
- }
-
- Value *visitInsertElementInst(InsertElementInst &Inst) {
- return Inst.getOperand(0);
- }
-
- Value *visitInsertValueInst(InsertValueInst &Inst) {
- return Inst.getAggregateOperand();
- }
-};
-
-// Set building requires a weighted bidirectional graph.
-template <typename EdgeTypeT> class WeightedBidirectionalGraph {
-public:
- typedef std::size_t Node;
-
-private:
- const static Node StartNode = Node(0);
-
- struct Edge {
- EdgeTypeT Weight;
- Node Other;
-
- Edge(const EdgeTypeT &W, const Node &N) : Weight(W), Other(N) {}
-
- bool operator==(const Edge &E) const {
- return Weight == E.Weight && Other == E.Other;
- }
-
- bool operator!=(const Edge &E) const { return !operator==(E); }
- };
-
- struct NodeImpl {
- std::vector<Edge> Edges;
- };
-
- std::vector<NodeImpl> NodeImpls;
-
- bool inbounds(Node NodeIndex) const { return NodeIndex < NodeImpls.size(); }
-
- const NodeImpl &getNode(Node N) const { return NodeImpls[N]; }
- NodeImpl &getNode(Node N) { return NodeImpls[N]; }
-
-public:
- // ----- Various Edge iterators for the graph ----- //
-
- // \brief Iterator for edges. Because this graph is bidirected, we don't
- // allow modification of the edges using this iterator. Additionally, the
- // iterator becomes invalid if you add edges to or from the node you're
- // getting the edges of.
- struct EdgeIterator : public std::iterator<std::forward_iterator_tag,
- std::tuple<EdgeTypeT, Node *>> {
- EdgeIterator(const typename std::vector<Edge>::const_iterator &Iter)
- : Current(Iter) {}
-
- EdgeIterator(NodeImpl &Impl) : Current(Impl.begin()) {}
-
- EdgeIterator &operator++() {
- ++Current;
- return *this;
- }
-
- EdgeIterator operator++(int) {
- EdgeIterator Copy(Current);
- operator++();
- return Copy;
- }
-
- std::tuple<EdgeTypeT, Node> &operator*() {
- Store = std::make_tuple(Current->Weight, Current->Other);
- return Store;
- }
-
- bool operator==(const EdgeIterator &Other) const {
- return Current == Other.Current;
- }
-
- bool operator!=(const EdgeIterator &Other) const {
- return !operator==(Other);
- }
-
- private:
- typename std::vector<Edge>::const_iterator Current;
- std::tuple<EdgeTypeT, Node> Store;
- };
-
- // Wrapper for EdgeIterator with begin()/end() calls.
- struct EdgeIterable {
- EdgeIterable(const std::vector<Edge> &Edges)
- : BeginIter(Edges.begin()), EndIter(Edges.end()) {}
-
- EdgeIterator begin() { return EdgeIterator(BeginIter); }
-
- EdgeIterator end() { return EdgeIterator(EndIter); }
-
- private:
- typename std::vector<Edge>::const_iterator BeginIter;
- typename std::vector<Edge>::const_iterator EndIter;
- };
-
- // ----- Actual graph-related things ----- //
-
- WeightedBidirectionalGraph() {}
-
- WeightedBidirectionalGraph(WeightedBidirectionalGraph<EdgeTypeT> &&Other)
- : NodeImpls(std::move(Other.NodeImpls)) {}
-
- WeightedBidirectionalGraph<EdgeTypeT> &
- operator=(WeightedBidirectionalGraph<EdgeTypeT> &&Other) {
- NodeImpls = std::move(Other.NodeImpls);
- return *this;
- }
-
- Node addNode() {
- auto Index = NodeImpls.size();
- auto NewNode = Node(Index);
- NodeImpls.push_back(NodeImpl());
- return NewNode;
- }
-
- void addEdge(Node From, Node To, const EdgeTypeT &Weight,
- const EdgeTypeT &ReverseWeight) {
- assert(inbounds(From));
- assert(inbounds(To));
- auto &FromNode = getNode(From);
- auto &ToNode = getNode(To);
- FromNode.Edges.push_back(Edge(Weight, To));
- ToNode.Edges.push_back(Edge(ReverseWeight, From));
- }
-
- EdgeIterable edgesFor(const Node &N) const {
- const auto &Node = getNode(N);
- return EdgeIterable(Node.Edges);
- }
-
- bool empty() const { return NodeImpls.empty(); }
- std::size_t size() const { return NodeImpls.size(); }
-
- // \brief Gets an arbitrary node in the graph as a starting point for
- // traversal.
- Node getEntryNode() {
- assert(inbounds(StartNode));
- return StartNode;
- }
-};
-
-typedef WeightedBidirectionalGraph<std::pair<EdgeType, StratifiedAttrs>> GraphT;
-typedef DenseMap<Value *, GraphT::Node> NodeMapT;
-}
-
-//===----------------------------------------------------------------------===//
-// Function declarations that require types defined in the namespace above
-//===----------------------------------------------------------------------===//
-
-// Given an argument number, returns the appropriate Attr index to set.
-static StratifiedAttr argNumberToAttrIndex(StratifiedAttr);
-
-// Given a Value, potentially return which AttrIndex it maps to.
-static Optional<StratifiedAttr> valueToAttrIndex(Value *Val);
-
-// Gets the inverse of a given EdgeType.
-static EdgeType flipWeight(EdgeType);
-
-// Gets edges of the given Instruction*, writing them to the SmallVector*.
-static void argsToEdges(CFLAAResult &, Instruction *, SmallVectorImpl<Edge> &);
-
-// Gets edges of the given ConstantExpr*, writing them to the SmallVector*.
-static void argsToEdges(CFLAAResult &, ConstantExpr *, SmallVectorImpl<Edge> &);
-
-// Gets the "Level" that one should travel in StratifiedSets
-// given an EdgeType.
-static Level directionOfEdgeType(EdgeType);
-
-// Builds the graph needed for constructing the StratifiedSets for the
-// given function
-static void buildGraphFrom(CFLAAResult &, Function *,
- SmallVectorImpl<Value *> &, NodeMapT &, GraphT &);
-
-// Gets the edges of a ConstantExpr as if it was an Instruction. This
-// function also acts on any nested ConstantExprs, adding the edges
-// of those to the given SmallVector as well.
-static void constexprToEdges(CFLAAResult &, ConstantExpr &,
- SmallVectorImpl<Edge> &);
-
-// Given an Instruction, this will add it to the graph, along with any
-// Instructions that are potentially only available from said Instruction
-// For example, given the following line:
-// %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
-// addInstructionToGraph would add both the `load` and `getelementptr`
-// instructions to the graph appropriately.
-static void addInstructionToGraph(CFLAAResult &, Instruction &,
- SmallVectorImpl<Value *> &, NodeMapT &,
- GraphT &);
-
-// Notes whether it would be pointless to add the given Value to our sets.
-static bool canSkipAddingToSets(Value *Val);
-
-static Optional<Function *> parentFunctionOfValue(Value *Val) {
- if (auto *Inst = dyn_cast<Instruction>(Val)) {
- auto *Bb = Inst->getParent();
- return Bb->getParent();
- }
-
- if (auto *Arg = dyn_cast<Argument>(Val))
- return Arg->getParent();
- return NoneType();
-}
-
-template <typename Inst>
-static bool getPossibleTargets(Inst *Call,
- SmallVectorImpl<Function *> &Output) {
- if (auto *Fn = Call->getCalledFunction()) {
- Output.push_back(Fn);
- return true;
- }
-
- // TODO: If the call is indirect, we might be able to enumerate all potential
- // targets of the call and return them, rather than just failing.
- return false;
-}
-
-static Optional<Value *> getTargetValue(Instruction *Inst) {
- GetTargetValueVisitor V;
- return V.visit(Inst);
-}
-
-static bool hasUsefulEdges(Instruction *Inst) {
- bool IsNonInvokeTerminator =
- isa<TerminatorInst>(Inst) && !isa<InvokeInst>(Inst);
- return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) && !IsNonInvokeTerminator;
-}
-
-static bool hasUsefulEdges(ConstantExpr *CE) {
- // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
- // to check for compares.
- return CE->getOpcode() != Instruction::ICmp &&
- CE->getOpcode() != Instruction::FCmp;
-}
-
-static Optional<StratifiedAttr> valueToAttrIndex(Value *Val) {
- if (isa<GlobalValue>(Val))
- return AttrGlobalIndex;
-
- if (auto *Arg = dyn_cast<Argument>(Val))
- // Only pointer arguments should have the argument attribute,
- // because things can't escape through scalars without us seeing a
- // cast, and thus, interaction with them doesn't matter.
- if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
- return argNumberToAttrIndex(Arg->getArgNo());
- return NoneType();
-}
-
-static StratifiedAttr argNumberToAttrIndex(unsigned ArgNum) {
- if (ArgNum >= AttrMaxNumArgs)
- return AttrAllIndex;
- return ArgNum + AttrFirstArgIndex;
-}
-
-static EdgeType flipWeight(EdgeType Initial) {
- switch (Initial) {
- case EdgeType::Assign:
- return EdgeType::Assign;
- case EdgeType::Dereference:
- return EdgeType::Reference;
- case EdgeType::Reference:
- return EdgeType::Dereference;
- }
- llvm_unreachable("Incomplete coverage of EdgeType enum");
-}
-
-static void argsToEdges(CFLAAResult &Analysis, Instruction *Inst,
- SmallVectorImpl<Edge> &Output) {
- assert(hasUsefulEdges(Inst) &&
- "Expected instructions to have 'useful' edges");
- GetEdgesVisitor v(Analysis, Output);
- v.visit(Inst);
-}
-
-static void argsToEdges(CFLAAResult &Analysis, ConstantExpr *CE,
- SmallVectorImpl<Edge> &Output) {
- assert(hasUsefulEdges(CE) && "Expected constant expr to have 'useful' edges");
- GetEdgesVisitor v(Analysis, Output);
- v.visitConstantExpr(CE);
-}
-
-static Level directionOfEdgeType(EdgeType Weight) {
- switch (Weight) {
- case EdgeType::Reference:
- return Level::Above;
- case EdgeType::Dereference:
- return Level::Below;
- case EdgeType::Assign:
- return Level::Same;
- }
- llvm_unreachable("Incomplete switch coverage");
-}
-
-static void constexprToEdges(CFLAAResult &Analysis,
- ConstantExpr &CExprToCollapse,
- SmallVectorImpl<Edge> &Results) {
- SmallVector<ConstantExpr *, 4> Worklist;
- Worklist.push_back(&CExprToCollapse);
-
- SmallVector<Edge, 8> ConstexprEdges;
- SmallPtrSet<ConstantExpr *, 4> Visited;
- while (!Worklist.empty()) {
- auto *CExpr = Worklist.pop_back_val();
-
- if (!hasUsefulEdges(CExpr))
- continue;
-
- ConstexprEdges.clear();
- argsToEdges(Analysis, CExpr, ConstexprEdges);
- for (auto &Edge : ConstexprEdges) {
- if (auto *Nested = dyn_cast<ConstantExpr>(Edge.From))
- if (Visited.insert(Nested).second)
- Worklist.push_back(Nested);
-
- if (auto *Nested = dyn_cast<ConstantExpr>(Edge.To))
- if (Visited.insert(Nested).second)
- Worklist.push_back(Nested);
- }
-
- Results.append(ConstexprEdges.begin(), ConstexprEdges.end());
- }
-}
-
-static void addInstructionToGraph(CFLAAResult &Analysis, Instruction &Inst,
- SmallVectorImpl<Value *> &ReturnedValues,
- NodeMapT &Map, GraphT &Graph) {
- const auto findOrInsertNode = [&Map, &Graph](Value *Val) {
- auto Pair = Map.insert(std::make_pair(Val, GraphT::Node()));
- auto &Iter = Pair.first;
- if (Pair.second) {
- auto NewNode = Graph.addNode();
- Iter->second = NewNode;
- }
- return Iter->second;
- };
-
- // We don't want the edges of most "return" instructions, but we *do* want
- // to know what can be returned.
- if (isa<ReturnInst>(&Inst))
- ReturnedValues.push_back(&Inst);
-
- if (!hasUsefulEdges(&Inst))
- return;
-
- SmallVector<Edge, 8> Edges;
- argsToEdges(Analysis, &Inst, Edges);
-
- // In the case of an unused alloca (or similar), edges may be empty. Note
- // that it exists so we can potentially answer NoAlias.
- if (Edges.empty()) {
- auto MaybeVal = getTargetValue(&Inst);
- assert(MaybeVal.hasValue());
- auto *Target = *MaybeVal;
- findOrInsertNode(Target);
- return;
- }
-
- const auto addEdgeToGraph = [&Graph, &findOrInsertNode](const Edge &E) {
- auto To = findOrInsertNode(E.To);
- auto From = findOrInsertNode(E.From);
- auto FlippedWeight = flipWeight(E.Weight);
- auto Attrs = E.AdditionalAttrs;
- Graph.addEdge(From, To, std::make_pair(E.Weight, Attrs),
- std::make_pair(FlippedWeight, Attrs));
- };
-
- SmallVector<ConstantExpr *, 4> ConstantExprs;
- for (const Edge &E : Edges) {
- addEdgeToGraph(E);
- if (auto *Constexpr = dyn_cast<ConstantExpr>(E.To))
- ConstantExprs.push_back(Constexpr);
- if (auto *Constexpr = dyn_cast<ConstantExpr>(E.From))
- ConstantExprs.push_back(Constexpr);
- }
-
- for (ConstantExpr *CE : ConstantExprs) {
- Edges.clear();
- constexprToEdges(Analysis, *CE, Edges);
- std::for_each(Edges.begin(), Edges.end(), addEdgeToGraph);
- }
-}
-
-// Aside: We may remove graph construction entirely, because it doesn't really
-// buy us much that we don't already have. I'd like to add interprocedural
-// analysis prior to this however, in case that somehow requires the graph
-// produced by this for efficient execution
-static void buildGraphFrom(CFLAAResult &Analysis, Function *Fn,
- SmallVectorImpl<Value *> &ReturnedValues,
- NodeMapT &Map, GraphT &Graph) {
- for (auto &Bb : Fn->getBasicBlockList())
- for (auto &Inst : Bb.getInstList())
- addInstructionToGraph(Analysis, Inst, ReturnedValues, Map, Graph);
-}
-
-static bool canSkipAddingToSets(Value *Val) {
- // Constants can share instances, which may falsely unify multiple
- // sets, e.g. in
- // store i32* null, i32** %ptr1
- // store i32* null, i32** %ptr2
- // clearly ptr1 and ptr2 should not be unified into the same set, so
- // we should filter out the (potentially shared) instance to
- // i32* null.
- if (isa<Constant>(Val)) {
- bool Container = isa<ConstantVector>(Val) || isa<ConstantArray>(Val) ||
- isa<ConstantStruct>(Val);
- // TODO: Because all of these things are constant, we can determine whether
- // the data is *actually* mutable at graph building time. This will probably
- // come for free/cheap with offset awareness.
- bool CanStoreMutableData =
- isa<GlobalValue>(Val) || isa<ConstantExpr>(Val) || Container;
- return !CanStoreMutableData;
- }
-
- return false;
-}
-
-// Builds the graph + StratifiedSets for a function.
-CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
- NodeMapT Map;
- GraphT Graph;
- SmallVector<Value *, 4> ReturnedValues;
-
- buildGraphFrom(*this, Fn, ReturnedValues, Map, Graph);
-
- DenseMap<GraphT::Node, Value *> NodeValueMap;
- NodeValueMap.resize(Map.size());
- for (const auto &Pair : Map)
- NodeValueMap.insert(std::make_pair(Pair.second, Pair.first));
-
- const auto findValueOrDie = [&NodeValueMap](GraphT::Node Node) {
- auto ValIter = NodeValueMap.find(Node);
- assert(ValIter != NodeValueMap.end());
- return ValIter->second;
- };
-
- StratifiedSetsBuilder<Value *> Builder;
-
- SmallVector<GraphT::Node, 16> Worklist;
- for (auto &Pair : Map) {
- Worklist.clear();
-
- auto *Value = Pair.first;
- Builder.add(Value);
- auto InitialNode = Pair.second;
- Worklist.push_back(InitialNode);
- while (!Worklist.empty()) {
- auto Node = Worklist.pop_back_val();
- auto *CurValue = findValueOrDie(Node);
- if (canSkipAddingToSets(CurValue))
- continue;
-
- for (const auto &EdgeTuple : Graph.edgesFor(Node)) {
- auto Weight = std::get<0>(EdgeTuple);
- auto Label = Weight.first;
- auto &OtherNode = std::get<1>(EdgeTuple);
- auto *OtherValue = findValueOrDie(OtherNode);
-
- if (canSkipAddingToSets(OtherValue))
- continue;
-
- bool Added;
- switch (directionOfEdgeType(Label)) {
- case Level::Above:
- Added = Builder.addAbove(CurValue, OtherValue);
- break;
- case Level::Below:
- Added = Builder.addBelow(CurValue, OtherValue);
- break;
- case Level::Same:
- Added = Builder.addWith(CurValue, OtherValue);
- break;
- }
-
- auto Aliasing = Weight.second;
- if (auto MaybeCurIndex = valueToAttrIndex(CurValue))
- Aliasing.set(*MaybeCurIndex);
- if (auto MaybeOtherIndex = valueToAttrIndex(OtherValue))
- Aliasing.set(*MaybeOtherIndex);
- Builder.noteAttributes(CurValue, Aliasing);
- Builder.noteAttributes(OtherValue, Aliasing);
-
- if (Added)
- Worklist.push_back(OtherNode);
- }
- }
- }
-
- // There are times when we end up with parameters not in our graph (i.e. if
- // it's only used as the condition of a branch). Other bits of code depend on
- // things that were present during construction being present in the graph.
- // So, we add all present arguments here.
- for (auto &Arg : Fn->args()) {
- if (!Builder.add(&Arg))
- continue;
-
- auto Attrs = valueToAttrIndex(&Arg);
- if (Attrs.hasValue())
- Builder.noteAttributes(&Arg, *Attrs);
- }
-
- return FunctionInfo(Builder.build(), std::move(ReturnedValues));
-}
-
-void CFLAAResult::scan(Function *Fn) {
- auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
- (void)InsertPair;
- assert(InsertPair.second &&
- "Trying to scan a function that has already been cached");
-
- FunctionInfo Info(buildSetsFrom(Fn));
- Cache[Fn] = std::move(Info);
- Handles.push_front(FunctionHandle(Fn, this));
-}
-
-void CFLAAResult::evict(Function *Fn) { Cache.erase(Fn); }
-
-/// \brief Ensures that the given function is available in the cache.
-/// Returns the appropriate entry from the cache.
-const Optional<CFLAAResult::FunctionInfo> &
-CFLAAResult::ensureCached(Function *Fn) {
- auto Iter = Cache.find(Fn);
- if (Iter == Cache.end()) {
- scan(Fn);
- Iter = Cache.find(Fn);
- assert(Iter != Cache.end());
- assert(Iter->second.hasValue());
- }
- return Iter->second;
-}
-
-AliasResult CFLAAResult::query(const MemoryLocation &LocA,
- const MemoryLocation &LocB) {
- auto *ValA = const_cast<Value *>(LocA.Ptr);
- auto *ValB = const_cast<Value *>(LocB.Ptr);
-
- Function *Fn = nullptr;
- auto MaybeFnA = parentFunctionOfValue(ValA);
- auto MaybeFnB = parentFunctionOfValue(ValB);
- if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
- // The only times this is known to happen are when globals + InlineAsm
- // are involved
- DEBUG(dbgs() << "CFLAA: could not extract parent function information.\n");
- return MayAlias;
- }
-
- if (MaybeFnA.hasValue()) {
- Fn = *MaybeFnA;
- assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
- "Interprocedural queries not supported");
- } else {
- Fn = *MaybeFnB;
- }
-
- assert(Fn != nullptr);
- auto &MaybeInfo = ensureCached(Fn);
- assert(MaybeInfo.hasValue());
-
- auto &Sets = MaybeInfo->Sets;
- auto MaybeA = Sets.find(ValA);
- if (!MaybeA.hasValue())
- return MayAlias;
-
- auto MaybeB = Sets.find(ValB);
- if (!MaybeB.hasValue())
- return MayAlias;
-
- auto SetA = *MaybeA;
- auto SetB = *MaybeB;
- auto AttrsA = Sets.getLink(SetA.Index).Attrs;
- auto AttrsB = Sets.getLink(SetB.Index).Attrs;
-
- // Stratified set attributes are used as markets to signify whether a member
- // of a StratifiedSet (or a member of a set above the current set) has
- // interacted with either arguments or globals. "Interacted with" meaning
- // its value may be different depending on the value of an argument or
- // global. The thought behind this is that, because arguments and globals
- // may alias each other, if AttrsA and AttrsB have touched args/globals,
- // we must conservatively say that they alias. However, if at least one of
- // the sets has no values that could legally be altered by changing the value
- // of an argument or global, then we don't have to be as conservative.
- if (AttrsA.any() && AttrsB.any())
- return MayAlias;
-
- // We currently unify things even if the accesses to them may not be in
- // bounds, so we can't return partial alias here because we don't
- // know whether the pointer is really within the object or not.
- // IE Given an out of bounds GEP and an alloca'd pointer, we may
- // unify the two. We can't return partial alias for this case.
- // Since we do not currently track enough information to
- // differentiate
-
- if (SetA.Index == SetB.Index)
- return MayAlias;
-
- return NoAlias;
-}
-
-CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> *AM) {
- return CFLAAResult(AM->getResult<TargetLibraryAnalysis>(F));
-}
-
-char CFLAA::PassID;
-
-char CFLAAWrapperPass::ID = 0;
-INITIALIZE_PASS_BEGIN(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis",
- false, true)
-INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
-INITIALIZE_PASS_END(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis",
- false, true)
-
-ImmutablePass *llvm::createCFLAAWrapperPass() { return new CFLAAWrapperPass(); }
-
-CFLAAWrapperPass::CFLAAWrapperPass() : ImmutablePass(ID) {
- initializeCFLAAWrapperPassPass(*PassRegistry::getPassRegistry());
-}
-
-bool CFLAAWrapperPass::doInitialization(Module &M) {
- Result.reset(
- new CFLAAResult(getAnalysis<TargetLibraryInfoWrapperPass>().getTLI()));
- return false;
-}
-
-bool CFLAAWrapperPass::doFinalization(Module &M) {
- Result.reset();
- return false;
-}
-
-void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<TargetLibraryInfoWrapperPass>();
-}
diff --git a/gnu/llvm/lib/Analysis/Makefile b/gnu/llvm/lib/Analysis/Makefile
deleted file mode 100644
index 93fd7f9bdd9..00000000000
--- a/gnu/llvm/lib/Analysis/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Analysis/Makefile -------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMAnalysis
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/AsmParser/Makefile b/gnu/llvm/lib/AsmParser/Makefile
deleted file mode 100644
index 995bb0e130e..00000000000
--- a/gnu/llvm/lib/AsmParser/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/AsmParser/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME := LLVMAsmParser
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/AsmParser/module.modulemap b/gnu/llvm/lib/AsmParser/module.modulemap
deleted file mode 100644
index cc300060b3f..00000000000
--- a/gnu/llvm/lib/AsmParser/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module AsmParser { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/Bitcode/Makefile b/gnu/llvm/lib/Bitcode/Makefile
deleted file mode 100644
index 2d6b5ad1fe8..00000000000
--- a/gnu/llvm/lib/Bitcode/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Bitcode/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-PARALLEL_DIRS = Reader Writer
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Bitcode/Reader/Makefile b/gnu/llvm/lib/Bitcode/Reader/Makefile
deleted file mode 100644
index 59af8d53a73..00000000000
--- a/gnu/llvm/lib/Bitcode/Reader/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Bitcode/Reader/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMBitReader
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Bitcode/Writer/Makefile b/gnu/llvm/lib/Bitcode/Writer/Makefile
deleted file mode 100644
index 7b0bd72159a..00000000000
--- a/gnu/llvm/lib/Bitcode/Writer/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Bitcode/Reader/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMBitWriter
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Bitcode/module.modulemap b/gnu/llvm/lib/Bitcode/module.modulemap
deleted file mode 100644
index 7df1a0a3c72..00000000000
--- a/gnu/llvm/lib/Bitcode/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module Bitcode { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/Makefile b/gnu/llvm/lib/CodeGen/AsmPrinter/Makefile
deleted file mode 100644
index 60aa6cbcf6f..00000000000
--- a/gnu/llvm/lib/CodeGen/AsmPrinter/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/CodeGen/AsmPrinter/Makefile ---------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMAsmPrinter
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
deleted file mode 100644
index 1e2f55b7115..00000000000
--- a/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp --*- C++ -*--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing line tables info into COFF files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "WinCodeViewLineTables.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/COFF.h"
-
-namespace llvm {
-
-StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
- assert(S);
- assert((isa<DICompileUnit>(S) || isa<DIFile>(S) || isa<DISubprogram>(S) ||
- isa<DILexicalBlockBase>(S)) &&
- "Unexpected scope info");
-
- auto *Scope = cast<DIScope>(S);
- StringRef Dir = Scope->getDirectory(),
- Filename = Scope->getFilename();
- std::string &Filepath =
- DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
- if (!Filepath.empty())
- return Filepath;
-
- // Clang emits directory and relative filename info into the IR, but CodeView
- // operates on full paths. We could change Clang to emit full paths too, but
- // that would increase the IR size and probably not needed for other users.
- // For now, just concatenate and canonicalize the path here.
- if (Filename.find(':') == 1)
- Filepath = Filename;
- else
- Filepath = (Dir + "\\" + Filename).str();
-
- // Canonicalize the path. We have to do it textually because we may no longer
- // have access the file in the filesystem.
- // First, replace all slashes with backslashes.
- std::replace(Filepath.begin(), Filepath.end(), '/', '\\');
-
- // Remove all "\.\" with "\".
- size_t Cursor = 0;
- while ((Cursor = Filepath.find("\\.\\", Cursor)) != std::string::npos)
- Filepath.erase(Cursor, 2);
-
- // Replace all "\XXX\..\" with "\". Don't try too hard though as the original
- // path should be well-formatted, e.g. start with a drive letter, etc.
- Cursor = 0;
- while ((Cursor = Filepath.find("\\..\\", Cursor)) != std::string::npos) {
- // Something's wrong if the path starts with "\..\", abort.
- if (Cursor == 0)
- break;
-
- size_t PrevSlash = Filepath.rfind('\\', Cursor - 1);
- if (PrevSlash == std::string::npos)
- // Something's wrong, abort.
- break;
-
- Filepath.erase(PrevSlash, Cursor + 3 - PrevSlash);
- // The next ".." might be following the one we've just erased.
- Cursor = PrevSlash;
- }
-
- // Remove all duplicate backslashes.
- Cursor = 0;
- while ((Cursor = Filepath.find("\\\\", Cursor)) != std::string::npos)
- Filepath.erase(Cursor, 1);
-
- return Filepath;
-}
-
-void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
- const MachineFunction *MF) {
- const MDNode *Scope = DL.getScope();
- if (!Scope)
- return;
- unsigned LineNumber = DL.getLine();
- // Skip this line if it is longer than the maximum we can record.
- if (LineNumber > COFF::CVL_MaxLineNumber)
- return;
-
- unsigned ColumnNumber = DL.getCol();
- // Truncate the column number if it is longer than the maximum we can record.
- if (ColumnNumber > COFF::CVL_MaxColumnNumber)
- ColumnNumber = 0;
-
- StringRef Filename = getFullFilepath(Scope);
-
- // Skip this instruction if it has the same file:line as the previous one.
- assert(CurFn);
- if (!CurFn->Instrs.empty()) {
- const InstrInfoTy &LastInstr = InstrInfo[CurFn->Instrs.back()];
- if (LastInstr.Filename == Filename && LastInstr.LineNumber == LineNumber &&
- LastInstr.ColumnNumber == ColumnNumber)
- return;
- }
- FileNameRegistry.add(Filename);
-
- MCSymbol *MCL = Asm->MMI->getContext().createTempSymbol();
- Asm->OutStreamer->EmitLabel(MCL);
- CurFn->Instrs.push_back(MCL);
- InstrInfo[MCL] = InstrInfoTy(Filename, LineNumber, ColumnNumber);
-}
-
-WinCodeViewLineTables::WinCodeViewLineTables(AsmPrinter *AP)
- : Asm(nullptr), CurFn(nullptr) {
- MachineModuleInfo *MMI = AP->MMI;
-
- // If module doesn't have named metadata anchors or COFF debug section
- // is not available, skip any debug info related stuff.
- if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") ||
- !AP->getObjFileLowering().getCOFFDebugSymbolsSection())
- return;
-
- // Tell MMI that we have debug info.
- MMI->setDebugInfoAvailability(true);
- Asm = AP;
-}
-
-void WinCodeViewLineTables::endModule() {
- if (FnDebugInfo.empty())
- return;
-
- assert(Asm != nullptr);
- Asm->OutStreamer->SwitchSection(
- Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
- Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC);
-
- // The COFF .debug$S section consists of several subsections, each starting
- // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length
- // of the payload followed by the payload itself. The subsections are 4-byte
- // aligned.
-
- // Emit per-function debug information. This code is extracted into a
- // separate function for readability.
- for (size_t I = 0, E = VisitedFunctions.size(); I != E; ++I)
- emitDebugInfoForFunction(VisitedFunctions[I]);
-
- // This subsection holds a file index to offset in string table table.
- Asm->OutStreamer->AddComment("File index to string table offset subsection");
- Asm->EmitInt32(COFF::DEBUG_INDEX_SUBSECTION);
- size_t NumFilenames = FileNameRegistry.Infos.size();
- Asm->EmitInt32(8 * NumFilenames);
- for (size_t I = 0, E = FileNameRegistry.Filenames.size(); I != E; ++I) {
- StringRef Filename = FileNameRegistry.Filenames[I];
- // For each unique filename, just write its offset in the string table.
- Asm->EmitInt32(FileNameRegistry.Infos[Filename].StartOffset);
- // The function name offset is not followed by any additional data.
- Asm->EmitInt32(0);
- }
-
- // This subsection holds the string table.
- Asm->OutStreamer->AddComment("String table");
- Asm->EmitInt32(COFF::DEBUG_STRING_TABLE_SUBSECTION);
- Asm->EmitInt32(FileNameRegistry.LastOffset);
- // The payload starts with a null character.
- Asm->EmitInt8(0);
-
- for (size_t I = 0, E = FileNameRegistry.Filenames.size(); I != E; ++I) {
- // Just emit unique filenames one by one, separated by a null character.
- Asm->OutStreamer->EmitBytes(FileNameRegistry.Filenames[I]);
- Asm->EmitInt8(0);
- }
-
- // No more subsections. Fill with zeros to align the end of the section by 4.
- Asm->OutStreamer->EmitFill((-FileNameRegistry.LastOffset) % 4, 0);
-
- clear();
-}
-
-static void EmitLabelDiff(MCStreamer &Streamer,
- const MCSymbol *From, const MCSymbol *To,
- unsigned int Size = 4) {
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- MCContext &Context = Streamer.getContext();
- const MCExpr *FromRef = MCSymbolRefExpr::create(From, Variant, Context),
- *ToRef = MCSymbolRefExpr::create(To, Variant, Context);
- const MCExpr *AddrDelta =
- MCBinaryExpr::create(MCBinaryExpr::Sub, ToRef, FromRef, Context);
- Streamer.EmitValue(AddrDelta, Size);
-}
-
-void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
- // For each function there is a separate subsection
- // which holds the PC to file:line table.
- const MCSymbol *Fn = Asm->getSymbol(GV);
- assert(Fn);
-
- const FunctionInfo &FI = FnDebugInfo[GV];
- if (FI.Instrs.empty())
- return;
- assert(FI.End && "Don't know where the function ends?");
-
- StringRef GVName = GV->getName();
- StringRef FuncName;
- if (auto *SP = getDISubprogram(GV))
- FuncName = SP->getDisplayName();
-
- // FIXME Clang currently sets DisplayName to "bar" for a C++
- // "namespace_foo::bar" function, see PR21528. Luckily, dbghelp.dll is trying
- // to demangle display names anyways, so let's just put a mangled name into
- // the symbols subsection until Clang gives us what we need.
- if (GVName.startswith("\01?"))
- FuncName = GVName.substr(1);
- // Emit a symbol subsection, required by VS2012+ to find function boundaries.
- MCSymbol *SymbolsBegin = Asm->MMI->getContext().createTempSymbol(),
- *SymbolsEnd = Asm->MMI->getContext().createTempSymbol();
- Asm->OutStreamer->AddComment("Symbol subsection for " + Twine(FuncName));
- Asm->EmitInt32(COFF::DEBUG_SYMBOL_SUBSECTION);
- EmitLabelDiff(*Asm->OutStreamer, SymbolsBegin, SymbolsEnd);
- Asm->OutStreamer->EmitLabel(SymbolsBegin);
- {
- MCSymbol *ProcSegmentBegin = Asm->MMI->getContext().createTempSymbol(),
- *ProcSegmentEnd = Asm->MMI->getContext().createTempSymbol();
- EmitLabelDiff(*Asm->OutStreamer, ProcSegmentBegin, ProcSegmentEnd, 2);
- Asm->OutStreamer->EmitLabel(ProcSegmentBegin);
-
- Asm->EmitInt16(COFF::DEBUG_SYMBOL_TYPE_PROC_START);
- // Some bytes of this segment don't seem to be required for basic debugging,
- // so just fill them with zeroes.
- Asm->OutStreamer->EmitFill(12, 0);
- // This is the important bit that tells the debugger where the function
- // code is located and what's its size:
- EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End);
- Asm->OutStreamer->EmitFill(12, 0);
- Asm->OutStreamer->EmitCOFFSecRel32(Fn);
- Asm->OutStreamer->EmitCOFFSectionIndex(Fn);
- Asm->EmitInt8(0);
- // Emit the function display name as a null-terminated string.
- Asm->OutStreamer->EmitBytes(FuncName);
- Asm->EmitInt8(0);
- Asm->OutStreamer->EmitLabel(ProcSegmentEnd);
-
- // We're done with this function.
- Asm->EmitInt16(0x0002);
- Asm->EmitInt16(COFF::DEBUG_SYMBOL_TYPE_PROC_END);
- }
- Asm->OutStreamer->EmitLabel(SymbolsEnd);
- // Every subsection must be aligned to a 4-byte boundary.
- Asm->OutStreamer->EmitFill((-FuncName.size()) % 4, 0);
-
- // PCs/Instructions are grouped into segments sharing the same filename.
- // Pre-calculate the lengths (in instructions) of these segments and store
- // them in a map for convenience. Each index in the map is the sequential
- // number of the respective instruction that starts a new segment.
- DenseMap<size_t, size_t> FilenameSegmentLengths;
- size_t LastSegmentEnd = 0;
- StringRef PrevFilename = InstrInfo[FI.Instrs[0]].Filename;
- for (size_t J = 1, F = FI.Instrs.size(); J != F; ++J) {
- if (PrevFilename == InstrInfo[FI.Instrs[J]].Filename)
- continue;
- FilenameSegmentLengths[LastSegmentEnd] = J - LastSegmentEnd;
- LastSegmentEnd = J;
- PrevFilename = InstrInfo[FI.Instrs[J]].Filename;
- }
- FilenameSegmentLengths[LastSegmentEnd] = FI.Instrs.size() - LastSegmentEnd;
-
- // Emit a line table subsection, required to do PC-to-file:line lookup.
- Asm->OutStreamer->AddComment("Line table subsection for " + Twine(FuncName));
- Asm->EmitInt32(COFF::DEBUG_LINE_TABLE_SUBSECTION);
- MCSymbol *LineTableBegin = Asm->MMI->getContext().createTempSymbol(),
- *LineTableEnd = Asm->MMI->getContext().createTempSymbol();
- EmitLabelDiff(*Asm->OutStreamer, LineTableBegin, LineTableEnd);
- Asm->OutStreamer->EmitLabel(LineTableBegin);
-
- // Identify the function this subsection is for.
- Asm->OutStreamer->EmitCOFFSecRel32(Fn);
- Asm->OutStreamer->EmitCOFFSectionIndex(Fn);
- // Insert flags after a 16-bit section index.
- Asm->EmitInt16(COFF::DEBUG_LINE_TABLES_HAVE_COLUMN_RECORDS);
-
- // Length of the function's code, in bytes.
- EmitLabelDiff(*Asm->OutStreamer, Fn, FI.End);
-
- // PC-to-linenumber lookup table:
- MCSymbol *FileSegmentEnd = nullptr;
-
- // The start of the last segment:
- size_t LastSegmentStart = 0;
-
- auto FinishPreviousChunk = [&] {
- if (!FileSegmentEnd)
- return;
- for (size_t ColSegI = LastSegmentStart,
- ColSegEnd = ColSegI + FilenameSegmentLengths[LastSegmentStart];
- ColSegI != ColSegEnd; ++ColSegI) {
- unsigned ColumnNumber = InstrInfo[FI.Instrs[ColSegI]].ColumnNumber;
- assert(ColumnNumber <= COFF::CVL_MaxColumnNumber);
- Asm->EmitInt16(ColumnNumber); // Start column
- Asm->EmitInt16(0); // End column
- }
- Asm->OutStreamer->EmitLabel(FileSegmentEnd);
- };
-
- for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
- MCSymbol *Instr = FI.Instrs[J];
- assert(InstrInfo.count(Instr));
-
- if (FilenameSegmentLengths.count(J)) {
- // We came to a beginning of a new filename segment.
- FinishPreviousChunk();
- StringRef CurFilename = InstrInfo[FI.Instrs[J]].Filename;
- assert(FileNameRegistry.Infos.count(CurFilename));
- size_t IndexInStringTable =
- FileNameRegistry.Infos[CurFilename].FilenameID;
- // Each segment starts with the offset of the filename
- // in the string table.
- Asm->OutStreamer->AddComment(
- "Segment for file '" + Twine(CurFilename) + "' begins");
- MCSymbol *FileSegmentBegin = Asm->MMI->getContext().createTempSymbol();
- Asm->OutStreamer->EmitLabel(FileSegmentBegin);
- Asm->EmitInt32(8 * IndexInStringTable);
-
- // Number of PC records in the lookup table.
- size_t SegmentLength = FilenameSegmentLengths[J];
- Asm->EmitInt32(SegmentLength);
-
- // Full size of the segment for this filename, including the prev two
- // records.
- FileSegmentEnd = Asm->MMI->getContext().createTempSymbol();
- EmitLabelDiff(*Asm->OutStreamer, FileSegmentBegin, FileSegmentEnd);
- LastSegmentStart = J;
- }
-
- // The first PC with the given linenumber and the linenumber itself.
- EmitLabelDiff(*Asm->OutStreamer, Fn, Instr);
- uint32_t LineNumber = InstrInfo[Instr].LineNumber;
- assert(LineNumber <= COFF::CVL_MaxLineNumber);
- uint32_t LineData = LineNumber | COFF::CVL_IsStatement;
- Asm->EmitInt32(LineData);
- }
-
- FinishPreviousChunk();
- Asm->OutStreamer->EmitLabel(LineTableEnd);
-}
-
-void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
- assert(!CurFn && "Can't process two functions at once!");
-
- if (!Asm || !Asm->MMI->hasDebugInfo())
- return;
-
- const Function *GV = MF->getFunction();
- assert(FnDebugInfo.count(GV) == false);
- VisitedFunctions.push_back(GV);
- CurFn = &FnDebugInfo[GV];
-
- // Find the end of the function prolog.
- // FIXME: is there a simpler a way to do this? Can we just search
- // for the first instruction of the function, not the last of the prolog?
- DebugLoc PrologEndLoc;
- bool EmptyPrologue = true;
- for (const auto &MBB : *MF) {
- if (PrologEndLoc)
- break;
- for (const auto &MI : MBB) {
- if (MI.isDebugValue())
- continue;
-
- // First known non-DBG_VALUE and non-frame setup location marks
- // the beginning of the function body.
- // FIXME: do we need the first subcondition?
- if (!MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) {
- PrologEndLoc = MI.getDebugLoc();
- break;
- }
- EmptyPrologue = false;
- }
- }
- // Record beginning of function if we have a non-empty prologue.
- if (PrologEndLoc && !EmptyPrologue) {
- DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
- maybeRecordLocation(FnStartDL, MF);
- }
-}
-
-void WinCodeViewLineTables::endFunction(const MachineFunction *MF) {
- if (!Asm || !CurFn) // We haven't created any debug info for this function.
- return;
-
- const Function *GV = MF->getFunction();
- assert(FnDebugInfo.count(GV));
- assert(CurFn == &FnDebugInfo[GV]);
-
- if (CurFn->Instrs.empty()) {
- FnDebugInfo.erase(GV);
- VisitedFunctions.pop_back();
- } else {
- CurFn->End = Asm->getFunctionEnd();
- }
- CurFn = nullptr;
-}
-
-void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) {
- // Ignore DBG_VALUE locations and function prologue.
- if (!Asm || MI->isDebugValue() || MI->getFlag(MachineInstr::FrameSetup))
- return;
- DebugLoc DL = MI->getDebugLoc();
- if (DL == PrevInstLoc || !DL)
- return;
- maybeRecordLocation(DL, Asm->MF);
-}
-}
diff --git a/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
deleted file mode 100644
index 78068e07c16..00000000000
--- a/gnu/llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
+++ /dev/null
@@ -1,138 +0,0 @@
-//===-- llvm/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h ----*- C++ -*--===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing line tables info into COFF files.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
-#define LLVM_LIB_CODEGEN_ASMPRINTER_WINCODEVIEWLINETABLES_H
-
-#include "AsmPrinterHandler.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/LexicalScopes.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/DebugLoc.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-
-namespace llvm {
-/// \brief Collects and handles line tables information in a CodeView format.
-class LLVM_LIBRARY_VISIBILITY WinCodeViewLineTables : public AsmPrinterHandler {
- AsmPrinter *Asm;
- DebugLoc PrevInstLoc;
-
- // For each function, store a vector of labels to its instructions, as well as
- // to the end of the function.
- struct FunctionInfo {
- SmallVector<MCSymbol *, 10> Instrs;
- MCSymbol *End;
- FunctionInfo() : End(nullptr) {}
- } *CurFn;
-
- typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
- FnDebugInfoTy FnDebugInfo;
- // Store the functions we've visited in a vector so we can maintain a stable
- // order while emitting subsections.
- SmallVector<const Function *, 10> VisitedFunctions;
-
- // InstrInfoTy - Holds the Filename:LineNumber information for every
- // instruction with a unique debug location.
- struct InstrInfoTy {
- StringRef Filename;
- unsigned LineNumber;
- unsigned ColumnNumber;
-
- InstrInfoTy() : LineNumber(0), ColumnNumber(0) {}
-
- InstrInfoTy(StringRef Filename, unsigned LineNumber, unsigned ColumnNumber)
- : Filename(Filename), LineNumber(LineNumber),
- ColumnNumber(ColumnNumber) {}
- };
- DenseMap<MCSymbol *, InstrInfoTy> InstrInfo;
-
- // FileNameRegistry - Manages filenames observed while generating debug info
- // by filtering out duplicates and bookkeeping the offsets in the string
- // table to be generated.
- struct FileNameRegistryTy {
- SmallVector<StringRef, 10> Filenames;
- struct PerFileInfo {
- size_t FilenameID, StartOffset;
- };
- StringMap<PerFileInfo> Infos;
-
- // The offset in the string table where we'll write the next unique
- // filename.
- size_t LastOffset;
-
- FileNameRegistryTy() {
- clear();
- }
-
- // Add Filename to the registry, if it was not observed before.
- void add(StringRef Filename) {
- if (Infos.count(Filename))
- return;
- size_t OldSize = Infos.size();
- Infos[Filename].FilenameID = OldSize;
- Infos[Filename].StartOffset = LastOffset;
- LastOffset += Filename.size() + 1;
- Filenames.push_back(Filename);
- }
-
- void clear() {
- LastOffset = 1;
- Infos.clear();
- Filenames.clear();
- }
- } FileNameRegistry;
-
- typedef std::map<std::pair<StringRef, StringRef>, std::string>
- DirAndFilenameToFilepathMapTy;
- DirAndFilenameToFilepathMapTy DirAndFilenameToFilepathMap;
- StringRef getFullFilepath(const MDNode *S);
-
- void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
-
- void clear() {
- assert(CurFn == nullptr);
- FileNameRegistry.clear();
- InstrInfo.clear();
- }
-
- void emitDebugInfoForFunction(const Function *GV);
-
-public:
- WinCodeViewLineTables(AsmPrinter *Asm);
-
- void setSymbolSize(const llvm::MCSymbol *, uint64_t) override {}
-
- /// \brief Emit the COFF section that holds the line table information.
- void endModule() override;
-
- /// \brief Gather pre-function debug information.
- void beginFunction(const MachineFunction *MF) override;
-
- /// \brief Gather post-function debug information.
- void endFunction(const MachineFunction *) override;
-
- /// \brief Process beginning of an instruction.
- void beginInstruction(const MachineInstr *MI) override;
-
- /// \brief Process end of an instruction.
- void endInstruction() override {}
-};
-} // End of namespace llvm
-
-#endif
diff --git a/gnu/llvm/lib/CodeGen/CoreCLRGC.cpp b/gnu/llvm/lib/CodeGen/CoreCLRGC.cpp
deleted file mode 100644
index ff7c0d5dc0a..00000000000
--- a/gnu/llvm/lib/CodeGen/CoreCLRGC.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-//===-- CoreCLRGC.cpp - CoreCLR Runtime GC Strategy -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a GCStrategy for the CoreCLR Runtime.
-// The strategy is similar to Statepoint-example GC, but differs from it in
-// certain aspects, such as:
-// 1) Base-pointers need not be explicitly tracked and reported for
-// interior pointers
-// 2) Uses a different format for encoding stack-maps
-// 3) Location of Safe-point polls: polls are only needed before loop-back edges
-// and before tail-calls (not needed at function-entry)
-//
-// The above differences in behavior are to be implemented in upcoming checkins.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Value.h"
-
-using namespace llvm;
-
-namespace {
-class CoreCLRGC : public GCStrategy {
-public:
- CoreCLRGC() {
- UseStatepoints = true;
- // These options are all gc.root specific, we specify them so that the
- // gc.root lowering code doesn't run.
- InitRoots = false;
- NeededSafePoints = 0;
- UsesMetadata = false;
- CustomRoots = false;
- }
- Optional<bool> isGCManagedPointer(const Type *Ty) const override {
- // Method is only valid on pointer typed values.
- const PointerType *PT = cast<PointerType>(Ty);
- // We pick addrspace(1) as our GC managed heap.
- return (1 == PT->getAddressSpace());
- }
-};
-}
-
-static GCRegistry::Add<CoreCLRGC> X("coreclr", "CoreCLR-compatible GC");
-
-namespace llvm {
-void linkCoreCLRGC() {}
-}
diff --git a/gnu/llvm/lib/CodeGen/ErlangGC.cpp b/gnu/llvm/lib/CodeGen/ErlangGC.cpp
deleted file mode 100644
index 024946d1436..00000000000
--- a/gnu/llvm/lib/CodeGen/ErlangGC.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-//===-- ErlangGC.cpp - Erlang/OTP GC strategy -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the Erlang/OTP runtime-compatible garbage collector
-// (e.g. defines safe points, root initialization etc.)
-//
-// The frametable emitter is in ErlangGCPrinter.cpp.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCs.h"
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-
-using namespace llvm;
-
-namespace {
-
-class ErlangGC : public GCStrategy {
-public:
- ErlangGC();
-};
-}
-
-static GCRegistry::Add<ErlangGC> X("erlang",
- "erlang-compatible garbage collector");
-
-void llvm::linkErlangGC() {}
-
-ErlangGC::ErlangGC() {
- InitRoots = false;
- NeededSafePoints = 1 << GC::PostCall;
- UsesMetadata = true;
- CustomRoots = false;
-}
diff --git a/gnu/llvm/lib/CodeGen/MIRParser/Makefile b/gnu/llvm/lib/CodeGen/MIRParser/Makefile
deleted file mode 100644
index c02d18806a9..00000000000
--- a/gnu/llvm/lib/CodeGen/MIRParser/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/CodeGen/MIRParser/Makefile ----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMIRParser
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/CodeGen/Makefile b/gnu/llvm/lib/CodeGen/Makefile
deleted file mode 100644
index 96f7ca58513..00000000000
--- a/gnu/llvm/lib/CodeGen/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-##===- lib/CodeGen/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMCodeGen
-PARALLEL_DIRS = SelectionDAG AsmPrinter MIRParser
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
-# Xcode prior to 2.4 generates an error in -pedantic mode with use of HUGE_VAL
-# in this directory. Disable -pedantic for this broken compiler.
-ifneq ($(HUGE_VAL_SANITY),yes)
-CompileCommonOpts := $(filter-out -pedantic, $(CompileCommonOpts))
-endif
-
diff --git a/gnu/llvm/lib/CodeGen/OcamlGC.cpp b/gnu/llvm/lib/CodeGen/OcamlGC.cpp
deleted file mode 100644
index 17654a6ac3a..00000000000
--- a/gnu/llvm/lib/CodeGen/OcamlGC.cpp
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- OcamlGC.cpp - Ocaml frametable GC strategy ------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements lowering for the llvm.gc* intrinsics compatible with
-// Objective Caml 3.10.0, which uses a liveness-accurate static stack map.
-//
-// The frametable emitter is in OcamlGCPrinter.cpp.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCs.h"
-#include "llvm/CodeGen/GCStrategy.h"
-
-using namespace llvm;
-
-namespace {
-class OcamlGC : public GCStrategy {
-public:
- OcamlGC();
-};
-}
-
-static GCRegistry::Add<OcamlGC> X("ocaml", "ocaml 3.10-compatible GC");
-
-void llvm::linkOcamlGC() {}
-
-OcamlGC::OcamlGC() {
- NeededSafePoints = 1 << GC::PostCall;
- UsesMetadata = true;
-}
diff --git a/gnu/llvm/lib/CodeGen/Passes.cpp b/gnu/llvm/lib/CodeGen/Passes.cpp
deleted file mode 100644
index 873f7125b82..00000000000
--- a/gnu/llvm/lib/CodeGen/Passes.cpp
+++ /dev/null
@@ -1,817 +0,0 @@
-//===-- Passes.cpp - Target independent code generation passes ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file 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.
-//
-//===---------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/CFLAliasAnalysis.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/Analysis/ScopedNoAliasAA.h"
-#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/RegAllocRegistry.h"
-#include "llvm/IR/IRPrintingPasses.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/SymbolRewriter.h"
-
-using namespace llvm;
-
-static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden,
- cl::desc("Disable Post Regalloc"));
-static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
- cl::desc("Disable branch folding"));
-static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
- cl::desc("Disable tail duplication"));
-static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
- cl::desc("Disable pre-register allocation tail duplication"));
-static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
- cl::Hidden, cl::desc("Disable probability-driven block placement"));
-static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
- cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
-static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
- cl::desc("Disable Stack Slot Coloring"));
-static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
- cl::desc("Disable Machine Dead Code Elimination"));
-static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
- cl::desc("Disable Early If-conversion"));
-static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
- cl::desc("Disable Machine LICM"));
-static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
- cl::desc("Disable Machine Common Subexpression Elimination"));
-static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
- "optimize-regalloc", cl::Hidden,
- cl::desc("Enable optimized register allocation compilation path."));
-static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
- cl::Hidden,
- cl::desc("Disable Machine LICM"));
-static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
- cl::desc("Disable Machine Sinking"));
-static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
- cl::desc("Disable Loop Strength Reduction Pass"));
-static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
- cl::Hidden, cl::desc("Disable ConstantHoisting"));
-static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
- cl::desc("Disable Codegen Prepare"));
-static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
- cl::desc("Disable Copy Propagation pass"));
-static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
- cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
-static cl::opt<bool> EnableImplicitNullChecks(
- "enable-implicit-null-checks",
- cl::desc("Fold null checks into faulting memory operations"),
- cl::init(false));
-static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
- cl::desc("Print LLVM IR produced by the loop-reduce pass"));
-static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
- cl::desc("Print LLVM IR input to isel pass"));
-static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
- cl::desc("Dump garbage collector data"));
-static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden,
- cl::desc("Verify generated machine code"),
- cl::init(false),
- cl::ZeroOrMore);
-
-static cl::opt<std::string>
-PrintMachineInstrs("print-machineinstrs", cl::ValueOptional,
- cl::desc("Print machine instrs"),
- cl::value_desc("pass-name"), cl::init("option-unspecified"));
-
-// Temporary option to allow experimenting with MachineScheduler as a post-RA
-// scheduler. Targets can "properly" enable this with
-// substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
-// Targets can return true in targetSchedulesPostRAScheduling() and
-// insert a PostRA scheduling pass wherever it wants.
-cl::opt<bool> MISchedPostRA("misched-postra", cl::Hidden,
- cl::desc("Run MachineScheduler post regalloc (independent of preRA sched)"));
-
-// Experimental option to run live interval analysis early.
-static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
- cl::desc("Run live interval analysis earlier in the pipeline"));
-
-static cl::opt<bool> UseCFLAA("use-cfl-aa-in-codegen",
- cl::init(false), cl::Hidden,
- cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"));
-
-/// Allow standard passes to be disabled by command line options. This supports
-/// simple binary flags that either suppress the pass or do nothing.
-/// i.e. -disable-mypass=false has no effect.
-/// These should be converted to boolOrDefault in order to use applyOverride.
-static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
- bool Override) {
- if (Override)
- return IdentifyingPassPtr();
- return PassID;
-}
-
-/// Allow standard passes to be disabled by the command line, regardless of who
-/// is adding the pass.
-///
-/// StandardID is the pass identified in the standard pass pipeline and provided
-/// to addPass(). It may be a target-specific ID in the case that the target
-/// directly adds its own pass, but in that case we harmlessly fall through.
-///
-/// TargetID is the pass that the target has configured to override StandardID.
-///
-/// StandardID may be a pseudo ID. In that case TargetID is the name of the real
-/// pass to run. This allows multiple options to control a single pass depending
-/// on where in the pipeline that pass is added.
-static IdentifyingPassPtr overridePass(AnalysisID StandardID,
- IdentifyingPassPtr TargetID) {
- if (StandardID == &PostRASchedulerID)
- return applyDisable(TargetID, DisablePostRA);
-
- if (StandardID == &BranchFolderPassID)
- return applyDisable(TargetID, DisableBranchFold);
-
- if (StandardID == &TailDuplicateID)
- return applyDisable(TargetID, DisableTailDuplicate);
-
- if (StandardID == &TargetPassConfig::EarlyTailDuplicateID)
- return applyDisable(TargetID, DisableEarlyTailDup);
-
- if (StandardID == &MachineBlockPlacementID)
- return applyDisable(TargetID, DisableBlockPlacement);
-
- if (StandardID == &StackSlotColoringID)
- return applyDisable(TargetID, DisableSSC);
-
- if (StandardID == &DeadMachineInstructionElimID)
- return applyDisable(TargetID, DisableMachineDCE);
-
- if (StandardID == &EarlyIfConverterID)
- return applyDisable(TargetID, DisableEarlyIfConversion);
-
- if (StandardID == &MachineLICMID)
- return applyDisable(TargetID, DisableMachineLICM);
-
- if (StandardID == &MachineCSEID)
- return applyDisable(TargetID, DisableMachineCSE);
-
- if (StandardID == &TargetPassConfig::PostRAMachineLICMID)
- return applyDisable(TargetID, DisablePostRAMachineLICM);
-
- if (StandardID == &MachineSinkingID)
- return applyDisable(TargetID, DisableMachineSink);
-
- if (StandardID == &MachineCopyPropagationID)
- return applyDisable(TargetID, DisableCopyProp);
-
- return TargetID;
-}
-
-//===---------------------------------------------------------------------===//
-/// TargetPassConfig
-//===---------------------------------------------------------------------===//
-
-INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
- "Target Pass Configuration", false, false)
-char TargetPassConfig::ID = 0;
-
-// Pseudo Pass IDs.
-char TargetPassConfig::EarlyTailDuplicateID = 0;
-char TargetPassConfig::PostRAMachineLICMID = 0;
-
-namespace {
-struct InsertedPass {
- AnalysisID TargetPassID;
- IdentifyingPassPtr InsertedPassID;
- bool VerifyAfter;
- bool PrintAfter;
-
- InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
- bool VerifyAfter, bool PrintAfter)
- : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
- VerifyAfter(VerifyAfter), PrintAfter(PrintAfter) {}
-
- Pass *getInsertedPass() const {
- assert(InsertedPassID.isValid() && "Illegal Pass ID!");
- if (InsertedPassID.isInstance())
- return InsertedPassID.getInstance();
- Pass *NP = Pass::createPass(InsertedPassID.getID());
- assert(NP && "Pass ID not registered");
- return NP;
- }
-};
-}
-
-namespace llvm {
-class PassConfigImpl {
-public:
- // List of passes explicitly substituted by this target. Normally this is
- // empty, but it is a convenient way to suppress or replace specific passes
- // that are part of a standard pass pipeline without overridding the entire
- // pipeline. This mechanism allows target options to inherit a standard pass's
- // user interface. For example, a target may disable a standard pass by
- // default by substituting a pass ID of zero, and the user may still enable
- // that standard pass with an explicit command line option.
- DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
-
- /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
- /// is inserted after each instance of the first one.
- SmallVector<InsertedPass, 4> InsertedPasses;
-};
-} // namespace llvm
-
-// Out of line virtual method.
-TargetPassConfig::~TargetPassConfig() {
- delete Impl;
-}
-
-// Out of line constructor provides default values for pass options and
-// registers all common codegen passes.
-TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm)
- : ImmutablePass(ID), PM(&pm), StartBefore(nullptr), StartAfter(nullptr),
- StopAfter(nullptr), Started(true), Stopped(false),
- AddingMachinePasses(false), TM(tm), Impl(nullptr), Initialized(false),
- DisableVerify(false), EnableTailMerge(true) {
-
- Impl = new PassConfigImpl();
-
- // Register all target independent codegen passes to activate their PassIDs,
- // including this pass itself.
- initializeCodeGen(*PassRegistry::getPassRegistry());
-
- // Also register alias analysis passes required by codegen passes.
- initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
- initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
-
- // Substitute Pseudo Pass IDs for real ones.
- substitutePass(&EarlyTailDuplicateID, &TailDuplicateID);
- substitutePass(&PostRAMachineLICMID, &MachineLICMID);
-}
-
-/// Insert InsertedPassID pass after TargetPassID.
-void TargetPassConfig::insertPass(AnalysisID TargetPassID,
- IdentifyingPassPtr InsertedPassID,
- bool VerifyAfter, bool PrintAfter) {
- assert(((!InsertedPassID.isInstance() &&
- TargetPassID != InsertedPassID.getID()) ||
- (InsertedPassID.isInstance() &&
- TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
- "Insert a pass after itself!");
- Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter,
- PrintAfter);
-}
-
-/// createPassConfig - Create a pass configuration object to be used by
-/// addPassToEmitX methods for generating a pipeline of CodeGen passes.
-///
-/// Targets may override this to extend TargetPassConfig.
-TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
- return new TargetPassConfig(this, PM);
-}
-
-TargetPassConfig::TargetPassConfig()
- : ImmutablePass(ID), PM(nullptr) {
- llvm_unreachable("TargetPassConfig should not be constructed on-the-fly");
-}
-
-// Helper to verify the analysis is really immutable.
-void TargetPassConfig::setOpt(bool &Opt, bool Val) {
- assert(!Initialized && "PassConfig is immutable");
- Opt = Val;
-}
-
-void TargetPassConfig::substitutePass(AnalysisID StandardID,
- IdentifyingPassPtr TargetID) {
- Impl->TargetPasses[StandardID] = TargetID;
-}
-
-IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
- DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
- I = Impl->TargetPasses.find(ID);
- if (I == Impl->TargetPasses.end())
- return ID;
- return I->second;
-}
-
-/// Add a pass to the PassManager if that pass is supposed to be run. If the
-/// Started/Stopped flags indicate either that the compilation should start at
-/// a later pass or that it should stop after an earlier pass, then do not add
-/// the pass. Finally, compare the current pass against the StartAfter
-/// and StopAfter options and change the Started/Stopped flags accordingly.
-void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) {
- assert(!Initialized && "PassConfig is immutable");
-
- // Cache the Pass ID here in case the pass manager finds this pass is
- // redundant with ones already scheduled / available, and deletes it.
- // Fundamentally, once we add the pass to the manager, we no longer own it
- // and shouldn't reference it.
- AnalysisID PassID = P->getPassID();
-
- if (StartBefore == PassID)
- Started = true;
- if (Started && !Stopped) {
- std::string Banner;
- // Construct banner message before PM->add() as that may delete the pass.
- if (AddingMachinePasses && (printAfter || verifyAfter))
- Banner = std::string("After ") + std::string(P->getPassName());
- PM->add(P);
- if (AddingMachinePasses) {
- if (printAfter)
- addPrintPass(Banner);
- if (verifyAfter)
- addVerifyPass(Banner);
- }
-
- // Add the passes after the pass P if there is any.
- for (auto IP : Impl->InsertedPasses) {
- if (IP.TargetPassID == PassID)
- addPass(IP.getInsertedPass(), IP.VerifyAfter, IP.PrintAfter);
- }
- } else {
- delete P;
- }
- if (StopAfter == PassID)
- Stopped = true;
- if (StartAfter == PassID)
- Started = true;
- if (Stopped && !Started)
- report_fatal_error("Cannot stop compilation after pass that is not run");
-}
-
-/// Add a CodeGen pass at this point in the pipeline after checking for target
-/// and command line overrides.
-///
-/// addPass cannot return a pointer to the pass instance because is internal the
-/// PassManager and the instance we create here may already be freed.
-AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter,
- bool printAfter) {
- IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
- IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
- if (!FinalPtr.isValid())
- return nullptr;
-
- Pass *P;
- if (FinalPtr.isInstance())
- P = FinalPtr.getInstance();
- else {
- P = Pass::createPass(FinalPtr.getID());
- if (!P)
- llvm_unreachable("Pass ID not registered");
- }
- AnalysisID FinalID = P->getPassID();
- addPass(P, verifyAfter, printAfter); // Ends the lifetime of P.
-
- return FinalID;
-}
-
-void TargetPassConfig::printAndVerify(const std::string &Banner) {
- addPrintPass(Banner);
- addVerifyPass(Banner);
-}
-
-void TargetPassConfig::addPrintPass(const std::string &Banner) {
- if (TM->shouldPrintMachineCode())
- PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
-}
-
-void TargetPassConfig::addVerifyPass(const std::string &Banner) {
- if (VerifyMachineCode)
- PM->add(createMachineVerifierPass(Banner));
-}
-
-/// Add common target configurable passes that perform LLVM IR to IR transforms
-/// following machine independent optimization.
-void TargetPassConfig::addIRPasses() {
- // Basic AliasAnalysis support.
- // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
- // BasicAliasAnalysis wins if they disagree. This is intended to help
- // support "obvious" type-punning idioms.
- if (UseCFLAA)
- addPass(createCFLAAWrapperPass());
- addPass(createTypeBasedAAWrapperPass());
- addPass(createScopedNoAliasAAWrapperPass());
- addPass(createBasicAAWrapperPass());
-
- // Before running any passes, run the verifier to determine if the input
- // coming from the front-end and/or optimizer is valid.
- if (!DisableVerify)
- addPass(createVerifierPass());
-
- // Run loop strength reduction before anything else.
- if (getOptLevel() != CodeGenOpt::None && !DisableLSR) {
- addPass(createLoopStrengthReducePass());
- if (PrintLSR)
- addPass(createPrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
- }
-
- // Run GC lowering passes for builtin collectors
- // TODO: add a pass insertion point here
- addPass(createGCLoweringPass());
- addPass(createShadowStackGCLoweringPass());
-
- // Make sure that no unreachable blocks are instruction selected.
- addPass(createUnreachableBlockEliminationPass());
-
- // Prepare expensive constants for SelectionDAG.
- if (getOptLevel() != CodeGenOpt::None && !DisableConstantHoisting)
- addPass(createConstantHoistingPass());
-
- if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
- addPass(createPartiallyInlineLibCallsPass());
-}
-
-/// Turn exception handling constructs into something the code generators can
-/// handle.
-void TargetPassConfig::addPassesToHandleExceptions() {
- switch (TM->getMCAsmInfo()->getExceptionHandlingType()) {
- case ExceptionHandling::SjLj:
- // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
- // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
- // catch info can get misplaced when a selector ends up more than one block
- // removed from the parent invoke(s). This could happen when a landing
- // pad is shared by multiple invokes and is also a target of a normal
- // edge from elsewhere.
- addPass(createSjLjEHPreparePass());
- // FALLTHROUGH
- case ExceptionHandling::DwarfCFI:
- case ExceptionHandling::ARM:
- addPass(createDwarfEHPass(TM));
- break;
- case ExceptionHandling::WinEH:
- // We support using both GCC-style and MSVC-style exceptions on Windows, so
- // add both preparation passes. Each pass will only actually run if it
- // recognizes the personality function.
- addPass(createWinEHPass(TM));
- addPass(createDwarfEHPass(TM));
- break;
- case ExceptionHandling::None:
- addPass(createLowerInvokePass());
-
- // The lower invoke pass may create unreachable code. Remove it.
- addPass(createUnreachableBlockEliminationPass());
- break;
- }
-}
-
-/// Add pass to prepare the LLVM IR for code generation. This should be done
-/// before exception handling preparation passes.
-void TargetPassConfig::addCodeGenPrepare() {
- if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
- addPass(createCodeGenPreparePass(TM));
- addPass(createRewriteSymbolsPass());
-}
-
-/// Add common passes that perform LLVM IR to IR transforms in preparation for
-/// instruction selection.
-void TargetPassConfig::addISelPrepare() {
- addPreISel();
-
- // Add both the safe stack and the stack protection passes: each of them will
- // only protect functions that have corresponding attributes.
- addPass(createSafeStackPass(TM));
- addPass(createStackProtectorPass(TM));
-
- if (PrintISelInput)
- addPass(createPrintFunctionPass(
- dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
-
- // All passes which modify the LLVM IR are now complete; run the verifier
- // to ensure that the IR is valid.
- if (!DisableVerify)
- addPass(createVerifierPass());
-}
-
-/// Add the complete set of target-independent postISel code generator passes.
-///
-/// This can be read as the standard order of major LLVM CodeGen stages. Stages
-/// with nontrivial configuration or multiple passes are broken out below in
-/// add%Stage routines.
-///
-/// Any TargetPassConfig::addXX routine may be overriden by the Target. The
-/// addPre/Post methods with empty header implementations allow injecting
-/// target-specific fixups just before or after major stages. Additionally,
-/// targets have the flexibility to change pass order within a stage by
-/// overriding default implementation of add%Stage routines below. Each
-/// technique has maintainability tradeoffs because alternate pass orders are
-/// not well supported. addPre/Post works better if the target pass is easily
-/// tied to a common pass. But if it has subtle dependencies on multiple passes,
-/// the target should override the stage instead.
-///
-/// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
-/// before/after any target-independent pass. But it's currently overkill.
-void TargetPassConfig::addMachinePasses() {
- AddingMachinePasses = true;
-
- // Insert a machine instr printer pass after the specified pass.
- // If -print-machineinstrs specified, print machineinstrs after all passes.
- if (StringRef(PrintMachineInstrs.getValue()).equals(""))
- TM->Options.PrintMachineCode = true;
- else if (!StringRef(PrintMachineInstrs.getValue())
- .equals("option-unspecified")) {
- const PassRegistry *PR = PassRegistry::getPassRegistry();
- const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue());
- const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer"));
- assert (TPI && IPI && "Pass ID not registered!");
- const char *TID = (const char *)(TPI->getTypeInfo());
- const char *IID = (const char *)(IPI->getTypeInfo());
- insertPass(TID, IID);
- }
-
- // Print the instruction selected machine code...
- printAndVerify("After Instruction Selection");
-
- // Expand pseudo-instructions emitted by ISel.
- addPass(&ExpandISelPseudosID);
-
- // Add passes that optimize machine instructions in SSA form.
- if (getOptLevel() != CodeGenOpt::None) {
- addMachineSSAOptimization();
- } else {
- // If the target requests it, assign local variables to stack slots relative
- // to one another and simplify frame index references where possible.
- addPass(&LocalStackSlotAllocationID, false);
- }
-
- // Run pre-ra passes.
- addPreRegAlloc();
-
- // Run register allocation and passes that are tightly coupled with it,
- // including phi elimination and scheduling.
- if (getOptimizeRegAlloc())
- addOptimizedRegAlloc(createRegAllocPass(true));
- else
- addFastRegAlloc(createRegAllocPass(false));
-
- // Run post-ra passes.
- addPostRegAlloc();
-
- // Insert prolog/epilog code. Eliminate abstract frame index references...
- if (getOptLevel() != CodeGenOpt::None)
- addPass(&ShrinkWrapID);
-
- addPass(&PrologEpilogCodeInserterID);
-
- /// Add passes that optimize machine instructions after register allocation.
- if (getOptLevel() != CodeGenOpt::None)
- addMachineLateOptimization();
-
- // Expand pseudo instructions before second scheduling pass.
- addPass(&ExpandPostRAPseudosID);
-
- // Run pre-sched2 passes.
- addPreSched2();
-
- if (EnableImplicitNullChecks)
- addPass(&ImplicitNullChecksID);
-
- // Second pass scheduler.
- // Let Target optionally insert this pass by itself at some other
- // point.
- if (getOptLevel() != CodeGenOpt::None &&
- !TM->targetSchedulesPostRAScheduling()) {
- if (MISchedPostRA)
- addPass(&PostMachineSchedulerID);
- else
- addPass(&PostRASchedulerID);
- }
-
- // GC
- if (addGCPasses()) {
- if (PrintGCInfo)
- addPass(createGCInfoPrinter(dbgs()), false, false);
- }
-
- // Basic block placement.
- if (getOptLevel() != CodeGenOpt::None)
- addBlockPlacement();
-
- addPreEmitPass();
-
- addPass(&FuncletLayoutID, false);
-
- addPass(&StackMapLivenessID, false);
- addPass(&LiveDebugValuesID, false);
-
- AddingMachinePasses = false;
-}
-
-/// Add passes that optimize machine instructions in SSA form.
-void TargetPassConfig::addMachineSSAOptimization() {
- // Pre-ra tail duplication.
- addPass(&EarlyTailDuplicateID);
-
- // Optimize PHIs before DCE: removing dead PHI cycles may make more
- // instructions dead.
- addPass(&OptimizePHIsID, false);
-
- // This pass merges large allocas. StackSlotColoring is a different pass
- // which merges spill slots.
- addPass(&StackColoringID, false);
-
- // If the target requests it, assign local variables to stack slots relative
- // to one another and simplify frame index references where possible.
- addPass(&LocalStackSlotAllocationID, false);
-
- // With optimization, dead code should already be eliminated. However
- // there is one known exception: lowered code for arguments that are only
- // used by tail calls, where the tail calls reuse the incoming stack
- // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
- addPass(&DeadMachineInstructionElimID);
-
- // Allow targets to insert passes that improve instruction level parallelism,
- // like if-conversion. Such passes will typically need dominator trees and
- // loop info, just like LICM and CSE below.
- addILPOpts();
-
- addPass(&MachineLICMID, false);
- addPass(&MachineCSEID, false);
- addPass(&MachineSinkingID);
-
- addPass(&PeepholeOptimizerID);
- // Clean-up the dead code that may have been generated by peephole
- // rewriting.
- addPass(&DeadMachineInstructionElimID);
-}
-
-//===---------------------------------------------------------------------===//
-/// Register Allocation Pass Configuration
-//===---------------------------------------------------------------------===//
-
-bool TargetPassConfig::getOptimizeRegAlloc() const {
- switch (OptimizeRegAlloc) {
- case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
- case cl::BOU_TRUE: return true;
- case cl::BOU_FALSE: return false;
- }
- llvm_unreachable("Invalid optimize-regalloc state");
-}
-
-/// RegisterRegAlloc's global Registry tracks allocator registration.
-MachinePassRegistry RegisterRegAlloc::Registry;
-
-/// A dummy default pass factory indicates whether the register allocator is
-/// overridden on the command line.
-static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
-static RegisterRegAlloc
-defaultRegAlloc("default",
- "pick register allocator based on -O option",
- useDefaultRegisterAllocator);
-
-/// -regalloc=... command line option.
-static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
- RegisterPassParser<RegisterRegAlloc> >
-RegAlloc("regalloc",
- cl::init(&useDefaultRegisterAllocator),
- cl::desc("Register allocator to use"));
-
-
-/// Instantiate the default register allocator pass for this target for either
-/// the optimized or unoptimized allocation path. This will be added to the pass
-/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
-/// in the optimized case.
-///
-/// A target that uses the standard regalloc pass order for fast or optimized
-/// allocation may still override this for per-target regalloc
-/// selection. But -regalloc=... always takes precedence.
-FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
- if (Optimized)
- return createGreedyRegisterAllocator();
- else
- return createFastRegisterAllocator();
-}
-
-/// Find and instantiate the register allocation pass requested by this target
-/// at the current optimization level. Different register allocators are
-/// defined as separate passes because they may require different analysis.
-///
-/// This helper ensures that the regalloc= option is always available,
-/// even for targets that override the default allocator.
-///
-/// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
-/// this can be folded into addPass.
-FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
- RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
-
- // Initialize the global default.
- if (!Ctor) {
- Ctor = RegAlloc;
- RegisterRegAlloc::setDefault(RegAlloc);
- }
- if (Ctor != useDefaultRegisterAllocator)
- return Ctor();
-
- // With no -regalloc= override, ask the target for a regalloc pass.
- return createTargetRegisterAllocator(Optimized);
-}
-
-/// Return true if the default global register allocator is in use and
-/// has not be overriden on the command line with '-regalloc=...'
-bool TargetPassConfig::usingDefaultRegAlloc() const {
- return RegAlloc.getNumOccurrences() == 0;
-}
-
-/// Add the minimum set of target-independent passes that are required for
-/// register allocation. No coalescing or scheduling.
-void TargetPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
- addPass(&PHIEliminationID, false);
- addPass(&TwoAddressInstructionPassID, false);
-
- if (RegAllocPass)
- addPass(RegAllocPass);
-}
-
-/// Add standard target-independent passes that are tightly coupled with
-/// optimized register allocation, including coalescing, machine instruction
-/// scheduling, and register allocation itself.
-void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
- addPass(&ProcessImplicitDefsID, false);
-
- // LiveVariables currently requires pure SSA form.
- //
- // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
- // LiveVariables can be removed completely, and LiveIntervals can be directly
- // computed. (We still either need to regenerate kill flags after regalloc, or
- // preferably fix the scavenger to not depend on them).
- addPass(&LiveVariablesID, false);
-
- // Edge splitting is smarter with machine loop info.
- addPass(&MachineLoopInfoID, false);
- addPass(&PHIEliminationID, false);
-
- // Eventually, we want to run LiveIntervals before PHI elimination.
- if (EarlyLiveIntervals)
- addPass(&LiveIntervalsID, false);
-
- addPass(&TwoAddressInstructionPassID, false);
- addPass(&RegisterCoalescerID);
-
- // PreRA instruction scheduling.
- addPass(&MachineSchedulerID);
-
- if (RegAllocPass) {
- // Add the selected register allocation pass.
- addPass(RegAllocPass);
-
- // Allow targets to change the register assignments before rewriting.
- addPreRewrite();
-
- // Finally rewrite virtual registers.
- addPass(&VirtRegRewriterID);
-
- // Perform stack slot coloring and post-ra machine LICM.
- //
- // FIXME: Re-enable coloring with register when it's capable of adding
- // kill markers.
- addPass(&StackSlotColoringID);
-
- // Run post-ra machine LICM to hoist reloads / remats.
- //
- // FIXME: can this move into MachineLateOptimization?
- addPass(&PostRAMachineLICMID);
- }
-}
-
-//===---------------------------------------------------------------------===//
-/// Post RegAlloc Pass Configuration
-//===---------------------------------------------------------------------===//
-
-/// Add passes that optimize machine instructions after register allocation.
-void TargetPassConfig::addMachineLateOptimization() {
- // Branch folding must be run after regalloc and prolog/epilog insertion.
- addPass(&BranchFolderPassID);
-
- // Tail duplication.
- // Note that duplicating tail just increases code size and degrades
- // performance for targets that require Structured Control Flow.
- // In addition it can also make CFG irreducible. Thus we disable it.
- if (!TM->requiresStructuredCFG())
- addPass(&TailDuplicateID);
-
- // Copy propagation.
- addPass(&MachineCopyPropagationID);
-}
-
-/// Add standard GC passes.
-bool TargetPassConfig::addGCPasses() {
- addPass(&GCMachineCodeAnalysisID, false);
- return true;
-}
-
-/// Add standard basic block placement passes.
-void TargetPassConfig::addBlockPlacement() {
- if (addPass(&MachineBlockPlacementID, false)) {
- // Run a separate pass to collect block placement statistics.
- if (EnableBlockPlacementStats)
- addPass(&MachineBlockPlacementStatsID);
- }
-}
diff --git a/gnu/llvm/lib/CodeGen/SelectionDAG/Makefile b/gnu/llvm/lib/CodeGen/SelectionDAG/Makefile
deleted file mode 100644
index ea716fdaabb..00000000000
--- a/gnu/llvm/lib/CodeGen/SelectionDAG/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/CodeGen/SelectionDAG/Makefile -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMSelectionDAG
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp b/gnu/llvm/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp
deleted file mode 100644
index 00db9425684..00000000000
--- a/gnu/llvm/lib/CodeGen/SelectionDAG/TargetSelectionDAGInfo.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===-- TargetSelectionDAGInfo.cpp - SelectionDAG Info --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This implements the TargetSelectionDAGInfo class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Target/TargetSelectionDAGInfo.h"
-#include "llvm/Target/TargetMachine.h"
-using namespace llvm;
-
-TargetSelectionDAGInfo::~TargetSelectionDAGInfo() {
-}
diff --git a/gnu/llvm/lib/CodeGen/ShadowStackGC.cpp b/gnu/llvm/lib/CodeGen/ShadowStackGC.cpp
deleted file mode 100644
index b12e943eb35..00000000000
--- a/gnu/llvm/lib/CodeGen/ShadowStackGC.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- ShadowStackGC.cpp - GC support for uncooperative targets ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements lowering for the llvm.gc* intrinsics for targets that do
-// not natively support them (which includes the C backend). Note that the code
-// generated is not quite as efficient as algorithms which generate stack maps
-// to identify roots.
-//
-// This pass implements the code transformation described in this paper:
-// "Accurate Garbage Collection in an Uncooperative Environment"
-// Fergus Henderson, ISMM, 2002
-//
-// In runtime/GC/SemiSpace.cpp is a prototype runtime which is compatible with
-// ShadowStackGC.
-//
-// In order to support this particular transformation, all stack roots are
-// coallocated in the stack. This allows a fully target-independent stack map
-// while introducing only minor runtime overhead.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCs.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/IR/CallSite.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "shadowstackgc"
-
-namespace {
-class ShadowStackGC : public GCStrategy {
-public:
- ShadowStackGC();
-};
-}
-
-static GCRegistry::Add<ShadowStackGC>
- X("shadow-stack", "Very portable GC for uncooperative code generators");
-
-void llvm::linkShadowStackGC() {}
-
-ShadowStackGC::ShadowStackGC() {
- InitRoots = true;
- CustomRoots = true;
-}
diff --git a/gnu/llvm/lib/CodeGen/StackProtector.cpp b/gnu/llvm/lib/CodeGen/StackProtector.cpp
index d45d31ee0ae..89868e43aba 100644
--- a/gnu/llvm/lib/CodeGen/StackProtector.cpp
+++ b/gnu/llvm/lib/CodeGen/StackProtector.cpp
@@ -18,12 +18,13 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
@@ -89,15 +90,25 @@ bool StackProtector::runOnFunction(Function &Fn) {
getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DT = DTWP ? &DTWP->getDomTree() : nullptr;
TLI = TM->getSubtargetImpl(Fn)->getTargetLowering();
+ HasPrologue = false;
+ HasIRCheck = false;
Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size");
if (Attr.isStringAttribute() &&
Attr.getValueAsString().getAsInteger(10, SSPBufferSize))
- return false; // Invalid integer string
+ return false; // Invalid integer string
if (!RequiresStackProtector())
return false;
+ // TODO(etienneb): Functions with funclets are not correctly supported now.
+ // Do nothing if this is funclet-based personality.
+ if (Fn.hasPersonalityFn()) {
+ EHPersonality Personality = classifyEHPersonality(Fn.getPersonalityFn());
+ if (isFuncletEHPersonality(Personality))
+ return false;
+ }
+
++NumFunProtected;
return InsertStackProtectors();
}
@@ -200,11 +211,24 @@ bool StackProtector::HasAddressTaken(const Instruction *AI) {
bool StackProtector::RequiresStackProtector() {
bool Strong = false;
bool NeedsProtector = false;
+ for (const BasicBlock &BB : *F)
+ for (const Instruction &I : BB)
+ if (const CallInst *CI = dyn_cast<CallInst>(&I))
+ if (CI->getCalledFunction() ==
+ Intrinsic::getDeclaration(F->getParent(),
+ Intrinsic::stackprotector))
+ HasPrologue = true;
+
+ if (F->hasFnAttribute(Attribute::SafeStack))
+ return false;
+
if (F->hasFnAttribute(Attribute::StackProtectReq)) {
NeedsProtector = true;
Strong = true; // Use the same heuristic as strong to determine SSPLayout
} else if (F->hasFnAttribute(Attribute::StackProtectStrong))
Strong = true;
+ else if (HasPrologue)
+ NeedsProtector = true;
else if (!F->hasFnAttribute(Attribute::StackProtect))
return false;
@@ -256,104 +280,51 @@ bool StackProtector::RequiresStackProtector() {
return NeedsProtector;
}
-static bool InstructionWillNotHaveChain(const Instruction *I) {
- return !I->mayHaveSideEffects() && !I->mayReadFromMemory() &&
- isSafeToSpeculativelyExecute(I);
+/// Create a stack guard loading and populate whether SelectionDAG SSP is
+/// supported.
+static Value *getStackGuard(const TargetLoweringBase *TLI, Module *M,
+ IRBuilder<> &B,
+ bool *SupportsSelectionDAGSP = nullptr) {
+ if (Value *Guard = TLI->getIRStackGuard(B))
+ return B.CreateLoad(Guard, true, "StackGuard");
+
+ // Use SelectionDAG SSP handling, since there isn't an IR guard.
+ //
+ // This is more or less weird, since we optionally output whether we
+ // should perform a SelectionDAG SP here. The reason is that it's strictly
+ // defined as !TLI->getIRStackGuard(B), where getIRStackGuard is also
+ // mutating. There is no way to get this bit without mutating the IR, so
+ // getting this bit has to happen in this right time.
+ //
+ // We could have define a new function TLI::supportsSelectionDAGSP(), but that
+ // will put more burden on the backends' overriding work, especially when it
+ // actually conveys the same information getIRStackGuard() already gives.
+ if (SupportsSelectionDAGSP)
+ *SupportsSelectionDAGSP = true;
+ TLI->insertSSPDeclarations(*M);
+ return B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackguard));
}
-/// Identify if RI has a previous instruction in the "Tail Position" and return
-/// it. Otherwise return 0.
-///
-/// This is based off of the code in llvm::isInTailCallPosition. The difference
-/// is that it inverts the first part of llvm::isInTailCallPosition since
-/// isInTailCallPosition is checking if a call is in a tail call position, and
-/// we are searching for an unknown tail call that might be in the tail call
-/// position. Once we find the call though, the code uses the same refactored
-/// code, returnTypeIsEligibleForTailCall.
-static CallInst *FindPotentialTailCall(BasicBlock *BB, ReturnInst *RI,
- const TargetLoweringBase *TLI) {
- // Establish a reasonable upper bound on the maximum amount of instructions we
- // will look through to find a tail call.
- unsigned SearchCounter = 0;
- const unsigned MaxSearch = 4;
- bool NoInterposingChain = true;
-
- for (BasicBlock::reverse_iterator I = std::next(BB->rbegin()), E = BB->rend();
- I != E && SearchCounter < MaxSearch; ++I) {
- Instruction *Inst = &*I;
-
- // Skip over debug intrinsics and do not allow them to affect our MaxSearch
- // counter.
- if (isa<DbgInfoIntrinsic>(Inst))
- continue;
-
- // If we find a call and the following conditions are satisifed, then we
- // have found a tail call that satisfies at least the target independent
- // requirements of a tail call:
- //
- // 1. The call site has the tail marker.
- //
- // 2. The call site either will not cause the creation of a chain or if a
- // chain is necessary there are no instructions in between the callsite and
- // the call which would create an interposing chain.
- //
- // 3. The return type of the function does not impede tail call
- // optimization.
- if (CallInst *CI = dyn_cast<CallInst>(Inst)) {
- if (CI->isTailCall() &&
- (InstructionWillNotHaveChain(CI) || NoInterposingChain) &&
- returnTypeIsEligibleForTailCall(BB->getParent(), CI, RI, *TLI))
- return CI;
- }
-
- // If we did not find a call see if we have an instruction that may create
- // an interposing chain.
- NoInterposingChain =
- NoInterposingChain && InstructionWillNotHaveChain(Inst);
-
- // Increment max search.
- SearchCounter++;
- }
-
- return nullptr;
-}
-
-/// Insert code into the entry block that stores the __stack_chk_guard
+/// Insert code into the entry block that stores the stack guard
/// variable onto the stack:
///
/// entry:
/// StackGuardSlot = alloca i8*
-/// StackGuard = load __stack_chk_guard
-/// call void @llvm.stackprotect.create(StackGuard, StackGuardSlot)
+/// StackGuard = <stack guard>
+/// call void @llvm.stackprotector(StackGuard, StackGuardSlot)
///
/// Returns true if the platform/triple supports the stackprotectorcreate pseudo
/// node.
static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI,
- const TargetLoweringBase *TLI, const Triple &TT,
- AllocaInst *&AI, Value *&StackGuardVar) {
+ const TargetLoweringBase *TLI, AllocaInst *&AI) {
bool SupportsSelectionDAGSP = false;
- PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
- unsigned AddressSpace, Offset;
- if (TLI->getStackCookieLocation(AddressSpace, Offset)) {
- Constant *OffsetVal =
- ConstantInt::get(Type::getInt32Ty(RI->getContext()), Offset);
-
- StackGuardVar =
- ConstantExpr::getIntToPtr(OffsetVal, PointerType::get(PtrTy,
- AddressSpace));
- } else if (TT.isOSOpenBSD())
- StackGuardVar = M->getOrInsertGlobal("__guard_local", PtrTy);
- else {
- SupportsSelectionDAGSP = true;
- StackGuardVar = M->getOrInsertGlobal("__stack_chk_guard", PtrTy);
- }
-
IRBuilder<> B(&F->getEntryBlock().front());
+ PointerType *PtrTy = Type::getInt8PtrTy(RI->getContext());
AI = B.CreateAlloca(PtrTy, nullptr, "StackGuardSlot");
- LoadInst *LI = B.CreateLoad(StackGuardVar, "StackGuard");
- B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
- {LI, AI});
+ Value *GuardSlot = getStackGuard(TLI, M, B, &SupportsSelectionDAGSP);
+ B.CreateCall(Intrinsic::getDeclaration(M, Intrinsic::stackprotector),
+ {GuardSlot, AI});
return SupportsSelectionDAGSP;
}
@@ -364,11 +335,9 @@ static bool CreatePrologue(Function *F, Module *M, ReturnInst *RI,
/// - The epilogue checks the value stored in the prologue against the original
/// value. It calls __stack_chk_fail if they differ.
bool StackProtector::InsertStackProtectors() {
- bool HasPrologue = false;
bool SupportsSelectionDAGSP =
EnableSelectionDAGSP && !TM->Options.EnableFastISel;
AllocaInst *AI = nullptr; // Place on stack that stores the stack guard.
- Value *StackGuardVar = nullptr; // The stack guard variable.
for (Function::iterator I = F->begin(), E = F->end(); I != E;) {
BasicBlock *BB = &*I++;
@@ -376,30 +345,36 @@ bool StackProtector::InsertStackProtectors() {
if (!RI)
continue;
+ // Generate prologue instrumentation if not already generated.
if (!HasPrologue) {
HasPrologue = true;
- SupportsSelectionDAGSP &=
- CreatePrologue(F, M, RI, TLI, Trip, AI, StackGuardVar);
+ SupportsSelectionDAGSP &= CreatePrologue(F, M, RI, TLI, AI);
}
- if (SupportsSelectionDAGSP) {
- // Since we have a potential tail call, insert the special stack check
- // intrinsic.
- Instruction *InsertionPt = nullptr;
- if (CallInst *CI = FindPotentialTailCall(BB, RI, TLI)) {
- InsertionPt = CI;
- } else {
- InsertionPt = RI;
- // At this point we know that BB has a return statement so it *DOES*
- // have a terminator.
- assert(InsertionPt != nullptr &&
- "BB must have a terminator instruction at this point.");
- }
-
- Function *Intrinsic =
- Intrinsic::getDeclaration(M, Intrinsic::stackprotectorcheck);
- CallInst::Create(Intrinsic, StackGuardVar, "", InsertionPt);
+ // SelectionDAG based code generation. Nothing else needs to be done here.
+ // The epilogue instrumentation is postponed to SelectionDAG.
+ if (SupportsSelectionDAGSP)
+ break;
+
+ // Set HasIRCheck to true, so that SelectionDAG will not generate its own
+ // version. SelectionDAG called 'shouldEmitSDCheck' to check whether
+ // instrumentation has already been generated.
+ HasIRCheck = true;
+
+ // Generate epilogue instrumentation. The epilogue intrumentation can be
+ // function-based or inlined depending on which mechanism the target is
+ // providing.
+ if (Value* GuardCheck = TLI->getSSPStackGuardCheck(*M)) {
+ // Generate the function-based epilogue instrumentation.
+ // The target provides a guard check function, generate a call to it.
+ IRBuilder<> B(RI);
+ LoadInst *Guard = B.CreateLoad(AI, true, "Guard");
+ CallInst *Call = B.CreateCall(GuardCheck, {Guard});
+ llvm::Function *Function = cast<llvm::Function>(GuardCheck);
+ Call->setAttributes(Function->getAttributes());
+ Call->setCallingConv(Function->getCallingConv());
} else {
+ // Generate the epilogue with inline instrumentation.
// If we do not support SelectionDAG based tail calls, generate IR level
// tail calls.
//
@@ -413,7 +388,7 @@ bool StackProtector::InsertStackProtectors() {
//
// return:
// ...
- // %1 = load __stack_chk_guard
+ // %1 = <stack guard>
// %2 = load StackGuardSlot
// %3 = cmp i1 %1, %2
// br i1 %3, label %SP_return, label %CallStackCheckFailBlk
@@ -448,9 +423,9 @@ bool StackProtector::InsertStackProtectors() {
// Generate the stack protector instructions in the old basic block.
IRBuilder<> B(BB);
- LoadInst *LI1 = B.CreateLoad(StackGuardVar);
- LoadInst *LI2 = B.CreateLoad(AI);
- Value *Cmp = B.CreateICmpEQ(LI1, LI2);
+ Value *Guard = getStackGuard(TLI, M, B);
+ LoadInst *LI2 = B.CreateLoad(AI, true);
+ Value *Cmp = B.CreateICmpEQ(Guard, LI2);
auto SuccessProb =
BranchProbabilityInfo::getBranchProbStackProtector(true);
auto FailureProb =
@@ -473,6 +448,7 @@ BasicBlock *StackProtector::CreateFailBB() {
LLVMContext &Context = F->getContext();
BasicBlock *FailBB = BasicBlock::Create(Context, "CallStackCheckFailBlk", F);
IRBuilder<> B(FailBB);
+ B.SetCurrentDebugLocation(DebugLoc::get(0, 0, F->getSubprogram()));
if (Trip.isOSOpenBSD()) {
Constant *StackChkFail =
M->getOrInsertFunction("__stack_smash_handler",
@@ -489,3 +465,7 @@ BasicBlock *StackProtector::CreateFailBB() {
B.CreateUnreachable();
return FailBB;
}
+
+bool StackProtector::shouldEmitSDCheck(const BasicBlock &BB) const {
+ return HasPrologue && !HasIRCheck && dyn_cast<ReturnInst>(BB.getTerminator());
+}
diff --git a/gnu/llvm/lib/CodeGen/StatepointExampleGC.cpp b/gnu/llvm/lib/CodeGen/StatepointExampleGC.cpp
deleted file mode 100644
index 3f60e18fafa..00000000000
--- a/gnu/llvm/lib/CodeGen/StatepointExampleGC.cpp
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- StatepointDefaultGC.cpp - The default statepoint GC strategy ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains a GCStrategy which serves as an example for the usage
-// of a statepoint based lowering strategy. This GCStrategy is intended to
-// suitable as a default implementation usable with any collector which can
-// consume the standard stackmap format generated by statepoints, uses the
-// default addrespace to distinguish between gc managed and non-gc managed
-// pointers, and has reasonable relocation semantics.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/GCStrategy.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Value.h"
-
-using namespace llvm;
-
-namespace {
-class StatepointGC : public GCStrategy {
-public:
- StatepointGC() {
- UseStatepoints = true;
- // These options are all gc.root specific, we specify them so that the
- // gc.root lowering code doesn't run.
- InitRoots = false;
- NeededSafePoints = 0;
- UsesMetadata = false;
- CustomRoots = false;
- }
- Optional<bool> isGCManagedPointer(const Type *Ty) const override {
- // Method is only valid on pointer typed values.
- const PointerType *PT = cast<PointerType>(Ty);
- // For the sake of this example GC, we arbitrarily pick addrspace(1) as our
- // GC managed heap. We know that a pointer into this heap needs to be
- // updated and that no other pointer does. Note that addrspace(1) is used
- // only as an example, it has no special meaning, and is not reserved for
- // GC usage.
- return (1 == PT->getAddressSpace());
- }
-};
-}
-
-static GCRegistry::Add<StatepointGC> X("statepoint-example",
- "an example strategy for statepoint");
-
-namespace llvm {
-void linkStatepointExampleGC() {}
-}
diff --git a/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp b/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp
index 36a31c9d646..8ca2bf9e86d 100644
--- a/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp
+++ b/gnu/llvm/lib/CodeGen/TargetLoweringBase.cpp
@@ -28,6 +28,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
@@ -43,6 +44,17 @@ static cl::opt<bool> JumpIsExpensiveOverride(
cl::desc("Do not create extra branches to split comparison logic."),
cl::Hidden);
+// Although this default value is arbitrary, it is not random. It is assumed
+// that a condition that evaluates the same way by a higher percentage than this
+// is best represented as control flow. Therefore, the default value N should be
+// set such that the win from N% correct executions is greater than the loss
+// from (100 - N)% mispredicted executions for the majority of intended targets.
+static cl::opt<int> MinPercentageForPredictableBranch(
+ "min-predictable-branch", cl::init(99),
+ cl::desc("Minimum percentage (0-100) that a condition must be either true "
+ "or false to assume that the condition is predictable"),
+ cl::Hidden);
+
/// InitLibcallNames - Set default libcall names.
///
static void InitLibcallNames(const char **Names, const Triple &TT) {
@@ -87,18 +99,6 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::UREM_I64] = "__umoddi3";
Names[RTLIB::UREM_I128] = "__umodti3";
- // These are generally not available.
- Names[RTLIB::SDIVREM_I8] = nullptr;
- Names[RTLIB::SDIVREM_I16] = nullptr;
- Names[RTLIB::SDIVREM_I32] = nullptr;
- Names[RTLIB::SDIVREM_I64] = nullptr;
- Names[RTLIB::SDIVREM_I128] = nullptr;
- Names[RTLIB::UDIVREM_I8] = nullptr;
- Names[RTLIB::UDIVREM_I16] = nullptr;
- Names[RTLIB::UDIVREM_I32] = nullptr;
- Names[RTLIB::UDIVREM_I64] = nullptr;
- Names[RTLIB::UDIVREM_I128] = nullptr;
-
Names[RTLIB::NEG_I32] = "__negsi2";
Names[RTLIB::NEG_I64] = "__negdi2";
Names[RTLIB::ADD_F32] = "__addsf3";
@@ -231,11 +231,21 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::COPYSIGN_F80] = "copysignl";
Names[RTLIB::COPYSIGN_F128] = "copysignl";
Names[RTLIB::COPYSIGN_PPCF128] = "copysignl";
+ Names[RTLIB::FPEXT_F32_PPCF128] = "__gcc_stoq";
+ Names[RTLIB::FPEXT_F64_PPCF128] = "__gcc_dtoq";
Names[RTLIB::FPEXT_F64_F128] = "__extenddftf2";
Names[RTLIB::FPEXT_F32_F128] = "__extendsftf2";
Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2";
- Names[RTLIB::FPEXT_F16_F32] = "__gnu_h2f_ieee";
- Names[RTLIB::FPROUND_F32_F16] = "__gnu_f2h_ieee";
+ if (TT.isOSDarwin()) {
+ // For f16/f32 conversions, Darwin uses the standard naming scheme, instead
+ // of the gnueabi-style __gnu_*_ieee.
+ // FIXME: What about other targets?
+ Names[RTLIB::FPEXT_F16_F32] = "__extendhfsf2";
+ Names[RTLIB::FPROUND_F32_F16] = "__truncsfhf2";
+ } else {
+ Names[RTLIB::FPEXT_F16_F32] = "__gnu_h2f_ieee";
+ Names[RTLIB::FPROUND_F32_F16] = "__gnu_f2h_ieee";
+ }
Names[RTLIB::FPROUND_F64_F16] = "__truncdfhf2";
Names[RTLIB::FPROUND_F80_F16] = "__truncxfhf2";
Names[RTLIB::FPROUND_F128_F16] = "__trunctfhf2";
@@ -243,10 +253,10 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2";
Names[RTLIB::FPROUND_F80_F32] = "__truncxfsf2";
Names[RTLIB::FPROUND_F128_F32] = "__trunctfsf2";
- Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2";
+ Names[RTLIB::FPROUND_PPCF128_F32] = "__gcc_qtos";
Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
Names[RTLIB::FPROUND_F128_F64] = "__trunctfdf2";
- Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
+ Names[RTLIB::FPROUND_PPCF128_F64] = "__gcc_qtod";
Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
@@ -259,7 +269,7 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::FPTOSINT_F128_I32] = "__fixtfsi";
Names[RTLIB::FPTOSINT_F128_I64] = "__fixtfdi";
Names[RTLIB::FPTOSINT_F128_I128] = "__fixtfti";
- Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi";
+ Names[RTLIB::FPTOSINT_PPCF128_I32] = "__gcc_qtou";
Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi";
Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti";
Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi";
@@ -281,7 +291,7 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::SINTTOFP_I32_F64] = "__floatsidf";
Names[RTLIB::SINTTOFP_I32_F80] = "__floatsixf";
Names[RTLIB::SINTTOFP_I32_F128] = "__floatsitf";
- Names[RTLIB::SINTTOFP_I32_PPCF128] = "__floatsitf";
+ Names[RTLIB::SINTTOFP_I32_PPCF128] = "__gcc_itoq";
Names[RTLIB::SINTTOFP_I64_F32] = "__floatdisf";
Names[RTLIB::SINTTOFP_I64_F64] = "__floatdidf";
Names[RTLIB::SINTTOFP_I64_F80] = "__floatdixf";
@@ -296,7 +306,7 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::UINTTOFP_I32_F64] = "__floatunsidf";
Names[RTLIB::UINTTOFP_I32_F80] = "__floatunsixf";
Names[RTLIB::UINTTOFP_I32_F128] = "__floatunsitf";
- Names[RTLIB::UINTTOFP_I32_PPCF128] = "__floatunsitf";
+ Names[RTLIB::UINTTOFP_I32_PPCF128] = "__gcc_utoq";
Names[RTLIB::UINTTOFP_I64_F32] = "__floatundisf";
Names[RTLIB::UINTTOFP_I64_F64] = "__floatundidf";
Names[RTLIB::UINTTOFP_I64_F80] = "__floatundixf";
@@ -310,27 +320,35 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::OEQ_F32] = "__eqsf2";
Names[RTLIB::OEQ_F64] = "__eqdf2";
Names[RTLIB::OEQ_F128] = "__eqtf2";
+ Names[RTLIB::OEQ_PPCF128] = "__gcc_qeq";
Names[RTLIB::UNE_F32] = "__nesf2";
Names[RTLIB::UNE_F64] = "__nedf2";
Names[RTLIB::UNE_F128] = "__netf2";
+ Names[RTLIB::UNE_PPCF128] = "__gcc_qne";
Names[RTLIB::OGE_F32] = "__gesf2";
Names[RTLIB::OGE_F64] = "__gedf2";
Names[RTLIB::OGE_F128] = "__getf2";
+ Names[RTLIB::OGE_PPCF128] = "__gcc_qge";
Names[RTLIB::OLT_F32] = "__ltsf2";
Names[RTLIB::OLT_F64] = "__ltdf2";
Names[RTLIB::OLT_F128] = "__lttf2";
+ Names[RTLIB::OLT_PPCF128] = "__gcc_qlt";
Names[RTLIB::OLE_F32] = "__lesf2";
Names[RTLIB::OLE_F64] = "__ledf2";
Names[RTLIB::OLE_F128] = "__letf2";
+ Names[RTLIB::OLE_PPCF128] = "__gcc_qle";
Names[RTLIB::OGT_F32] = "__gtsf2";
Names[RTLIB::OGT_F64] = "__gtdf2";
Names[RTLIB::OGT_F128] = "__gttf2";
+ Names[RTLIB::OGT_PPCF128] = "__gcc_qgt";
Names[RTLIB::UO_F32] = "__unordsf2";
Names[RTLIB::UO_F64] = "__unorddf2";
Names[RTLIB::UO_F128] = "__unordtf2";
+ Names[RTLIB::UO_PPCF128] = "__gcc_qunord";
Names[RTLIB::O_F32] = "__unordsf2";
Names[RTLIB::O_F64] = "__unorddf2";
Names[RTLIB::O_F128] = "__unordtf2";
+ Names[RTLIB::O_PPCF128] = "__gcc_qunord";
Names[RTLIB::MEMCPY] = "memcpy";
Names[RTLIB::MEMMOVE] = "memmove";
Names[RTLIB::MEMSET] = "memset";
@@ -395,36 +413,79 @@ static void InitLibcallNames(const char **Names, const Triple &TT) {
Names[RTLIB::SYNC_FETCH_AND_UMIN_4] = "__sync_fetch_and_umin_4";
Names[RTLIB::SYNC_FETCH_AND_UMIN_8] = "__sync_fetch_and_umin_8";
Names[RTLIB::SYNC_FETCH_AND_UMIN_16] = "__sync_fetch_and_umin_16";
-
- if (TT.getEnvironment() == Triple::GNU) {
+
+ Names[RTLIB::ATOMIC_LOAD] = "__atomic_load";
+ Names[RTLIB::ATOMIC_LOAD_1] = "__atomic_load_1";
+ Names[RTLIB::ATOMIC_LOAD_2] = "__atomic_load_2";
+ Names[RTLIB::ATOMIC_LOAD_4] = "__atomic_load_4";
+ Names[RTLIB::ATOMIC_LOAD_8] = "__atomic_load_8";
+ Names[RTLIB::ATOMIC_LOAD_16] = "__atomic_load_16";
+
+ Names[RTLIB::ATOMIC_STORE] = "__atomic_store";
+ Names[RTLIB::ATOMIC_STORE_1] = "__atomic_store_1";
+ Names[RTLIB::ATOMIC_STORE_2] = "__atomic_store_2";
+ Names[RTLIB::ATOMIC_STORE_4] = "__atomic_store_4";
+ Names[RTLIB::ATOMIC_STORE_8] = "__atomic_store_8";
+ Names[RTLIB::ATOMIC_STORE_16] = "__atomic_store_16";
+
+ Names[RTLIB::ATOMIC_EXCHANGE] = "__atomic_exchange";
+ Names[RTLIB::ATOMIC_EXCHANGE_1] = "__atomic_exchange_1";
+ Names[RTLIB::ATOMIC_EXCHANGE_2] = "__atomic_exchange_2";
+ Names[RTLIB::ATOMIC_EXCHANGE_4] = "__atomic_exchange_4";
+ Names[RTLIB::ATOMIC_EXCHANGE_8] = "__atomic_exchange_8";
+ Names[RTLIB::ATOMIC_EXCHANGE_16] = "__atomic_exchange_16";
+
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE] = "__atomic_compare_exchange";
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE_1] = "__atomic_compare_exchange_1";
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE_2] = "__atomic_compare_exchange_2";
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE_4] = "__atomic_compare_exchange_4";
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE_8] = "__atomic_compare_exchange_8";
+ Names[RTLIB::ATOMIC_COMPARE_EXCHANGE_16] = "__atomic_compare_exchange_16";
+
+ Names[RTLIB::ATOMIC_FETCH_ADD_1] = "__atomic_fetch_add_1";
+ Names[RTLIB::ATOMIC_FETCH_ADD_2] = "__atomic_fetch_add_2";
+ Names[RTLIB::ATOMIC_FETCH_ADD_4] = "__atomic_fetch_add_4";
+ Names[RTLIB::ATOMIC_FETCH_ADD_8] = "__atomic_fetch_add_8";
+ Names[RTLIB::ATOMIC_FETCH_ADD_16] = "__atomic_fetch_add_16";
+ Names[RTLIB::ATOMIC_FETCH_SUB_1] = "__atomic_fetch_sub_1";
+ Names[RTLIB::ATOMIC_FETCH_SUB_2] = "__atomic_fetch_sub_2";
+ Names[RTLIB::ATOMIC_FETCH_SUB_4] = "__atomic_fetch_sub_4";
+ Names[RTLIB::ATOMIC_FETCH_SUB_8] = "__atomic_fetch_sub_8";
+ Names[RTLIB::ATOMIC_FETCH_SUB_16] = "__atomic_fetch_sub_16";
+ Names[RTLIB::ATOMIC_FETCH_AND_1] = "__atomic_fetch_and_1";
+ Names[RTLIB::ATOMIC_FETCH_AND_2] = "__atomic_fetch_and_2";
+ Names[RTLIB::ATOMIC_FETCH_AND_4] = "__atomic_fetch_and_4";
+ Names[RTLIB::ATOMIC_FETCH_AND_8] = "__atomic_fetch_and_8";
+ Names[RTLIB::ATOMIC_FETCH_AND_16] = "__atomic_fetch_and_16";
+ Names[RTLIB::ATOMIC_FETCH_OR_1] = "__atomic_fetch_or_1";
+ Names[RTLIB::ATOMIC_FETCH_OR_2] = "__atomic_fetch_or_2";
+ Names[RTLIB::ATOMIC_FETCH_OR_4] = "__atomic_fetch_or_4";
+ Names[RTLIB::ATOMIC_FETCH_OR_8] = "__atomic_fetch_or_8";
+ Names[RTLIB::ATOMIC_FETCH_OR_16] = "__atomic_fetch_or_16";
+ Names[RTLIB::ATOMIC_FETCH_XOR_1] = "__atomic_fetch_xor_1";
+ Names[RTLIB::ATOMIC_FETCH_XOR_2] = "__atomic_fetch_xor_2";
+ Names[RTLIB::ATOMIC_FETCH_XOR_4] = "__atomic_fetch_xor_4";
+ Names[RTLIB::ATOMIC_FETCH_XOR_8] = "__atomic_fetch_xor_8";
+ Names[RTLIB::ATOMIC_FETCH_XOR_16] = "__atomic_fetch_xor_16";
+ Names[RTLIB::ATOMIC_FETCH_NAND_1] = "__atomic_fetch_nand_1";
+ Names[RTLIB::ATOMIC_FETCH_NAND_2] = "__atomic_fetch_nand_2";
+ Names[RTLIB::ATOMIC_FETCH_NAND_4] = "__atomic_fetch_nand_4";
+ Names[RTLIB::ATOMIC_FETCH_NAND_8] = "__atomic_fetch_nand_8";
+ Names[RTLIB::ATOMIC_FETCH_NAND_16] = "__atomic_fetch_nand_16";
+
+ if (TT.isGNUEnvironment()) {
Names[RTLIB::SINCOS_F32] = "sincosf";
Names[RTLIB::SINCOS_F64] = "sincos";
Names[RTLIB::SINCOS_F80] = "sincosl";
Names[RTLIB::SINCOS_F128] = "sincosl";
Names[RTLIB::SINCOS_PPCF128] = "sincosl";
- } else {
- // These are generally not available.
- Names[RTLIB::SINCOS_F32] = nullptr;
- Names[RTLIB::SINCOS_F64] = nullptr;
- Names[RTLIB::SINCOS_F80] = nullptr;
- Names[RTLIB::SINCOS_F128] = nullptr;
- Names[RTLIB::SINCOS_PPCF128] = nullptr;
}
if (!TT.isOSOpenBSD()) {
Names[RTLIB::STACKPROTECTOR_CHECK_FAIL] = "__stack_chk_fail";
- } else {
- // These are generally not available.
- Names[RTLIB::STACKPROTECTOR_CHECK_FAIL] = nullptr;
}
- // For f16/f32 conversions, Darwin uses the standard naming scheme, instead
- // of the gnueabi-style __gnu_*_ieee.
- // FIXME: What about other targets?
- if (TT.isOSDarwin()) {
- Names[RTLIB::FPEXT_F16_F32] = "__extendhfsf2";
- Names[RTLIB::FPROUND_F32_F16] = "__truncsfhf2";
- }
+ Names[RTLIB::DEOPTIMIZE] = "__llvm_deoptimize";
}
/// InitLibcallCallingConvs - Set default libcall CallingConvs.
@@ -446,9 +507,13 @@ RTLIB::Libcall RTLIB::getFPEXT(EVT OpVT, EVT RetVT) {
return FPEXT_F32_F64;
if (RetVT == MVT::f128)
return FPEXT_F32_F128;
+ if (RetVT == MVT::ppcf128)
+ return FPEXT_F32_PPCF128;
} else if (OpVT == MVT::f64) {
if (RetVT == MVT::f128)
return FPEXT_F64_F128;
+ else if (RetVT == MVT::ppcf128)
+ return FPEXT_F64_PPCF128;
}
return UNKNOWN_LIBCALL;
@@ -653,7 +718,7 @@ RTLIB::Libcall RTLIB::getUINTTOFP(EVT OpVT, EVT RetVT) {
return UNKNOWN_LIBCALL;
}
-RTLIB::Libcall RTLIB::getATOMIC(unsigned Opc, MVT VT) {
+RTLIB::Libcall RTLIB::getSYNC(unsigned Opc, MVT VT) {
#define OP_TO_LIBCALL(Name, Enum) \
case Name: \
switch (VT.SimpleTy) { \
@@ -698,27 +763,35 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
CCs[RTLIB::OEQ_F32] = ISD::SETEQ;
CCs[RTLIB::OEQ_F64] = ISD::SETEQ;
CCs[RTLIB::OEQ_F128] = ISD::SETEQ;
+ CCs[RTLIB::OEQ_PPCF128] = ISD::SETEQ;
CCs[RTLIB::UNE_F32] = ISD::SETNE;
CCs[RTLIB::UNE_F64] = ISD::SETNE;
CCs[RTLIB::UNE_F128] = ISD::SETNE;
+ CCs[RTLIB::UNE_PPCF128] = ISD::SETNE;
CCs[RTLIB::OGE_F32] = ISD::SETGE;
CCs[RTLIB::OGE_F64] = ISD::SETGE;
CCs[RTLIB::OGE_F128] = ISD::SETGE;
+ CCs[RTLIB::OGE_PPCF128] = ISD::SETGE;
CCs[RTLIB::OLT_F32] = ISD::SETLT;
CCs[RTLIB::OLT_F64] = ISD::SETLT;
CCs[RTLIB::OLT_F128] = ISD::SETLT;
+ CCs[RTLIB::OLT_PPCF128] = ISD::SETLT;
CCs[RTLIB::OLE_F32] = ISD::SETLE;
CCs[RTLIB::OLE_F64] = ISD::SETLE;
CCs[RTLIB::OLE_F128] = ISD::SETLE;
+ CCs[RTLIB::OLE_PPCF128] = ISD::SETLE;
CCs[RTLIB::OGT_F32] = ISD::SETGT;
CCs[RTLIB::OGT_F64] = ISD::SETGT;
CCs[RTLIB::OGT_F128] = ISD::SETGT;
+ CCs[RTLIB::OGT_PPCF128] = ISD::SETGT;
CCs[RTLIB::UO_F32] = ISD::SETNE;
CCs[RTLIB::UO_F64] = ISD::SETNE;
CCs[RTLIB::UO_F128] = ISD::SETNE;
+ CCs[RTLIB::UO_PPCF128] = ISD::SETNE;
CCs[RTLIB::O_F32] = ISD::SETEQ;
CCs[RTLIB::O_F64] = ISD::SETEQ;
CCs[RTLIB::O_F128] = ISD::SETEQ;
+ CCs[RTLIB::O_PPCF128] = ISD::SETEQ;
}
/// NOTE: The TargetMachine owns TLOF.
@@ -752,8 +825,14 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm) : TM(tm) {
PrefLoopAlignment = 0;
GatherAllAliasesMaxDepth = 6;
MinStackArgumentAlignment = 1;
- InsertFencesForAtomic = false;
MinimumJumpTableEntries = 4;
+ // TODO: the default will be switched to 0 in the next commit, along
+ // with the Target-specific changes necessary.
+ MaxAtomicSizeInBitsSupported = 1024;
+
+ MinCmpXchgSizeInBits = 0;
+
+ std::fill(std::begin(LibcallRoutineNames), std::end(LibcallRoutineNames), nullptr);
InitLibcallNames(LibcallRoutineNames, TM.getTargetTriple());
InitCmpLibcallCCs(CmpLibcallCCs);
@@ -767,8 +846,9 @@ void TargetLoweringBase::initActions() {
memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
memset(IndexedModeActions, 0, sizeof(IndexedModeActions));
memset(CondCodeActions, 0, sizeof(CondCodeActions));
- memset(RegClassForVT, 0,MVT::LAST_VALUETYPE*sizeof(TargetRegisterClass*));
- memset(TargetDAGCombineArray, 0, array_lengthof(TargetDAGCombineArray));
+ std::fill(std::begin(RegClassForVT), std::end(RegClassForVT), nullptr);
+ std::fill(std::begin(TargetDAGCombineArray),
+ std::end(TargetDAGCombineArray), 0);
// Set default actions for various operations.
for (MVT VT : MVT::all_valuetypes()) {
@@ -803,6 +883,10 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::SMULO, VT, Expand);
setOperationAction(ISD::UMULO, VT, Expand);
+ // These default to Expand so they will be expanded to CTLZ/CTTZ by default.
+ setOperationAction(ISD::CTLZ_ZERO_UNDEF, VT, Expand);
+ setOperationAction(ISD::CTTZ_ZERO_UNDEF, VT, Expand);
+
setOperationAction(ISD::BITREVERSE, VT, Expand);
// These library functions default to expand.
@@ -816,7 +900,7 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::ZERO_EXTEND_VECTOR_INREG, VT, Expand);
}
- // For most targets @llvm.get.dynamic.area.offest just returns 0.
+ // For most targets @llvm.get.dynamic.area.offset just returns 0.
setOperationAction(ISD::GET_DYNAMIC_AREA_OFFSET, VT, Expand);
}
@@ -843,8 +927,6 @@ void TargetLoweringBase::initActions() {
setOperationAction(ISD::FEXP , VT, Expand);
setOperationAction(ISD::FEXP2, VT, Expand);
setOperationAction(ISD::FFLOOR, VT, Expand);
- setOperationAction(ISD::FMINNUM, VT, Expand);
- setOperationAction(ISD::FMAXNUM, VT, Expand);
setOperationAction(ISD::FNEARBYINT, VT, Expand);
setOperationAction(ISD::FCEIL, VT, Expand);
setOperationAction(ISD::FRINT, VT, Expand);
@@ -1090,9 +1172,10 @@ bool TargetLoweringBase::isLegalRC(const TargetRegisterClass *RC) const {
/// Replace/modify any TargetFrameIndex operands with a targte-dependent
/// sequence of memory operands that is recognized by PrologEpilogInserter.
-MachineBasicBlock*
-TargetLoweringBase::emitPatchPoint(MachineInstr *MI,
+MachineBasicBlock *
+TargetLoweringBase::emitPatchPoint(MachineInstr &InitialMI,
MachineBasicBlock *MBB) const {
+ MachineInstr *MI = &InitialMI;
MachineFunction &MF = *MI->getParent()->getParent();
MachineFrameInfo &MFI = *MF.getFrameInfo();
@@ -1151,7 +1234,7 @@ TargetLoweringBase::emitPatchPoint(MachineInstr *MI,
// Add a new memory operand for this FI.
assert(MFI.getObjectOffset(FI) != -1);
- unsigned Flags = MachineMemOperand::MOLoad;
+ auto Flags = MachineMemOperand::MOLoad;
if (MI->getOpcode() == TargetOpcode::STATEPOINT) {
Flags |= MachineMemOperand::MOStore;
Flags |= MachineMemOperand::MOVolatile;
@@ -1250,10 +1333,17 @@ void TargetLoweringBase::computeRegisterProperties(
// ppcf128 type is really two f64's.
if (!isTypeLegal(MVT::ppcf128)) {
- NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64];
- RegisterTypeForVT[MVT::ppcf128] = MVT::f64;
- TransformToType[MVT::ppcf128] = MVT::f64;
- ValueTypeActions.setTypeAction(MVT::ppcf128, TypeExpandFloat);
+ if (isTypeLegal(MVT::f64)) {
+ NumRegistersForVT[MVT::ppcf128] = 2*NumRegistersForVT[MVT::f64];
+ RegisterTypeForVT[MVT::ppcf128] = MVT::f64;
+ TransformToType[MVT::ppcf128] = MVT::f64;
+ ValueTypeActions.setTypeAction(MVT::ppcf128, TypeExpandFloat);
+ } else {
+ NumRegistersForVT[MVT::ppcf128] = NumRegistersForVT[MVT::i128];
+ RegisterTypeForVT[MVT::ppcf128] = RegisterTypeForVT[MVT::i128];
+ TransformToType[MVT::ppcf128] = MVT::i128;
+ ValueTypeActions.setTypeAction(MVT::ppcf128, TypeSoftenFloat);
+ }
}
// Decide how to handle f128. If the target does not have native f128 support,
@@ -1308,13 +1398,12 @@ void TargetLoweringBase::computeRegisterProperties(
case TypePromoteInteger: {
// Try to promote the elements of integer vectors. If no legal
// promotion was found, fall through to the widen-vector method.
- for (unsigned nVT = i + 1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
+ for (unsigned nVT = i + 1; nVT <= MVT::LAST_INTEGER_VECTOR_VALUETYPE; ++nVT) {
MVT SVT = (MVT::SimpleValueType) nVT;
// Promote vectors of integers to vectors with the same number
// of elements, with a wider element type.
- if (SVT.getVectorElementType().getSizeInBits() > EltVT.getSizeInBits()
- && SVT.getVectorNumElements() == NElts && isTypeLegal(SVT)
- && SVT.getScalarType().isInteger()) {
+ if (SVT.getVectorElementType().getSizeInBits() > EltVT.getSizeInBits() &&
+ SVT.getVectorNumElements() == NElts && isTypeLegal(SVT)) {
TransformToType[i] = SVT;
RegisterTypeForVT[i] = SVT;
NumRegistersForVT[i] = 1;
@@ -1553,6 +1642,9 @@ bool TargetLoweringBase::allowsMemoryAccess(LLVMContext &Context,
return allowsMisalignedMemoryAccesses(VT, AddrSpace, Alignment, Fast);
}
+BranchProbability TargetLoweringBase::getPredictableBranchThreshold() const {
+ return BranchProbability(MinPercentageForPredictableBranch, 100);
+}
//===----------------------------------------------------------------------===//
// TargetTransformInfo Helpers
@@ -1715,3 +1807,34 @@ bool TargetLoweringBase::isLegalAddressingMode(const DataLayout &DL,
return true;
}
+
+//===----------------------------------------------------------------------===//
+// Stack Protector
+//===----------------------------------------------------------------------===//
+
+// For OpenBSD return its special guard variable. Otherwise return nullptr,
+// so that SelectionDAG handle SSP.
+Value *TargetLoweringBase::getIRStackGuard(IRBuilder<> &IRB) const {
+ if (getTargetMachine().getTargetTriple().isOSOpenBSD()) {
+ Module &M = *IRB.GetInsertBlock()->getParent()->getParent();
+ PointerType *PtrTy = Type::getInt8PtrTy(M.getContext());
+ return M.getOrInsertGlobal("__guard_local", PtrTy);
+ }
+ return nullptr;
+}
+
+// Currently only support "standard" __stack_chk_guard.
+// TODO: add LOAD_STACK_GUARD support.
+void TargetLoweringBase::insertSSPDeclarations(Module &M) const {
+ M.getOrInsertGlobal("__stack_chk_guard", Type::getInt8PtrTy(M.getContext()));
+}
+
+// Currently only support "standard" __stack_chk_guard.
+// TODO: add LOAD_STACK_GUARD support.
+Value *TargetLoweringBase::getSDagStackGuard(const Module &M) const {
+ return M.getGlobalVariable("__stack_chk_guard", true);
+}
+
+Value *TargetLoweringBase::getSSPStackGuardCheck(const Module &M) const {
+ return nullptr;
+}
diff --git a/gnu/llvm/lib/CodeGen/module.modulemap b/gnu/llvm/lib/CodeGen/module.modulemap
deleted file mode 100644
index d4f68bcc6ee..00000000000
--- a/gnu/llvm/lib/CodeGen/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module CodeGen { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/DebugInfo/CodeView/Makefile b/gnu/llvm/lib/DebugInfo/CodeView/Makefile
deleted file mode 100644
index 70e2bd01142..00000000000
--- a/gnu/llvm/lib/DebugInfo/CodeView/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/DebugInfo/CodeView/Makefile ---------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMDebugInfoCodeView
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/DebugInfo/DWARF/Makefile b/gnu/llvm/lib/DebugInfo/DWARF/Makefile
deleted file mode 100644
index 863337353d0..00000000000
--- a/gnu/llvm/lib/DebugInfo/DWARF/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/DebugInfo/DWARF/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMDebugInfoDWARF
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/DebugInfo/DWARF/module.modulemap b/gnu/llvm/lib/DebugInfo/DWARF/module.modulemap
deleted file mode 100644
index c2f624fd4b6..00000000000
--- a/gnu/llvm/lib/DebugInfo/DWARF/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module DebugInfoDWARF { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/DebugInfo/Makefile b/gnu/llvm/lib/DebugInfo/Makefile
deleted file mode 100644
index 6072af31441..00000000000
--- a/gnu/llvm/lib/DebugInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/DebugInfo/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS := CodeView DWARF PDB Symbolize
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/DebugInfo/PDB/Makefile b/gnu/llvm/lib/DebugInfo/PDB/Makefile
deleted file mode 100644
index 444019e5a18..00000000000
--- a/gnu/llvm/lib/DebugInfo/PDB/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/DebugInfo/PDB/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMDebugInfoPDB
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/DebugInfo/Symbolize/Makefile b/gnu/llvm/lib/DebugInfo/Symbolize/Makefile
deleted file mode 100644
index 17aac939658..00000000000
--- a/gnu/llvm/lib/DebugInfo/Symbolize/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/DebugInfo/Symbolize/Makefile --------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMSymbolize
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/ExecutionEngine/IntelJITEvents/Makefile b/gnu/llvm/lib/ExecutionEngine/IntelJITEvents/Makefile
deleted file mode 100644
index dcf3126cc52..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/IntelJITEvents/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- lib/ExecutionEngine/JITProfile/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-LIBRARYNAME = LLVMIntelJITEvents
-
-include $(LEVEL)/Makefile.config
-
-SOURCES := IntelJITEventListener.cpp \
- jitprofiling.c
-CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/gnu/llvm/lib/ExecutionEngine/Interpreter/Makefile b/gnu/llvm/lib/ExecutionEngine/Interpreter/Makefile
deleted file mode 100644
index 5def1365c61..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/Interpreter/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/ExecutionEngine/Interpreter/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMInterpreter
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/ExecutionEngine/MCJIT/Makefile b/gnu/llvm/lib/ExecutionEngine/MCJIT/Makefile
deleted file mode 100644
index 967efbc0efa..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/MCJIT/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMCJIT
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/ExecutionEngine/Makefile b/gnu/llvm/lib/ExecutionEngine/Makefile
deleted file mode 100644
index e9a5b79ddf6..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- lib/ExecutionEngine/Makefile ------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = LLVMExecutionEngine
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS = Interpreter MCJIT Orc RuntimeDyld
-
-ifeq ($(USE_INTEL_JITEVENTS), 1)
-PARALLEL_DIRS += IntelJITEvents
-endif
-
-ifeq ($(USE_OPROFILE), 1)
-PARALLEL_DIRS += OProfileJIT
-endif
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/gnu/llvm/lib/ExecutionEngine/OProfileJIT/Makefile b/gnu/llvm/lib/ExecutionEngine/OProfileJIT/Makefile
deleted file mode 100644
index fd3adce26c1..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/OProfileJIT/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- lib/ExecutionEngine/OProfileJIT/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-LIBRARYNAME = LLVMOProfileJIT
-
-include $(LEVEL)/Makefile.config
-
-SOURCES += OProfileJITEventListener.cpp \
- OProfileWrapper.cpp
-CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/Makefile b/gnu/llvm/lib/ExecutionEngine/Orc/Makefile
deleted file mode 100644
index ac302348ee7..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/Orc/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/ExecutionEngine/OrcJIT/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMOrcJIT
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp
deleted file mode 100644
index 01e829f7909..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcArchitectureSupport.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===------ OrcArchSupport.cpp - Architecture specific support code -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/Triple.h"
-#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
-#include "llvm/Support/Process.h"
-#include <array>
-
-namespace llvm {
-namespace orc {
-
-void OrcX86_64::writeResolverCode(uint8_t *ResolverMem, JITReentryFn ReentryFn,
- void *CallbackMgr) {
-
- const uint8_t ResolverCode[] = {
- // resolver_entry:
- 0x55, // 0x00: pushq %rbp
- 0x48, 0x89, 0xe5, // 0x01: movq %rsp, %rbp
- 0x50, // 0x04: pushq %rax
- 0x53, // 0x05: pushq %rbx
- 0x51, // 0x06: pushq %rcx
- 0x52, // 0x07: pushq %rdx
- 0x56, // 0x08: pushq %rsi
- 0x57, // 0x09: pushq %rdi
- 0x41, 0x50, // 0x0a: pushq %r8
- 0x41, 0x51, // 0x0c: pushq %r9
- 0x41, 0x52, // 0x0e: pushq %r10
- 0x41, 0x53, // 0x10: pushq %r11
- 0x41, 0x54, // 0x12: pushq %r12
- 0x41, 0x55, // 0x14: pushq %r13
- 0x41, 0x56, // 0x16: pushq %r14
- 0x41, 0x57, // 0x18: pushq %r15
- 0x48, 0x81, 0xec, 0x08, 0x02, 0x00, 0x00, // 0x1a: subq 20, %rsp
- 0x48, 0x0f, 0xae, 0x04, 0x24, // 0x21: fxsave64 (%rsp)
- 0x48, 0x8d, 0x3d, 0x43, 0x00, 0x00, 0x00, // 0x26: leaq 67(%rip), %rdi
- 0x48, 0x8b, 0x3f, // 0x2d: movq (%rdi), %rdi
- 0x48, 0x8b, 0x75, 0x08, // 0x30: movq 8(%rbp), %rsi
- 0x48, 0x83, 0xee, 0x06, // 0x34: subq $6, %rsi
- 0x48, 0xb8, // 0x38: movabsq $0, %rax
-
- // 0x3a: JIT re-entry fn addr:
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-
- 0xff, 0xd0, // 0x42: callq *%rax
- 0x48, 0x89, 0x45, 0x08, // 0x44: movq %rax, 8(%rbp)
- 0x48, 0x0f, 0xae, 0x0c, 0x24, // 0x48: fxrstor64 (%rsp)
- 0x48, 0x81, 0xc4, 0x08, 0x02, 0x00, 0x00, // 0x4d: addq 20, %rsp
- 0x41, 0x5f, // 0x54: popq %r15
- 0x41, 0x5e, // 0x56: popq %r14
- 0x41, 0x5d, // 0x58: popq %r13
- 0x41, 0x5c, // 0x5a: popq %r12
- 0x41, 0x5b, // 0x5c: popq %r11
- 0x41, 0x5a, // 0x5e: popq %r10
- 0x41, 0x59, // 0x60: popq %r9
- 0x41, 0x58, // 0x62: popq %r8
- 0x5f, // 0x64: popq %rdi
- 0x5e, // 0x65: popq %rsi
- 0x5a, // 0x66: popq %rdx
- 0x59, // 0x67: popq %rcx
- 0x5b, // 0x68: popq %rbx
- 0x58, // 0x69: popq %rax
- 0x5d, // 0x6a: popq %rbp
- 0xc3, // 0x6b: retq
- 0x00, 0x00, 0x00, 0x00, // 0x6c: <padding>
-
- // 0x70: Callback mgr address.
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
-
- const unsigned ReentryFnAddrOffset = 0x3a;
- const unsigned CallbackMgrAddrOffset = 0x70;
-
- memcpy(ResolverMem, ResolverCode, sizeof(ResolverCode));
- memcpy(ResolverMem + ReentryFnAddrOffset, &ReentryFn, sizeof(ReentryFn));
- memcpy(ResolverMem + CallbackMgrAddrOffset, &CallbackMgr,
- sizeof(CallbackMgr));
-}
-
-void OrcX86_64::writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
- unsigned NumTrampolines) {
-
- unsigned OffsetToPtr = NumTrampolines * TrampolineSize;
-
- memcpy(TrampolineMem + OffsetToPtr, &ResolverAddr, sizeof(void*));
-
- uint64_t *Trampolines = reinterpret_cast<uint64_t*>(TrampolineMem);
- uint64_t CallIndirPCRel = 0xf1c40000000015ff;
-
- for (unsigned I = 0; I < NumTrampolines; ++I, OffsetToPtr -= TrampolineSize)
- Trampolines[I] = CallIndirPCRel | ((OffsetToPtr - 6) << 16);
-}
-
-std::error_code OrcX86_64::emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
- unsigned MinStubs,
- void *InitialPtrVal) {
- // Stub format is:
- //
- // .section __orc_stubs
- // stub1:
- // jmpq *ptr1(%rip)
- // .byte 0xC4 ; <- Invalid opcode padding.
- // .byte 0xF1
- // stub2:
- // jmpq *ptr2(%rip)
- //
- // ...
- //
- // .section __orc_ptrs
- // ptr1:
- // .quad 0x0
- // ptr2:
- // .quad 0x0
- //
- // ...
-
- const unsigned StubSize = IndirectStubsInfo::StubSize;
-
- // Emit at least MinStubs, rounded up to fill the pages allocated.
- unsigned PageSize = sys::Process::getPageSize();
- unsigned NumPages = ((MinStubs * StubSize) + (PageSize - 1)) / PageSize;
- unsigned NumStubs = (NumPages * PageSize) / StubSize;
-
- // Allocate memory for stubs and pointers in one call.
- std::error_code EC;
- auto StubsMem =
- sys::OwningMemoryBlock(
- sys::Memory::allocateMappedMemory(2 * NumPages * PageSize, nullptr,
- sys::Memory::MF_READ |
- sys::Memory::MF_WRITE,
- EC));
-
- if (EC)
- return EC;
-
- // Create separate MemoryBlocks representing the stubs and pointers.
- sys::MemoryBlock StubsBlock(StubsMem.base(), NumPages * PageSize);
- sys::MemoryBlock PtrsBlock(static_cast<char*>(StubsMem.base()) +
- NumPages * PageSize,
- NumPages * PageSize);
-
- // Populate the stubs page stubs and mark it executable.
- uint64_t *Stub = reinterpret_cast<uint64_t*>(StubsBlock.base());
- uint64_t PtrOffsetField =
- static_cast<uint64_t>(NumPages * PageSize - 6) << 16;
- for (unsigned I = 0; I < NumStubs; ++I)
- Stub[I] = 0xF1C40000000025ff | PtrOffsetField;
-
- if (auto EC = sys::Memory::protectMappedMemory(StubsBlock,
- sys::Memory::MF_READ |
- sys::Memory::MF_EXEC))
- return EC;
-
- // Initialize all pointers to point at FailureAddress.
- void **Ptr = reinterpret_cast<void**>(PtrsBlock.base());
- for (unsigned I = 0; I < NumStubs; ++I)
- Ptr[I] = InitialPtrVal;
-
- StubsInfo.NumStubs = NumStubs;
- StubsInfo.StubsMem = std::move(StubsMem);
-
- return std::error_code();
-}
-
-} // End namespace orc.
-} // End namespace llvm.
diff --git a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp b/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
deleted file mode 100644
index 956daae372d..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===-------- OrcCBindingsStack.cpp - Orc JIT stack for C bindings --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "OrcCBindingsStack.h"
-
-#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include <cstdio>
-#include <system_error>
-
-using namespace llvm;
-
-std::unique_ptr<OrcCBindingsStack::CompileCallbackMgr>
-OrcCBindingsStack::createCompileCallbackMgr(Triple T) {
- switch (T.getArch()) {
- default: return nullptr;
-
- case Triple::x86_64: {
- typedef orc::LocalJITCompileCallbackManager<orc::OrcX86_64> CCMgrT;
- return llvm::make_unique<CCMgrT>(0);
- }
- }
-}
-
-OrcCBindingsStack::IndirectStubsManagerBuilder
-OrcCBindingsStack::createIndirectStubsMgrBuilder(Triple T) {
- switch (T.getArch()) {
- default: return nullptr;
-
- case Triple::x86_64:
- return [](){
- return llvm::make_unique<
- orc::LocalIndirectStubsManager<orc::OrcX86_64>>();
- };
- }
-}
diff --git a/gnu/llvm/lib/ExecutionEngine/RuntimeDyld/Makefile b/gnu/llvm/lib/ExecutionEngine/RuntimeDyld/Makefile
deleted file mode 100644
index 5d6f26d950f..00000000000
--- a/gnu/llvm/lib/ExecutionEngine/RuntimeDyld/Makefile
+++ /dev/null
@@ -1,13 +0,0 @@
-##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMRuntimeDyld
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Fuzzer/FuzzerInterface.cpp b/gnu/llvm/lib/Fuzzer/FuzzerInterface.cpp
deleted file mode 100644
index bcd726fc08e..00000000000
--- a/gnu/llvm/lib/Fuzzer/FuzzerInterface.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- FuzzerInterface.cpp - Mutate a test input --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Parts of public interface for libFuzzer.
-//===----------------------------------------------------------------------===//
-
-
-#include "FuzzerInterface.h"
-#include "FuzzerInternal.h"
-
-namespace fuzzer {
-
-void FuzzerRandomLibc::ResetSeed(unsigned int seed) { srand(seed); }
-
-size_t FuzzerRandomLibc::Rand() { return rand(); }
-
-UserSuppliedFuzzer::UserSuppliedFuzzer(FuzzerRandomBase *Rand)
- : Rand(Rand), MD(*Rand) {}
-
-UserSuppliedFuzzer::~UserSuppliedFuzzer() {
- if (OwnRand)
- delete Rand;
-}
-
-} // namespace fuzzer.
diff --git a/gnu/llvm/lib/Fuzzer/FuzzerSanitizerOptions.cpp b/gnu/llvm/lib/Fuzzer/FuzzerSanitizerOptions.cpp
deleted file mode 100644
index b2f20dd4ddf..00000000000
--- a/gnu/llvm/lib/Fuzzer/FuzzerSanitizerOptions.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===- FuzzerSanitizerOptions.cpp - default flags for sanitizers ----------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Set default options for sanitizers while running the fuzzer.
-// Options reside in a separate file, so if we don't want to set the default
-// options we simply do not link this file in.
-// ASAN options:
-// * don't dump the coverage to disk.
-// * enable coverage by default.
-// * enable handle_abort.
-//===----------------------------------------------------------------------===//
-extern "C" const char *__asan_default_options() {
- return "coverage_pcs=0:coverage=1:handle_abort=1";
-}
diff --git a/gnu/llvm/lib/Fuzzer/pull_and_push_fuzz_corpus.sh b/gnu/llvm/lib/Fuzzer/pull_and_push_fuzz_corpus.sh
deleted file mode 100755
index 05c322c6e5b..00000000000
--- a/gnu/llvm/lib/Fuzzer/pull_and_push_fuzz_corpus.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-# A simple script to synchronise a fuzz test corpus
-# with an external git repository.
-# Usage:
-# pull_and_push_fuzz_corpus.sh DIR
-# It assumes that DIR is inside a git repo and push
-# can be done w/o typing a password.
-cd $1
-git add *
-git commit -m "fuzz test corpus"
-git pull --rebase --no-edit
-for((attempt=0; attempt<5; attempt++)); do
- echo GIT PUSH $1 ATTEMPT $attempt
- if $(git push); then break; fi
- git pull --rebase --no-edit
-done
-
diff --git a/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp b/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
deleted file mode 100644
index 59f83b57bfa..00000000000
--- a/gnu/llvm/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-// Simple test for a fuzzer.
-// The fuzzer must find the string "Hi!" preceded by a magic value.
-// Uses UserSuppliedFuzzer which ensures that the magic is present.
-#include <cstdint>
-#include <cassert>
-#include <cstdlib>
-#include <cstddef>
-#include <cstring>
-#include <iostream>
-
-#include "FuzzerInterface.h"
-
-static const uint64_t kMagic = 8860221463604ULL;
-
-class MyFuzzer : public fuzzer::UserSuppliedFuzzer {
- public:
- MyFuzzer(fuzzer::FuzzerRandomBase *Rand)
- : fuzzer::UserSuppliedFuzzer(Rand) {}
- int TargetFunction(const uint8_t *Data, size_t Size) {
- if (Size <= 10) return 0;
- if (memcmp(Data, &kMagic, sizeof(kMagic))) return 0;
- // It's hard to get here w/o advanced fuzzing techniques (e.g. cmp tracing).
- // So, we simply 'fix' the data in the custom mutator.
- if (Data[8] == 'H') {
- if (Data[9] == 'i') {
- if (Data[10] == '!') {
- std::cout << "BINGO; Found the target, exiting\n";
- exit(1);
- }
- }
- }
- return 0;
- }
- // Custom mutator.
- virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
- assert(MaxSize > sizeof(kMagic));
- if (Size < sizeof(kMagic))
- Size = sizeof(kMagic);
- // "Fix" the data, then mutate.
- memcpy(Data, &kMagic, std::min(MaxSize, sizeof(kMagic)));
- return fuzzer::UserSuppliedFuzzer::Mutate(
- Data + sizeof(kMagic), Size - sizeof(kMagic), MaxSize - sizeof(kMagic));
- }
- // No need to redefine CrossOver() here.
-};
-
-int main(int argc, char **argv) {
- fuzzer::FuzzerRandomLibc Rand(0);
- MyFuzzer F(&Rand);
- fuzzer::FuzzerDriver(argc, argv, F);
-}
diff --git a/gnu/llvm/lib/IR/FunctionInfo.cpp b/gnu/llvm/lib/IR/FunctionInfo.cpp
deleted file mode 100644
index 17a67bcf047..00000000000
--- a/gnu/llvm/lib/IR/FunctionInfo.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//===-- FunctionInfo.cpp - Function Info Index ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the function info index and summary classes for the
-// IR library.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/FunctionInfo.h"
-#include "llvm/ADT/StringMap.h"
-using namespace llvm;
-
-// Create the combined function index/summary from multiple
-// per-module instances.
-void FunctionInfoIndex::mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
- uint64_t NextModuleId) {
-
- StringRef ModPath;
- for (auto &OtherFuncInfoLists : *Other) {
- std::string FuncName = OtherFuncInfoLists.getKey();
- FunctionInfoList &List = OtherFuncInfoLists.second;
-
- // Assert that the func info list only has one entry, since we shouldn't
- // have duplicate names within a single per-module index.
- assert(List.size() == 1);
- std::unique_ptr<FunctionInfo> Info = std::move(List.front());
-
- // Skip if there was no function summary section.
- if (!Info->functionSummary())
- continue;
-
- // Add the module path string ref for this module if we haven't already
- // saved a reference to it.
- if (ModPath.empty())
- ModPath =
- addModulePath(Info->functionSummary()->modulePath(), NextModuleId);
- else
- assert(ModPath == Info->functionSummary()->modulePath() &&
- "Each module in the combined map should have a unique ID");
-
- // Note the module path string ref was copied above and is still owned by
- // the original per-module index. Reset it to the new module path
- // string reference owned by the combined index.
- Info->functionSummary()->setModulePath(ModPath);
-
- // If it is a local function, rename it.
- if (Info->functionSummary()->isLocalFunction()) {
- // Any local functions are virtually renamed when being added to the
- // combined index map, to disambiguate from other functions with
- // the same name. The symbol table created for the combined index
- // file should contain the renamed symbols.
- FuncName =
- FunctionInfoIndex::getGlobalNameForLocal(FuncName, NextModuleId);
- }
-
- // Add new function info to existing list. There may be duplicates when
- // combining FunctionMap entries, due to COMDAT functions. Any local
- // functions were virtually renamed above.
- addFunctionInfo(FuncName, std::move(Info));
- }
-}
diff --git a/gnu/llvm/lib/IR/Makefile b/gnu/llvm/lib/IR/Makefile
deleted file mode 100644
index 329cd6636e9..00000000000
--- a/gnu/llvm/lib/IR/Makefile
+++ /dev/null
@@ -1,61 +0,0 @@
-##===- lib/IR/Makefile -------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../..
-LIBRARYNAME = LLVMCore
-BUILD_ARCHIVE = 1
-
-BUILT_SOURCES = $(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen \
- $(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc \
- $(PROJ_OBJ_ROOT)/lib/IR/AttributesCompatFunc.inc
-
-include $(LEVEL)/Makefile.common
-
-GENFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Intrinsics.gen
-ATTRINCFILE:=$(PROJ_OBJ_ROOT)/include/llvm/IR/Attributes.inc
-ATTRCOMPATFUNCINCFILE:=$(PROJ_OBJ_ROOT)/lib/IR/AttributesCompatFunc.inc
-
-INTRINSICTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics.td
-INTRINSICTDS := $(wildcard $(PROJ_SRC_ROOT)/include/llvm/IR/Intrinsics*.td)
-ATTRIBUTESTD := $(PROJ_SRC_ROOT)/include/llvm/IR/Attributes.td
-ATTRCOMPATFUNCTD := $(PROJ_SRC_ROOT)/lib/IR/AttributesCompatFunc.td
-
-$(ObjDir)/Intrinsics.gen.tmp: $(ObjDir)/.dir $(INTRINSICTDS) $(LLVM_TBLGEN)
- $(Echo) Building Intrinsics.gen.tmp from Intrinsics.td
- $(Verb) $(LLVMTableGen) $(call SYSPATH, $(INTRINSICTD)) -o $(call SYSPATH, $@) -gen-intrinsic
-
-$(GENFILE): $(ObjDir)/Intrinsics.gen.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir
- $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
- $(EchoCmd) Updated Intrinsics.gen because Intrinsics.gen.tmp \
- changed significantly. )
-
-$(ObjDir)/Attributes.inc.tmp: $(ObjDir)/.dir $(ATTRIBUTESTD) $(LLVM_TBLGEN)
- $(Echo) Building Attributes.inc.tmp from $(ATTRIBUTESTD)
- $(Verb) $(LLVMTableGen) $(call SYSPATH, $(ATTRIBUTESTD)) -o $(call SYSPATH, $@) -gen-attrs
-
-$(ATTRINCFILE): $(ObjDir)/Attributes.inc.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir
- $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
- $(EchoCmd) Updated Attributes.inc because Attributes.inc.tmp \
- changed significantly. )
-
-$(ObjDir)/AttributesCompatFunc.inc.tmp: $(ObjDir)/.dir $(ATTRCOMPATFUNCTD) $(LLVM_TBLGEN)
- $(Echo) Building AttributesCompatFunc.inc.tmp from $(ATTRCOMPATFUNCTD)
- $(Verb) $(LLVMTableGen) $(call SYSPATH, $(ATTRCOMPATFUNCTD)) -o $(call SYSPATH, $@) -gen-attrs
-
-$(ATTRCOMPATFUNCINCFILE): $(ObjDir)/AttributesCompatFunc.inc.tmp $(PROJ_OBJ_ROOT)/include/llvm/IR/.dir
- $(Verb) $(CMP) -s $@ $< || ( $(CP) $< $@ && \
- $(EchoCmd) Updated AttributesCompatFunc.inc because AttributesCompatFunc.inc.tmp \
- changed significantly. )
-
-install-local:: $(GENFILE)
- $(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen
- $(Verb) $(DataInstall) $(GENFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Intrinsics.gen
-
-install-local:: $(ATTRINCFILE)
- $(Echo) Installing $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc
- $(Verb) $(DataInstall) $(ATTRINCFILE) $(DESTDIR)$(PROJ_includedir)/llvm/IR/Attributes.inc
diff --git a/gnu/llvm/lib/IR/module.modulemap b/gnu/llvm/lib/IR/module.modulemap
deleted file mode 100644
index 9698e917834..00000000000
--- a/gnu/llvm/lib/IR/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module IR { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/IRReader/Makefile b/gnu/llvm/lib/IRReader/Makefile
deleted file mode 100644
index cf6bc113542..00000000000
--- a/gnu/llvm/lib/IRReader/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/IRReader/Makefile -------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME := LLVMIRReader
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/LTO/Makefile b/gnu/llvm/lib/LTO/Makefile
deleted file mode 100644
index 55e2a5ef803..00000000000
--- a/gnu/llvm/lib/LTO/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/LTO/Makefile ------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMLTO
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/LibDriver/Makefile b/gnu/llvm/lib/LibDriver/Makefile
deleted file mode 100644
index 1c62eac9093..00000000000
--- a/gnu/llvm/lib/LibDriver/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-##===- lib/LibDriver/Makefile ------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMLibDriver
-BUILD_ARCHIVE := 1
-BUILT_SOURCES = Options.inc
-TABLEGEN_INC_FILES_COMMON = 1
-
-include $(LEVEL)/Makefile.common
-
-$(ObjDir)/Options.inc.tmp : Options.td $(LLVM_TBLGEN) $(ObjDir)/.dir
- $(Echo) "Building lib Driver Option tables with tblgen"
- $(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $<
diff --git a/gnu/llvm/lib/LineEditor/Makefile b/gnu/llvm/lib/LineEditor/Makefile
deleted file mode 100644
index c7ff6d8eaae..00000000000
--- a/gnu/llvm/lib/LineEditor/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/LineEditor/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMLineEditor
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Linker/Makefile b/gnu/llvm/lib/Linker/Makefile
deleted file mode 100644
index 19e646b7483..00000000000
--- a/gnu/llvm/lib/Linker/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Linker/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMLinker
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/MC/MCCodeGenInfo.cpp b/gnu/llvm/lib/MC/MCCodeGenInfo.cpp
deleted file mode 100644
index 347ec2cd01e..00000000000
--- a/gnu/llvm/lib/MC/MCCodeGenInfo.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===-- MCCodeGenInfo.cpp - Target CodeGen Info -----------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file tracks information about the target which can affect codegen,
-// asm parsing, and asm printing. For example, relocation model.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCCodeGenInfo.h"
-using namespace llvm;
-
-void MCCodeGenInfo::initMCCodeGenInfo(Reloc::Model RM, CodeModel::Model CM,
- CodeGenOpt::Level OL) {
- RelocationModel = RM;
- CMModel = CM;
- OptLevel = OL;
-}
diff --git a/gnu/llvm/lib/MC/MCDisassembler/Makefile b/gnu/llvm/lib/MC/MCDisassembler/Makefile
deleted file mode 100644
index 7d71cd381a7..00000000000
--- a/gnu/llvm/lib/MC/MCDisassembler/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/MC/MCDisassembler/Makefile ----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMCDisassembler
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/MC/MCParser/Makefile b/gnu/llvm/lib/MC/MCParser/Makefile
deleted file mode 100644
index 4477757657c..00000000000
--- a/gnu/llvm/lib/MC/MCParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/MC/MCParser/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMCParser
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/MC/MCSymbolizer.cpp b/gnu/llvm/lib/MC/MCSymbolizer.cpp
deleted file mode 100644
index 4080e40b3f1..00000000000
--- a/gnu/llvm/lib/MC/MCSymbolizer.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-//===-- llvm/MC/MCSymbolizer.cpp - MCSymbolizer class -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/MCSymbolizer.h"
-
-using namespace llvm;
-
-MCSymbolizer::~MCSymbolizer() {
-}
diff --git a/gnu/llvm/lib/MC/Makefile b/gnu/llvm/lib/MC/Makefile
deleted file mode 100644
index bf8b7c0e783..00000000000
--- a/gnu/llvm/lib/MC/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/MC/Makefile -------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMMC
-BUILD_ARCHIVE := 1
-PARALLEL_DIRS := MCParser MCDisassembler
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/MC/YAML.cpp b/gnu/llvm/lib/MC/YAML.cpp
deleted file mode 100644
index 067e91a26d3..00000000000
--- a/gnu/llvm/lib/MC/YAML.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-//===- YAML.cpp - YAMLIO utilities for object files -----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines utility classes for handling the YAML representation of
-// object files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/MC/YAML.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cctype>
-
-using namespace llvm;
-
-void yaml::ScalarTraits<yaml::BinaryRef>::output(
- const yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) {
- Val.writeAsHex(Out);
-}
-
-StringRef yaml::ScalarTraits<yaml::BinaryRef>::input(StringRef Scalar, void *,
- yaml::BinaryRef &Val) {
- if (Scalar.size() % 2 != 0)
- return "BinaryRef hex string must contain an even number of nybbles.";
- // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here?
- // (e.g. a caret pointing to the offending character).
- for (unsigned I = 0, N = Scalar.size(); I != N; ++I)
- if (!isxdigit(Scalar[I]))
- return "BinaryRef hex string must contain only hex digits.";
- Val = yaml::BinaryRef(Scalar);
- return StringRef();
-}
-
-void yaml::BinaryRef::writeAsBinary(raw_ostream &OS) const {
- if (!DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (unsigned I = 0, N = Data.size(); I != N; I += 2) {
- uint8_t Byte;
- StringRef((const char *)&Data[I], 2).getAsInteger(16, Byte);
- OS.write(Byte);
- }
-}
-
-void yaml::BinaryRef::writeAsHex(raw_ostream &OS) const {
- if (binary_size() == 0)
- return;
- if (DataIsHexString) {
- OS.write((const char *)Data.data(), Data.size());
- return;
- }
- for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E;
- ++I) {
- uint8_t Byte = *I;
- OS << hexdigit(Byte >> 4);
- OS << hexdigit(Byte & 0xf);
- }
-}
diff --git a/gnu/llvm/lib/Makefile b/gnu/llvm/lib/Makefile
deleted file mode 100644
index 9b76126b80a..00000000000
--- a/gnu/llvm/lib/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- lib/Makefile ----------------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ..
-
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen Target \
- ExecutionEngine Linker LTO MC Object Option DebugInfo \
- IRReader LineEditor ProfileData Passes LibDriver
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Object/COFFYAML.cpp b/gnu/llvm/lib/Object/COFFYAML.cpp
deleted file mode 100644
index 4c1fca19bf1..00000000000
--- a/gnu/llvm/lib/Object/COFFYAML.cpp
+++ /dev/null
@@ -1,503 +0,0 @@
-//===- COFFYAML.cpp - COFF YAMLIO implementation --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines classes for handling the YAML representation of COFF.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/COFFYAML.h"
-
-#define ECase(X) IO.enumCase(Value, #X, COFF::X);
-namespace llvm {
-
-namespace COFFYAML {
-Section::Section() { memset(&Header, 0, sizeof(COFF::section)); }
-Symbol::Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); }
-Object::Object() { memset(&Header, 0, sizeof(COFF::header)); }
-}
-
-namespace yaml {
-void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration(
- IO &IO, COFFYAML::COMDATType &Value) {
- IO.enumCase(Value, "0", 0);
- ECase(IMAGE_COMDAT_SELECT_NODUPLICATES);
- ECase(IMAGE_COMDAT_SELECT_ANY);
- ECase(IMAGE_COMDAT_SELECT_SAME_SIZE);
- ECase(IMAGE_COMDAT_SELECT_EXACT_MATCH);
- ECase(IMAGE_COMDAT_SELECT_ASSOCIATIVE);
- ECase(IMAGE_COMDAT_SELECT_LARGEST);
- ECase(IMAGE_COMDAT_SELECT_NEWEST);
-}
-
-void
-ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
- IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
- IO.enumCase(Value, "0", 0);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
- ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
-}
-
-void ScalarEnumerationTraits<COFFYAML::AuxSymbolType>::enumeration(
- IO &IO, COFFYAML::AuxSymbolType &Value) {
- ECase(IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF);
-}
-
-void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration(
- IO &IO, COFF::MachineTypes &Value) {
- ECase(IMAGE_FILE_MACHINE_UNKNOWN);
- ECase(IMAGE_FILE_MACHINE_AM33);
- ECase(IMAGE_FILE_MACHINE_AMD64);
- ECase(IMAGE_FILE_MACHINE_ARM);
- ECase(IMAGE_FILE_MACHINE_ARMNT);
- ECase(IMAGE_FILE_MACHINE_ARM64);
- ECase(IMAGE_FILE_MACHINE_EBC);
- ECase(IMAGE_FILE_MACHINE_I386);
- ECase(IMAGE_FILE_MACHINE_IA64);
- ECase(IMAGE_FILE_MACHINE_M32R);
- ECase(IMAGE_FILE_MACHINE_MIPS16);
- ECase(IMAGE_FILE_MACHINE_MIPSFPU);
- ECase(IMAGE_FILE_MACHINE_MIPSFPU16);
- ECase(IMAGE_FILE_MACHINE_POWERPC);
- ECase(IMAGE_FILE_MACHINE_POWERPCFP);
- ECase(IMAGE_FILE_MACHINE_R4000);
- ECase(IMAGE_FILE_MACHINE_SH3);
- ECase(IMAGE_FILE_MACHINE_SH3DSP);
- ECase(IMAGE_FILE_MACHINE_SH4);
- ECase(IMAGE_FILE_MACHINE_SH5);
- ECase(IMAGE_FILE_MACHINE_THUMB);
- ECase(IMAGE_FILE_MACHINE_WCEMIPSV2);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolBaseType>::enumeration(
- IO &IO, COFF::SymbolBaseType &Value) {
- ECase(IMAGE_SYM_TYPE_NULL);
- ECase(IMAGE_SYM_TYPE_VOID);
- ECase(IMAGE_SYM_TYPE_CHAR);
- ECase(IMAGE_SYM_TYPE_SHORT);
- ECase(IMAGE_SYM_TYPE_INT);
- ECase(IMAGE_SYM_TYPE_LONG);
- ECase(IMAGE_SYM_TYPE_FLOAT);
- ECase(IMAGE_SYM_TYPE_DOUBLE);
- ECase(IMAGE_SYM_TYPE_STRUCT);
- ECase(IMAGE_SYM_TYPE_UNION);
- ECase(IMAGE_SYM_TYPE_ENUM);
- ECase(IMAGE_SYM_TYPE_MOE);
- ECase(IMAGE_SYM_TYPE_BYTE);
- ECase(IMAGE_SYM_TYPE_WORD);
- ECase(IMAGE_SYM_TYPE_UINT);
- ECase(IMAGE_SYM_TYPE_DWORD);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolStorageClass>::enumeration(
- IO &IO, COFF::SymbolStorageClass &Value) {
- ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION);
- ECase(IMAGE_SYM_CLASS_NULL);
- ECase(IMAGE_SYM_CLASS_AUTOMATIC);
- ECase(IMAGE_SYM_CLASS_EXTERNAL);
- ECase(IMAGE_SYM_CLASS_STATIC);
- ECase(IMAGE_SYM_CLASS_REGISTER);
- ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF);
- ECase(IMAGE_SYM_CLASS_LABEL);
- ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT);
- ECase(IMAGE_SYM_CLASS_ARGUMENT);
- ECase(IMAGE_SYM_CLASS_STRUCT_TAG);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION);
- ECase(IMAGE_SYM_CLASS_UNION_TAG);
- ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION);
- ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC);
- ECase(IMAGE_SYM_CLASS_ENUM_TAG);
- ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM);
- ECase(IMAGE_SYM_CLASS_REGISTER_PARAM);
- ECase(IMAGE_SYM_CLASS_BIT_FIELD);
- ECase(IMAGE_SYM_CLASS_BLOCK);
- ECase(IMAGE_SYM_CLASS_FUNCTION);
- ECase(IMAGE_SYM_CLASS_END_OF_STRUCT);
- ECase(IMAGE_SYM_CLASS_FILE);
- ECase(IMAGE_SYM_CLASS_SECTION);
- ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL);
- ECase(IMAGE_SYM_CLASS_CLR_TOKEN);
-}
-
-void ScalarEnumerationTraits<COFF::SymbolComplexType>::enumeration(
- IO &IO, COFF::SymbolComplexType &Value) {
- ECase(IMAGE_SYM_DTYPE_NULL);
- ECase(IMAGE_SYM_DTYPE_POINTER);
- ECase(IMAGE_SYM_DTYPE_FUNCTION);
- ECase(IMAGE_SYM_DTYPE_ARRAY);
-}
-
-void ScalarEnumerationTraits<COFF::RelocationTypeI386>::enumeration(
- IO &IO, COFF::RelocationTypeI386 &Value) {
- ECase(IMAGE_REL_I386_ABSOLUTE);
- ECase(IMAGE_REL_I386_DIR16);
- ECase(IMAGE_REL_I386_REL16);
- ECase(IMAGE_REL_I386_DIR32);
- ECase(IMAGE_REL_I386_DIR32NB);
- ECase(IMAGE_REL_I386_SEG12);
- ECase(IMAGE_REL_I386_SECTION);
- ECase(IMAGE_REL_I386_SECREL);
- ECase(IMAGE_REL_I386_TOKEN);
- ECase(IMAGE_REL_I386_SECREL7);
- ECase(IMAGE_REL_I386_REL32);
-}
-
-void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration(
- IO &IO, COFF::RelocationTypeAMD64 &Value) {
- ECase(IMAGE_REL_AMD64_ABSOLUTE);
- ECase(IMAGE_REL_AMD64_ADDR64);
- ECase(IMAGE_REL_AMD64_ADDR32);
- ECase(IMAGE_REL_AMD64_ADDR32NB);
- ECase(IMAGE_REL_AMD64_REL32);
- ECase(IMAGE_REL_AMD64_REL32_1);
- ECase(IMAGE_REL_AMD64_REL32_2);
- ECase(IMAGE_REL_AMD64_REL32_3);
- ECase(IMAGE_REL_AMD64_REL32_4);
- ECase(IMAGE_REL_AMD64_REL32_5);
- ECase(IMAGE_REL_AMD64_SECTION);
- ECase(IMAGE_REL_AMD64_SECREL);
- ECase(IMAGE_REL_AMD64_SECREL7);
- ECase(IMAGE_REL_AMD64_TOKEN);
- ECase(IMAGE_REL_AMD64_SREL32);
- ECase(IMAGE_REL_AMD64_PAIR);
- ECase(IMAGE_REL_AMD64_SSPAN32);
-}
-
-void ScalarEnumerationTraits<COFF::WindowsSubsystem>::enumeration(
- IO &IO, COFF::WindowsSubsystem &Value) {
- ECase(IMAGE_SUBSYSTEM_UNKNOWN);
- ECase(IMAGE_SUBSYSTEM_NATIVE);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_GUI);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_CUI);
- ECase(IMAGE_SUBSYSTEM_OS2_CUI);
- ECase(IMAGE_SUBSYSTEM_POSIX_CUI);
- ECase(IMAGE_SUBSYSTEM_NATIVE_WINDOWS);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_CE_GUI);
- ECase(IMAGE_SUBSYSTEM_EFI_APPLICATION);
- ECase(IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER);
- ECase(IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER);
- ECase(IMAGE_SUBSYSTEM_EFI_ROM);
- ECase(IMAGE_SUBSYSTEM_XBOX);
- ECase(IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION);
-}
-#undef ECase
-
-#define BCase(X) IO.bitSetCase(Value, #X, COFF::X);
-void ScalarBitSetTraits<COFF::Characteristics>::bitset(
- IO &IO, COFF::Characteristics &Value) {
- BCase(IMAGE_FILE_RELOCS_STRIPPED);
- BCase(IMAGE_FILE_EXECUTABLE_IMAGE);
- BCase(IMAGE_FILE_LINE_NUMS_STRIPPED);
- BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED);
- BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM);
- BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE);
- BCase(IMAGE_FILE_BYTES_REVERSED_LO);
- BCase(IMAGE_FILE_32BIT_MACHINE);
- BCase(IMAGE_FILE_DEBUG_STRIPPED);
- BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP);
- BCase(IMAGE_FILE_NET_RUN_FROM_SWAP);
- BCase(IMAGE_FILE_SYSTEM);
- BCase(IMAGE_FILE_DLL);
- BCase(IMAGE_FILE_UP_SYSTEM_ONLY);
- BCase(IMAGE_FILE_BYTES_REVERSED_HI);
-}
-
-void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset(
- IO &IO, COFF::SectionCharacteristics &Value) {
- BCase(IMAGE_SCN_TYPE_NOLOAD);
- BCase(IMAGE_SCN_TYPE_NO_PAD);
- BCase(IMAGE_SCN_CNT_CODE);
- BCase(IMAGE_SCN_CNT_INITIALIZED_DATA);
- BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA);
- BCase(IMAGE_SCN_LNK_OTHER);
- BCase(IMAGE_SCN_LNK_INFO);
- BCase(IMAGE_SCN_LNK_REMOVE);
- BCase(IMAGE_SCN_LNK_COMDAT);
- BCase(IMAGE_SCN_GPREL);
- BCase(IMAGE_SCN_MEM_PURGEABLE);
- BCase(IMAGE_SCN_MEM_16BIT);
- BCase(IMAGE_SCN_MEM_LOCKED);
- BCase(IMAGE_SCN_MEM_PRELOAD);
- BCase(IMAGE_SCN_LNK_NRELOC_OVFL);
- BCase(IMAGE_SCN_MEM_DISCARDABLE);
- BCase(IMAGE_SCN_MEM_NOT_CACHED);
- BCase(IMAGE_SCN_MEM_NOT_PAGED);
- BCase(IMAGE_SCN_MEM_SHARED);
- BCase(IMAGE_SCN_MEM_EXECUTE);
- BCase(IMAGE_SCN_MEM_READ);
- BCase(IMAGE_SCN_MEM_WRITE);
-}
-
-void ScalarBitSetTraits<COFF::DLLCharacteristics>::bitset(
- IO &IO, COFF::DLLCharacteristics &Value) {
- BCase(IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA);
- BCase(IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE);
- BCase(IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY);
- BCase(IMAGE_DLL_CHARACTERISTICS_NX_COMPAT);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_SEH);
- BCase(IMAGE_DLL_CHARACTERISTICS_NO_BIND);
- BCase(IMAGE_DLL_CHARACTERISTICS_APPCONTAINER);
- BCase(IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER);
- BCase(IMAGE_DLL_CHARACTERISTICS_GUARD_CF);
- BCase(IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE);
-}
-#undef BCase
-
-namespace {
-struct NSectionSelectionType {
- NSectionSelectionType(IO &)
- : SelectionType(COFFYAML::COMDATType(0)) {}
- NSectionSelectionType(IO &, uint8_t C)
- : SelectionType(COFFYAML::COMDATType(C)) {}
- uint8_t denormalize(IO &) { return SelectionType; }
- COFFYAML::COMDATType SelectionType;
-};
-
-struct NWeakExternalCharacteristics {
- NWeakExternalCharacteristics(IO &)
- : Characteristics(COFFYAML::WeakExternalCharacteristics(0)) {}
- NWeakExternalCharacteristics(IO &, uint32_t C)
- : Characteristics(COFFYAML::WeakExternalCharacteristics(C)) {}
- uint32_t denormalize(IO &) { return Characteristics; }
- COFFYAML::WeakExternalCharacteristics Characteristics;
-};
-
-struct NSectionCharacteristics {
- NSectionCharacteristics(IO &)
- : Characteristics(COFF::SectionCharacteristics(0)) {}
- NSectionCharacteristics(IO &, uint32_t C)
- : Characteristics(COFF::SectionCharacteristics(C)) {}
- uint32_t denormalize(IO &) { return Characteristics; }
- COFF::SectionCharacteristics Characteristics;
-};
-
-struct NAuxTokenType {
- NAuxTokenType(IO &)
- : AuxType(COFFYAML::AuxSymbolType(0)) {}
- NAuxTokenType(IO &, uint8_t C)
- : AuxType(COFFYAML::AuxSymbolType(C)) {}
- uint32_t denormalize(IO &) { return AuxType; }
- COFFYAML::AuxSymbolType AuxType;
-};
-
-struct NStorageClass {
- NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {}
- NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {}
- uint8_t denormalize(IO &) { return StorageClass; }
-
- COFF::SymbolStorageClass StorageClass;
-};
-
-struct NMachine {
- NMachine(IO &) : Machine(COFF::MachineTypes(0)) {}
- NMachine(IO &, uint16_t M) : Machine(COFF::MachineTypes(M)) {}
- uint16_t denormalize(IO &) { return Machine; }
- COFF::MachineTypes Machine;
-};
-
-struct NHeaderCharacteristics {
- NHeaderCharacteristics(IO &) : Characteristics(COFF::Characteristics(0)) {}
- NHeaderCharacteristics(IO &, uint16_t C)
- : Characteristics(COFF::Characteristics(C)) {}
- uint16_t denormalize(IO &) { return Characteristics; }
-
- COFF::Characteristics Characteristics;
-};
-
-template <typename RelocType>
-struct NType {
- NType(IO &) : Type(RelocType(0)) {}
- NType(IO &, uint16_t T) : Type(RelocType(T)) {}
- uint16_t denormalize(IO &) { return Type; }
- RelocType Type;
-};
-
-struct NWindowsSubsystem {
- NWindowsSubsystem(IO &) : Subsystem(COFF::WindowsSubsystem(0)) {}
- NWindowsSubsystem(IO &, uint16_t C) : Subsystem(COFF::WindowsSubsystem(C)) {}
- uint16_t denormalize(IO &) { return Subsystem; }
-
- COFF::WindowsSubsystem Subsystem;
-};
-
-struct NDLLCharacteristics {
- NDLLCharacteristics(IO &) : Characteristics(COFF::DLLCharacteristics(0)) {}
- NDLLCharacteristics(IO &, uint16_t C)
- : Characteristics(COFF::DLLCharacteristics(C)) {}
- uint16_t denormalize(IO &) { return Characteristics; }
-
- COFF::DLLCharacteristics Characteristics;
-};
-
-}
-
-void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
- COFFYAML::Relocation &Rel) {
- IO.mapRequired("VirtualAddress", Rel.VirtualAddress);
- IO.mapRequired("SymbolName", Rel.SymbolName);
-
- COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
- if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
- MappingNormalization<NType<COFF::RelocationTypeI386>, uint16_t> NT(
- IO, Rel.Type);
- IO.mapRequired("Type", NT->Type);
- } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
- MappingNormalization<NType<COFF::RelocationTypeAMD64>, uint16_t> NT(
- IO, Rel.Type);
- IO.mapRequired("Type", NT->Type);
- } else {
- IO.mapRequired("Type", Rel.Type);
- }
-}
-
-void MappingTraits<COFF::DataDirectory>::mapping(IO &IO,
- COFF::DataDirectory &DD) {
- IO.mapRequired("RelativeVirtualAddress", DD.RelativeVirtualAddress);
- IO.mapRequired("Size", DD.Size);
-}
-
-void MappingTraits<COFFYAML::PEHeader>::mapping(IO &IO,
- COFFYAML::PEHeader &PH) {
- MappingNormalization<NWindowsSubsystem, uint16_t> NWS(IO,
- PH.Header.Subsystem);
- MappingNormalization<NDLLCharacteristics, uint16_t> NDC(
- IO, PH.Header.DLLCharacteristics);
-
- IO.mapRequired("AddressOfEntryPoint", PH.Header.AddressOfEntryPoint);
- IO.mapRequired("ImageBase", PH.Header.ImageBase);
- IO.mapRequired("SectionAlignment", PH.Header.SectionAlignment);
- IO.mapRequired("FileAlignment", PH.Header.FileAlignment);
- IO.mapRequired("MajorOperatingSystemVersion",
- PH.Header.MajorOperatingSystemVersion);
- IO.mapRequired("MinorOperatingSystemVersion",
- PH.Header.MinorOperatingSystemVersion);
- IO.mapRequired("MajorImageVersion", PH.Header.MajorImageVersion);
- IO.mapRequired("MinorImageVersion", PH.Header.MinorImageVersion);
- IO.mapRequired("MajorSubsystemVersion", PH.Header.MajorSubsystemVersion);
- IO.mapRequired("MinorSubsystemVersion", PH.Header.MinorSubsystemVersion);
- IO.mapRequired("Subsystem", NWS->Subsystem);
- IO.mapRequired("DLLCharacteristics", NDC->Characteristics);
- IO.mapRequired("SizeOfStackReserve", PH.Header.SizeOfStackReserve);
- IO.mapRequired("SizeOfStackCommit", PH.Header.SizeOfStackCommit);
- IO.mapRequired("SizeOfHeapReserve", PH.Header.SizeOfHeapReserve);
- IO.mapRequired("SizeOfHeapCommit", PH.Header.SizeOfHeapCommit);
-
- IO.mapOptional("ExportTable", PH.DataDirectories[COFF::EXPORT_TABLE]);
- IO.mapOptional("ImportTable", PH.DataDirectories[COFF::IMPORT_TABLE]);
- IO.mapOptional("ResourceTable", PH.DataDirectories[COFF::RESOURCE_TABLE]);
- IO.mapOptional("ExceptionTable", PH.DataDirectories[COFF::EXCEPTION_TABLE]);
- IO.mapOptional("CertificateTable", PH.DataDirectories[COFF::CERTIFICATE_TABLE]);
- IO.mapOptional("BaseRelocationTable",
- PH.DataDirectories[COFF::BASE_RELOCATION_TABLE]);
- IO.mapOptional("Debug", PH.DataDirectories[COFF::DEBUG]);
- IO.mapOptional("Architecture", PH.DataDirectories[COFF::ARCHITECTURE]);
- IO.mapOptional("GlobalPtr", PH.DataDirectories[COFF::GLOBAL_PTR]);
- IO.mapOptional("TlsTable", PH.DataDirectories[COFF::TLS_TABLE]);
- IO.mapOptional("LoadConfigTable",
- PH.DataDirectories[COFF::LOAD_CONFIG_TABLE]);
- IO.mapOptional("BoundImport", PH.DataDirectories[COFF::BOUND_IMPORT]);
- IO.mapOptional("IAT", PH.DataDirectories[COFF::IAT]);
- IO.mapOptional("DelayImportDescriptor",
- PH.DataDirectories[COFF::DELAY_IMPORT_DESCRIPTOR]);
- IO.mapOptional("ClrRuntimeHeader",
- PH.DataDirectories[COFF::CLR_RUNTIME_HEADER]);
-}
-
-void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
- MappingNormalization<NMachine, uint16_t> NM(IO, H.Machine);
- MappingNormalization<NHeaderCharacteristics, uint16_t> NC(IO,
- H.Characteristics);
-
- IO.mapRequired("Machine", NM->Machine);
- IO.mapOptional("Characteristics", NC->Characteristics);
- IO.setContext(static_cast<void *>(&H));
-}
-
-void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
- IO &IO, COFF::AuxiliaryFunctionDefinition &AFD) {
- IO.mapRequired("TagIndex", AFD.TagIndex);
- IO.mapRequired("TotalSize", AFD.TotalSize);
- IO.mapRequired("PointerToLinenumber", AFD.PointerToLinenumber);
- IO.mapRequired("PointerToNextFunction", AFD.PointerToNextFunction);
-}
-
-void MappingTraits<COFF::AuxiliarybfAndefSymbol>::mapping(
- IO &IO, COFF::AuxiliarybfAndefSymbol &AAS) {
- IO.mapRequired("Linenumber", AAS.Linenumber);
- IO.mapRequired("PointerToNextFunction", AAS.PointerToNextFunction);
-}
-
-void MappingTraits<COFF::AuxiliaryWeakExternal>::mapping(
- IO &IO, COFF::AuxiliaryWeakExternal &AWE) {
- MappingNormalization<NWeakExternalCharacteristics, uint32_t> NWEC(
- IO, AWE.Characteristics);
- IO.mapRequired("TagIndex", AWE.TagIndex);
- IO.mapRequired("Characteristics", NWEC->Characteristics);
-}
-
-void MappingTraits<COFF::AuxiliarySectionDefinition>::mapping(
- IO &IO, COFF::AuxiliarySectionDefinition &ASD) {
- MappingNormalization<NSectionSelectionType, uint8_t> NSST(
- IO, ASD.Selection);
-
- IO.mapRequired("Length", ASD.Length);
- IO.mapRequired("NumberOfRelocations", ASD.NumberOfRelocations);
- IO.mapRequired("NumberOfLinenumbers", ASD.NumberOfLinenumbers);
- IO.mapRequired("CheckSum", ASD.CheckSum);
- IO.mapRequired("Number", ASD.Number);
- IO.mapOptional("Selection", NSST->SelectionType, COFFYAML::COMDATType(0));
-}
-
-void MappingTraits<COFF::AuxiliaryCLRToken>::mapping(
- IO &IO, COFF::AuxiliaryCLRToken &ACT) {
- MappingNormalization<NAuxTokenType, uint8_t> NATT(IO, ACT.AuxType);
- IO.mapRequired("AuxType", NATT->AuxType);
- IO.mapRequired("SymbolTableIndex", ACT.SymbolTableIndex);
-}
-
-void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) {
- MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass);
-
- IO.mapRequired("Name", S.Name);
- IO.mapRequired("Value", S.Header.Value);
- IO.mapRequired("SectionNumber", S.Header.SectionNumber);
- IO.mapRequired("SimpleType", S.SimpleType);
- IO.mapRequired("ComplexType", S.ComplexType);
- IO.mapRequired("StorageClass", NS->StorageClass);
- IO.mapOptional("FunctionDefinition", S.FunctionDefinition);
- IO.mapOptional("bfAndefSymbol", S.bfAndefSymbol);
- IO.mapOptional("WeakExternal", S.WeakExternal);
- IO.mapOptional("File", S.File, StringRef());
- IO.mapOptional("SectionDefinition", S.SectionDefinition);
- IO.mapOptional("CLRToken", S.CLRToken);
-}
-
-void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) {
- MappingNormalization<NSectionCharacteristics, uint32_t> NC(
- IO, Sec.Header.Characteristics);
- IO.mapRequired("Name", Sec.Name);
- IO.mapRequired("Characteristics", NC->Characteristics);
- IO.mapOptional("VirtualAddress", Sec.Header.VirtualAddress, 0U);
- IO.mapOptional("VirtualSize", Sec.Header.VirtualSize, 0U);
- IO.mapOptional("Alignment", Sec.Alignment);
- IO.mapRequired("SectionData", Sec.SectionData);
- IO.mapOptional("Relocations", Sec.Relocations);
-}
-
-void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) {
- IO.mapOptional("OptionalHeader", Obj.OptionalHeader);
- IO.mapRequired("header", Obj.Header);
- IO.mapRequired("sections", Obj.Sections);
- IO.mapRequired("symbols", Obj.Symbols);
-}
-
-}
-}
diff --git a/gnu/llvm/lib/Object/ELFYAML.cpp b/gnu/llvm/lib/Object/ELFYAML.cpp
deleted file mode 100644
index 4a4b2276f46..00000000000
--- a/gnu/llvm/lib/Object/ELFYAML.cpp
+++ /dev/null
@@ -1,809 +0,0 @@
-//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines classes for handling the YAML representation of ELF.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/ELFYAML.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/MipsABIFlags.h"
-
-namespace llvm {
-
-ELFYAML::Section::~Section() {}
-
-namespace yaml {
-
-void
-ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO,
- ELFYAML::ELF_ET &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(ET_NONE)
- ECase(ET_REL)
- ECase(ET_EXEC)
- ECase(ET_DYN)
- ECase(ET_CORE)
-#undef ECase
- IO.enumFallback<Hex16>(Value);
-}
-
-void
-ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO,
- ELFYAML::ELF_EM &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(EM_NONE)
- ECase(EM_M32)
- ECase(EM_SPARC)
- ECase(EM_386)
- ECase(EM_68K)
- ECase(EM_88K)
- ECase(EM_IAMCU)
- ECase(EM_860)
- ECase(EM_MIPS)
- ECase(EM_S370)
- ECase(EM_MIPS_RS3_LE)
- ECase(EM_PARISC)
- ECase(EM_VPP500)
- ECase(EM_SPARC32PLUS)
- ECase(EM_960)
- ECase(EM_PPC)
- ECase(EM_PPC64)
- ECase(EM_S390)
- ECase(EM_SPU)
- ECase(EM_V800)
- ECase(EM_FR20)
- ECase(EM_RH32)
- ECase(EM_RCE)
- ECase(EM_ARM)
- ECase(EM_ALPHA)
- ECase(EM_SH)
- ECase(EM_SPARCV9)
- ECase(EM_TRICORE)
- ECase(EM_ARC)
- ECase(EM_H8_300)
- ECase(EM_H8_300H)
- ECase(EM_H8S)
- ECase(EM_H8_500)
- ECase(EM_IA_64)
- ECase(EM_MIPS_X)
- ECase(EM_COLDFIRE)
- ECase(EM_68HC12)
- ECase(EM_MMA)
- ECase(EM_PCP)
- ECase(EM_NCPU)
- ECase(EM_NDR1)
- ECase(EM_STARCORE)
- ECase(EM_ME16)
- ECase(EM_ST100)
- ECase(EM_TINYJ)
- ECase(EM_X86_64)
- ECase(EM_PDSP)
- ECase(EM_PDP10)
- ECase(EM_PDP11)
- ECase(EM_FX66)
- ECase(EM_ST9PLUS)
- ECase(EM_ST7)
- ECase(EM_68HC16)
- ECase(EM_68HC11)
- ECase(EM_68HC08)
- ECase(EM_68HC05)
- ECase(EM_SVX)
- ECase(EM_ST19)
- ECase(EM_VAX)
- ECase(EM_CRIS)
- ECase(EM_JAVELIN)
- ECase(EM_FIREPATH)
- ECase(EM_ZSP)
- ECase(EM_MMIX)
- ECase(EM_HUANY)
- ECase(EM_PRISM)
- ECase(EM_AVR)
- ECase(EM_FR30)
- ECase(EM_D10V)
- ECase(EM_D30V)
- ECase(EM_V850)
- ECase(EM_M32R)
- ECase(EM_MN10300)
- ECase(EM_MN10200)
- ECase(EM_PJ)
- ECase(EM_OPENRISC)
- ECase(EM_ARC_COMPACT)
- ECase(EM_XTENSA)
- ECase(EM_VIDEOCORE)
- ECase(EM_TMM_GPP)
- ECase(EM_NS32K)
- ECase(EM_TPC)
- ECase(EM_SNP1K)
- ECase(EM_ST200)
- ECase(EM_IP2K)
- ECase(EM_MAX)
- ECase(EM_CR)
- ECase(EM_F2MC16)
- ECase(EM_MSP430)
- ECase(EM_BLACKFIN)
- ECase(EM_SE_C33)
- ECase(EM_SEP)
- ECase(EM_ARCA)
- ECase(EM_UNICORE)
- ECase(EM_EXCESS)
- ECase(EM_DXP)
- ECase(EM_ALTERA_NIOS2)
- ECase(EM_CRX)
- ECase(EM_XGATE)
- ECase(EM_C166)
- ECase(EM_M16C)
- ECase(EM_DSPIC30F)
- ECase(EM_CE)
- ECase(EM_M32C)
- ECase(EM_TSK3000)
- ECase(EM_RS08)
- ECase(EM_SHARC)
- ECase(EM_ECOG2)
- ECase(EM_SCORE7)
- ECase(EM_DSP24)
- ECase(EM_VIDEOCORE3)
- ECase(EM_LATTICEMICO32)
- ECase(EM_SE_C17)
- ECase(EM_TI_C6000)
- ECase(EM_TI_C2000)
- ECase(EM_TI_C5500)
- ECase(EM_MMDSP_PLUS)
- ECase(EM_CYPRESS_M8C)
- ECase(EM_R32C)
- ECase(EM_TRIMEDIA)
- ECase(EM_HEXAGON)
- ECase(EM_8051)
- ECase(EM_STXP7X)
- ECase(EM_NDS32)
- ECase(EM_ECOG1)
- ECase(EM_ECOG1X)
- ECase(EM_MAXQ30)
- ECase(EM_XIMO16)
- ECase(EM_MANIK)
- ECase(EM_CRAYNV2)
- ECase(EM_RX)
- ECase(EM_METAG)
- ECase(EM_MCST_ELBRUS)
- ECase(EM_ECOG16)
- ECase(EM_CR16)
- ECase(EM_ETPU)
- ECase(EM_SLE9X)
- ECase(EM_L10M)
- ECase(EM_K10M)
- ECase(EM_AARCH64)
- ECase(EM_AVR32)
- ECase(EM_STM8)
- ECase(EM_TILE64)
- ECase(EM_TILEPRO)
- ECase(EM_CUDA)
- ECase(EM_TILEGX)
- ECase(EM_CLOUDSHIELD)
- ECase(EM_COREA_1ST)
- ECase(EM_COREA_2ND)
- ECase(EM_ARC_COMPACT2)
- ECase(EM_OPEN8)
- ECase(EM_RL78)
- ECase(EM_VIDEOCORE5)
- ECase(EM_78KOR)
- ECase(EM_56800EX)
- ECase(EM_AMDGPU)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration(
- IO &IO, ELFYAML::ELF_ELFCLASS &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it
- // here.
- ECase(ELFCLASS32)
- ECase(ELFCLASS64)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration(
- IO &IO, ELFYAML::ELF_ELFDATA &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- // Since the semantics of ELFDATANONE is "invalid", just don't accept it
- // here.
- ECase(ELFDATA2LSB)
- ECase(ELFDATA2MSB)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
- IO &IO, ELFYAML::ELF_ELFOSABI &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(ELFOSABI_NONE)
- ECase(ELFOSABI_HPUX)
- ECase(ELFOSABI_NETBSD)
- ECase(ELFOSABI_GNU)
- ECase(ELFOSABI_GNU)
- ECase(ELFOSABI_HURD)
- ECase(ELFOSABI_SOLARIS)
- ECase(ELFOSABI_AIX)
- ECase(ELFOSABI_IRIX)
- ECase(ELFOSABI_FREEBSD)
- ECase(ELFOSABI_TRU64)
- ECase(ELFOSABI_MODESTO)
- ECase(ELFOSABI_OPENBSD)
- ECase(ELFOSABI_OPENVMS)
- ECase(ELFOSABI_NSK)
- ECase(ELFOSABI_AROS)
- ECase(ELFOSABI_FENIXOS)
- ECase(ELFOSABI_CLOUDABI)
- ECase(ELFOSABI_C6000_ELFABI)
- ECase(ELFOSABI_C6000_LINUX)
- ECase(ELFOSABI_ARM)
- ECase(ELFOSABI_STANDALONE)
-#undef ECase
-}
-
-void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
- ELFYAML::ELF_EF &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
-#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M);
- switch (Object->Header.Machine) {
- case ELF::EM_ARM:
- BCase(EF_ARM_SOFT_FLOAT)
- BCase(EF_ARM_VFP_FLOAT)
- BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK)
- BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK)
- break;
- case ELF::EM_MIPS:
- BCase(EF_MIPS_NOREORDER)
- BCase(EF_MIPS_PIC)
- BCase(EF_MIPS_CPIC)
- BCase(EF_MIPS_ABI2)
- BCase(EF_MIPS_32BITMODE)
- BCase(EF_MIPS_FP64)
- BCase(EF_MIPS_NAN2008)
- BCase(EF_MIPS_MICROMIPS)
- BCase(EF_MIPS_ARCH_ASE_M16)
- BCase(EF_MIPS_ARCH_ASE_MDMX)
- BCaseMask(EF_MIPS_ABI_O32, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_O64, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_EABI32, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_ABI_EABI64, EF_MIPS_ABI)
- BCaseMask(EF_MIPS_MACH_3900, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4010, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4100, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4650, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4120, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_4111, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_SB1, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_XLR, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON2, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_OCTEON3, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5400, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5900, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_5500, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_9000, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS2E, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS2F, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_MACH_LS3A, EF_MIPS_MACH)
- BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH)
- BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH)
- break;
- case ELF::EM_HEXAGON:
- BCase(EF_HEXAGON_MACH_V2)
- BCase(EF_HEXAGON_MACH_V3)
- BCase(EF_HEXAGON_MACH_V4)
- BCase(EF_HEXAGON_MACH_V5)
- BCase(EF_HEXAGON_ISA_V2)
- BCase(EF_HEXAGON_ISA_V3)
- BCase(EF_HEXAGON_ISA_V4)
- BCase(EF_HEXAGON_ISA_V5)
- break;
- case ELF::EM_AVR:
- BCase(EF_AVR_ARCH_AVR1)
- BCase(EF_AVR_ARCH_AVR2)
- BCase(EF_AVR_ARCH_AVR25)
- BCase(EF_AVR_ARCH_AVR3)
- BCase(EF_AVR_ARCH_AVR31)
- BCase(EF_AVR_ARCH_AVR35)
- BCase(EF_AVR_ARCH_AVR4)
- BCase(EF_AVR_ARCH_AVR51)
- BCase(EF_AVR_ARCH_AVR6)
- BCase(EF_AVR_ARCH_AVRTINY)
- BCase(EF_AVR_ARCH_XMEGA1)
- BCase(EF_AVR_ARCH_XMEGA2)
- BCase(EF_AVR_ARCH_XMEGA3)
- BCase(EF_AVR_ARCH_XMEGA4)
- BCase(EF_AVR_ARCH_XMEGA5)
- BCase(EF_AVR_ARCH_XMEGA6)
- BCase(EF_AVR_ARCH_XMEGA7)
- break;
- default:
- llvm_unreachable("Unsupported architecture");
- }
-#undef BCase
-#undef BCaseMask
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
- IO &IO, ELFYAML::ELF_SHT &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(SHT_NULL)
- ECase(SHT_PROGBITS)
- // No SHT_SYMTAB. Use the top-level `Symbols` key instead.
- // FIXME: Issue a diagnostic with this information.
- ECase(SHT_STRTAB)
- ECase(SHT_RELA)
- ECase(SHT_HASH)
- ECase(SHT_DYNAMIC)
- ECase(SHT_NOTE)
- ECase(SHT_NOBITS)
- ECase(SHT_REL)
- ECase(SHT_SHLIB)
- ECase(SHT_DYNSYM)
- ECase(SHT_INIT_ARRAY)
- ECase(SHT_FINI_ARRAY)
- ECase(SHT_PREINIT_ARRAY)
- ECase(SHT_GROUP)
- ECase(SHT_SYMTAB_SHNDX)
- ECase(SHT_LOOS)
- ECase(SHT_GNU_ATTRIBUTES)
- ECase(SHT_GNU_HASH)
- ECase(SHT_GNU_verdef)
- ECase(SHT_GNU_verneed)
- ECase(SHT_GNU_versym)
- ECase(SHT_HIOS)
- ECase(SHT_LOPROC)
- switch (Object->Header.Machine) {
- case ELF::EM_ARM:
- ECase(SHT_ARM_EXIDX)
- ECase(SHT_ARM_PREEMPTMAP)
- ECase(SHT_ARM_ATTRIBUTES)
- ECase(SHT_ARM_DEBUGOVERLAY)
- ECase(SHT_ARM_OVERLAYSECTION)
- break;
- case ELF::EM_HEXAGON:
- ECase(SHT_HEX_ORDERED)
- break;
- case ELF::EM_X86_64:
- ECase(SHT_X86_64_UNWIND)
- break;
- case ELF::EM_MIPS:
- ECase(SHT_MIPS_REGINFO)
- ECase(SHT_MIPS_OPTIONS)
- ECase(SHT_MIPS_ABIFLAGS)
- break;
- default:
- // Nothing to do.
- break;
- }
-#undef ECase
-}
-
-void ScalarBitSetTraits<ELFYAML::ELF_SHF>::bitset(IO &IO,
- ELFYAML::ELF_SHF &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
- BCase(SHF_WRITE)
- BCase(SHF_ALLOC)
- BCase(SHF_EXCLUDE)
- BCase(SHF_EXECINSTR)
- BCase(SHF_MERGE)
- BCase(SHF_STRINGS)
- BCase(SHF_INFO_LINK)
- BCase(SHF_LINK_ORDER)
- BCase(SHF_OS_NONCONFORMING)
- BCase(SHF_GROUP)
- BCase(SHF_TLS)
- switch(Object->Header.Machine) {
- case ELF::EM_AMDGPU:
- BCase(SHF_AMDGPU_HSA_GLOBAL)
- BCase(SHF_AMDGPU_HSA_READONLY)
- BCase(SHF_AMDGPU_HSA_CODE)
- BCase(SHF_AMDGPU_HSA_AGENT)
- break;
- default:
- // Nothing to do.
- break;
- }
-#undef BCase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
- IO &IO, ELFYAML::ELF_STT &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(STT_NOTYPE)
- ECase(STT_OBJECT)
- ECase(STT_FUNC)
- ECase(STT_SECTION)
- ECase(STT_FILE)
- ECase(STT_COMMON)
- ECase(STT_TLS)
- ECase(STT_GNU_IFUNC)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_STV>::enumeration(
- IO &IO, ELFYAML::ELF_STV &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(STV_DEFAULT)
- ECase(STV_INTERNAL)
- ECase(STV_HIDDEN)
- ECase(STV_PROTECTED)
-#undef ECase
-}
-
-void ScalarBitSetTraits<ELFYAML::ELF_STO>::bitset(IO &IO,
- ELFYAML::ELF_STO &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
- switch (Object->Header.Machine) {
- case ELF::EM_MIPS:
- BCase(STO_MIPS_OPTIONAL)
- BCase(STO_MIPS_PLT)
- BCase(STO_MIPS_PIC)
- BCase(STO_MIPS_MICROMIPS)
- break;
- default:
- break; // Nothing to do
- }
-#undef BCase
-#undef BCaseMask
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_RSS>::enumeration(
- IO &IO, ELFYAML::ELF_RSS &Value) {
-#define ECase(X) IO.enumCase(Value, #X, ELF::X);
- ECase(RSS_UNDEF)
- ECase(RSS_GP)
- ECase(RSS_GP0)
- ECase(RSS_LOC)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
- IO &IO, ELFYAML::ELF_REL &Value) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-#define ELF_RELOC(X, Y) IO.enumCase(Value, #X, ELF::X);
- switch (Object->Header.Machine) {
- case ELF::EM_X86_64:
-#include "llvm/Support/ELFRelocs/x86_64.def"
- break;
- case ELF::EM_MIPS:
-#include "llvm/Support/ELFRelocs/Mips.def"
- break;
- case ELF::EM_HEXAGON:
-#include "llvm/Support/ELFRelocs/Hexagon.def"
- break;
- case ELF::EM_386:
- case ELF::EM_IAMCU:
-#include "llvm/Support/ELFRelocs/i386.def"
- break;
- case ELF::EM_AARCH64:
-#include "llvm/Support/ELFRelocs/AArch64.def"
- break;
- case ELF::EM_ARM:
-#include "llvm/Support/ELFRelocs/ARM.def"
- break;
- default:
- llvm_unreachable("Unsupported architecture");
- }
-#undef ELF_RELOC
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_REG>::enumeration(
- IO &IO, ELFYAML::MIPS_AFL_REG &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
- ECase(REG_NONE)
- ECase(REG_32)
- ECase(REG_64)
- ECase(REG_128)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_ABI_FP>::enumeration(
- IO &IO, ELFYAML::MIPS_ABI_FP &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::Val_GNU_MIPS_ABI_##X);
- ECase(FP_ANY)
- ECase(FP_DOUBLE)
- ECase(FP_SINGLE)
- ECase(FP_SOFT)
- ECase(FP_OLD_64)
- ECase(FP_XX)
- ECase(FP_64)
- ECase(FP_64A)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_AFL_EXT>::enumeration(
- IO &IO, ELFYAML::MIPS_AFL_EXT &Value) {
-#define ECase(X) IO.enumCase(Value, #X, Mips::AFL_##X);
- ECase(EXT_NONE)
- ECase(EXT_XLR)
- ECase(EXT_OCTEON2)
- ECase(EXT_OCTEONP)
- ECase(EXT_LOONGSON_3A)
- ECase(EXT_OCTEON)
- ECase(EXT_5900)
- ECase(EXT_4650)
- ECase(EXT_4010)
- ECase(EXT_4100)
- ECase(EXT_3900)
- ECase(EXT_10000)
- ECase(EXT_SB1)
- ECase(EXT_4111)
- ECase(EXT_4120)
- ECase(EXT_5400)
- ECase(EXT_5500)
- ECase(EXT_LOONGSON_2E)
- ECase(EXT_LOONGSON_2F)
- ECase(EXT_OCTEON3)
-#undef ECase
-}
-
-void ScalarEnumerationTraits<ELFYAML::MIPS_ISA>::enumeration(
- IO &IO, ELFYAML::MIPS_ISA &Value) {
- IO.enumCase(Value, "MIPS1", 1);
- IO.enumCase(Value, "MIPS2", 2);
- IO.enumCase(Value, "MIPS3", 3);
- IO.enumCase(Value, "MIPS4", 4);
- IO.enumCase(Value, "MIPS5", 5);
- IO.enumCase(Value, "MIPS32", 32);
- IO.enumCase(Value, "MIPS64", 64);
-}
-
-void ScalarBitSetTraits<ELFYAML::MIPS_AFL_ASE>::bitset(
- IO &IO, ELFYAML::MIPS_AFL_ASE &Value) {
-#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_ASE_##X);
- BCase(DSP)
- BCase(DSPR2)
- BCase(EVA)
- BCase(MCU)
- BCase(MDMX)
- BCase(MIPS3D)
- BCase(MT)
- BCase(SMARTMIPS)
- BCase(VIRT)
- BCase(MSA)
- BCase(MIPS16)
- BCase(MICROMIPS)
- BCase(XPA)
-#undef BCase
-}
-
-void ScalarBitSetTraits<ELFYAML::MIPS_AFL_FLAGS1>::bitset(
- IO &IO, ELFYAML::MIPS_AFL_FLAGS1 &Value) {
-#define BCase(X) IO.bitSetCase(Value, #X, Mips::AFL_FLAGS1_##X);
- BCase(ODDSPREG)
-#undef BCase
-}
-
-void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
- ELFYAML::FileHeader &FileHdr) {
- IO.mapRequired("Class", FileHdr.Class);
- IO.mapRequired("Data", FileHdr.Data);
- IO.mapOptional("OSABI", FileHdr.OSABI, ELFYAML::ELF_ELFOSABI(0));
- IO.mapRequired("Type", FileHdr.Type);
- IO.mapRequired("Machine", FileHdr.Machine);
- IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
- IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
-}
-
-namespace {
-struct NormalizedOther {
- NormalizedOther(IO &)
- : Visibility(ELFYAML::ELF_STV(0)), Other(ELFYAML::ELF_STO(0)) {}
- NormalizedOther(IO &, uint8_t Original)
- : Visibility(Original & 0x3), Other(Original & ~0x3) {}
-
- uint8_t denormalize(IO &) { return Visibility | Other; }
-
- ELFYAML::ELF_STV Visibility;
- ELFYAML::ELF_STO Other;
-};
-}
-
-void MappingTraits<ELFYAML::Symbol>::mapping(IO &IO, ELFYAML::Symbol &Symbol) {
- IO.mapOptional("Name", Symbol.Name, StringRef());
- IO.mapOptional("Type", Symbol.Type, ELFYAML::ELF_STT(0));
- IO.mapOptional("Section", Symbol.Section, StringRef());
- IO.mapOptional("Value", Symbol.Value, Hex64(0));
- IO.mapOptional("Size", Symbol.Size, Hex64(0));
-
- MappingNormalization<NormalizedOther, uint8_t> Keys(IO, Symbol.Other);
- IO.mapOptional("Visibility", Keys->Visibility, ELFYAML::ELF_STV(0));
- IO.mapOptional("Other", Keys->Other, ELFYAML::ELF_STO(0));
-}
-
-void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
- IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols) {
- IO.mapOptional("Local", Symbols.Local);
- IO.mapOptional("Global", Symbols.Global);
- IO.mapOptional("Weak", Symbols.Weak);
-}
-
-static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
- IO.mapOptional("Name", Section.Name, StringRef());
- IO.mapRequired("Type", Section.Type);
- IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
- IO.mapOptional("Address", Section.Address, Hex64(0));
- IO.mapOptional("Link", Section.Link, StringRef());
- IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
- IO.mapOptional("Info", Section.Info, StringRef());
-}
-
-static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size()));
-}
-
-static void sectionMapping(IO &IO, ELFYAML::NoBitsSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Size", Section.Size, Hex64(0));
-}
-
-static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Relocations", Section.Relocations);
-}
-
-static void groupSectionMapping(IO &IO, ELFYAML::Group &group) {
- commonSectionMapping(IO, group);
- IO.mapRequired("Members", group.Members);
-}
-
-void MappingTraits<ELFYAML::SectionOrType>::mapping(
- IO &IO, ELFYAML::SectionOrType &sectionOrType) {
- IO.mapRequired("SectionOrType", sectionOrType.sectionNameOrType);
-}
-
-static void sectionMapping(IO &IO, ELFYAML::MipsABIFlags &Section) {
- commonSectionMapping(IO, Section);
- IO.mapOptional("Version", Section.Version, Hex16(0));
- IO.mapRequired("ISA", Section.ISALevel);
- IO.mapOptional("ISARevision", Section.ISARevision, Hex8(0));
- IO.mapOptional("ISAExtension", Section.ISAExtension,
- ELFYAML::MIPS_AFL_EXT(Mips::AFL_EXT_NONE));
- IO.mapOptional("ASEs", Section.ASEs, ELFYAML::MIPS_AFL_ASE(0));
- IO.mapOptional("FpABI", Section.FpABI,
- ELFYAML::MIPS_ABI_FP(Mips::Val_GNU_MIPS_ABI_FP_ANY));
- IO.mapOptional("GPRSize", Section.GPRSize,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("CPR1Size", Section.CPR1Size,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("CPR2Size", Section.CPR2Size,
- ELFYAML::MIPS_AFL_REG(Mips::AFL_REG_NONE));
- IO.mapOptional("Flags1", Section.Flags1, ELFYAML::MIPS_AFL_FLAGS1(0));
- IO.mapOptional("Flags2", Section.Flags2, Hex32(0));
-}
-
-void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
- IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
- ELFYAML::ELF_SHT sectionType;
- if (IO.outputting())
- sectionType = Section->Type;
- else
- IO.mapRequired("Type", sectionType);
-
- switch (sectionType) {
- case ELF::SHT_REL:
- case ELF::SHT_RELA:
- if (!IO.outputting())
- Section.reset(new ELFYAML::RelocationSection());
- sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
- break;
- case ELF::SHT_GROUP:
- if (!IO.outputting())
- Section.reset(new ELFYAML::Group());
- groupSectionMapping(IO, *cast<ELFYAML::Group>(Section.get()));
- break;
- case ELF::SHT_NOBITS:
- if (!IO.outputting())
- Section.reset(new ELFYAML::NoBitsSection());
- sectionMapping(IO, *cast<ELFYAML::NoBitsSection>(Section.get()));
- break;
- case ELF::SHT_MIPS_ABIFLAGS:
- if (!IO.outputting())
- Section.reset(new ELFYAML::MipsABIFlags());
- sectionMapping(IO, *cast<ELFYAML::MipsABIFlags>(Section.get()));
- break;
- default:
- if (!IO.outputting())
- Section.reset(new ELFYAML::RawContentSection());
- sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get()));
- }
-}
-
-StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
- IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
- const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Section.get());
- if (!RawSection || RawSection->Size >= RawSection->Content.binary_size())
- return StringRef();
- return "Section size must be greater or equal to the content size";
-}
-
-namespace {
-struct NormalizedMips64RelType {
- NormalizedMips64RelType(IO &)
- : Type(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- Type2(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- Type3(ELFYAML::ELF_REL(ELF::R_MIPS_NONE)),
- SpecSym(ELFYAML::ELF_REL(ELF::RSS_UNDEF)) {}
- NormalizedMips64RelType(IO &, ELFYAML::ELF_REL Original)
- : Type(Original & 0xFF), Type2(Original >> 8 & 0xFF),
- Type3(Original >> 16 & 0xFF), SpecSym(Original >> 24 & 0xFF) {}
-
- ELFYAML::ELF_REL denormalize(IO &) {
- ELFYAML::ELF_REL Res = Type | Type2 << 8 | Type3 << 16 | SpecSym << 24;
- return Res;
- }
-
- ELFYAML::ELF_REL Type;
- ELFYAML::ELF_REL Type2;
- ELFYAML::ELF_REL Type3;
- ELFYAML::ELF_RSS SpecSym;
-};
-}
-
-void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
- ELFYAML::Relocation &Rel) {
- const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
- assert(Object && "The IO context is not initialized");
-
- IO.mapRequired("Offset", Rel.Offset);
- IO.mapRequired("Symbol", Rel.Symbol);
-
- if (Object->Header.Machine == ELFYAML::ELF_EM(ELF::EM_MIPS) &&
- Object->Header.Class == ELFYAML::ELF_ELFCLASS(ELF::ELFCLASS64)) {
- MappingNormalization<NormalizedMips64RelType, ELFYAML::ELF_REL> Key(
- IO, Rel.Type);
- IO.mapRequired("Type", Key->Type);
- IO.mapOptional("Type2", Key->Type2, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
- IO.mapOptional("Type3", Key->Type3, ELFYAML::ELF_REL(ELF::R_MIPS_NONE));
- IO.mapOptional("SpecSym", Key->SpecSym, ELFYAML::ELF_RSS(ELF::RSS_UNDEF));
- } else
- IO.mapRequired("Type", Rel.Type);
-
- IO.mapOptional("Addend", Rel.Addend, (int64_t)0);
-}
-
-void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
- assert(!IO.getContext() && "The IO context is initialized already");
- IO.setContext(&Object);
- IO.mapRequired("FileHeader", Object.Header);
- IO.mapOptional("Sections", Object.Sections);
- IO.mapOptional("Symbols", Object.Symbols);
- IO.setContext(nullptr);
-}
-
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_AFL_REG)
-LLVM_YAML_STRONG_TYPEDEF(uint8_t, MIPS_ABI_FP)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_EXT)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_ASE)
-LLVM_YAML_STRONG_TYPEDEF(uint32_t, MIPS_AFL_FLAGS1)
-
-} // end namespace yaml
-} // end namespace llvm
diff --git a/gnu/llvm/lib/Object/FunctionIndexObjectFile.cpp b/gnu/llvm/lib/Object/FunctionIndexObjectFile.cpp
deleted file mode 100644
index fe111de1a9c..00000000000
--- a/gnu/llvm/lib/Object/FunctionIndexObjectFile.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Part of the FunctionIndexObjectFile class implementation.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Object/FunctionIndexObjectFile.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/IR/FunctionInfo.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
-using namespace llvm;
-using namespace object;
-
-FunctionIndexObjectFile::FunctionIndexObjectFile(
- MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I)
- : SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {}
-
-FunctionIndexObjectFile::~FunctionIndexObjectFile() {}
-
-std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() {
- return std::move(Index);
-}
-
-ErrorOr<MemoryBufferRef>
-FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
- for (const SectionRef &Sec : Obj.sections()) {
- StringRef SecName;
- if (std::error_code EC = Sec.getName(SecName))
- return EC;
- if (SecName == ".llvmbc") {
- StringRef SecContents;
- if (std::error_code EC = Sec.getContents(SecContents))
- return EC;
- return MemoryBufferRef(SecContents, Obj.getFileName());
- }
- }
-
- return object_error::bitcode_section_not_found;
-}
-
-ErrorOr<MemoryBufferRef>
-FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
- sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
- switch (Type) {
- case sys::fs::file_magic::bitcode:
- return Object;
- case sys::fs::file_magic::elf_relocatable:
- case sys::fs::file_magic::macho_object:
- case sys::fs::file_magic::coff_object: {
- ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
- ObjectFile::createObjectFile(Object, Type);
- if (!ObjFile)
- return ObjFile.getError();
- return findBitcodeInObject(*ObjFile->get());
- }
- default:
- return object_error::invalid_file_type;
- }
-}
-
-// Looks for function index in the given memory buffer.
-// returns true if found, else false.
-bool FunctionIndexObjectFile::hasFunctionSummaryInMemBuffer(
- MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
- ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
- if (!BCOrErr)
- return false;
-
- return hasFunctionSummary(BCOrErr.get(), DiagnosticHandler);
-}
-
-// Parse function index in the given memory buffer.
-// Return new FunctionIndexObjectFile instance containing parsed
-// function summary/index.
-ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
-FunctionIndexObjectFile::create(MemoryBufferRef Object,
- DiagnosticHandlerFunction DiagnosticHandler,
- bool IsLazy) {
- std::unique_ptr<FunctionInfoIndex> Index;
-
- ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
- if (!BCOrErr)
- return BCOrErr.getError();
-
- ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex(
- BCOrErr.get(), DiagnosticHandler, IsLazy);
-
- if (std::error_code EC = IOrErr.getError())
- return EC;
-
- Index = std::move(IOrErr.get());
-
- return llvm::make_unique<FunctionIndexObjectFile>(Object, std::move(Index));
-}
-
-// Parse the function summary information for function with the
-// given name out of the given buffer. Parsed information is
-// stored on the index object saved in this object.
-std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
- MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
- StringRef FunctionName) {
- sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
- switch (Type) {
- case sys::fs::file_magic::bitcode: {
- return readFunctionSummary(Object, DiagnosticHandler, FunctionName,
- std::move(Index));
- }
- default:
- return object_error::invalid_file_type;
- }
-}
-
-// Parse the function index out of an IR file and return the function
-// index object if found, or nullptr if not.
-ErrorOr<std::unique_ptr<FunctionInfoIndex>>
-llvm::getFunctionIndexForFile(StringRef Path,
- DiagnosticHandlerFunction DiagnosticHandler) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFileOrSTDIN(Path);
- std::error_code EC = FileOrErr.getError();
- if (EC)
- return EC;
- MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
- ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
- object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler);
- EC = ObjOrErr.getError();
- if (EC)
- return EC;
-
- object::FunctionIndexObjectFile &Obj = **ObjOrErr;
- return Obj.takeIndex();
-}
diff --git a/gnu/llvm/lib/Object/Makefile b/gnu/llvm/lib/Object/Makefile
deleted file mode 100644
index 79388dc97f1..00000000000
--- a/gnu/llvm/lib/Object/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Object/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMObject
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Option/Makefile b/gnu/llvm/lib/Option/Makefile
deleted file mode 100644
index 255d0796e23..00000000000
--- a/gnu/llvm/lib/Option/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Option/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMOption
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Passes/Makefile b/gnu/llvm/lib/Passes/Makefile
deleted file mode 100644
index 413dc5cf485..00000000000
--- a/gnu/llvm/lib/Passes/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/Passes/Makefile ---------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMPasses
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/ProfileData/CoverageMapping.cpp b/gnu/llvm/lib/ProfileData/CoverageMapping.cpp
deleted file mode 100644
index f5d477bd139..00000000000
--- a/gnu/llvm/lib/ProfileData/CoverageMapping.cpp
+++ /dev/null
@@ -1,522 +0,0 @@
-//=-- CoverageMapping.cpp - Code coverage mapping support ---------*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for clang's and llvm's instrumentation based
-// code coverage.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ProfileData/CoverageMapping.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallBitVector.h"
-#include "llvm/ProfileData/CoverageMappingReader.h"
-#include "llvm/ProfileData/InstrProfReader.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-using namespace coverage;
-
-#define DEBUG_TYPE "coverage-mapping"
-
-Counter CounterExpressionBuilder::get(const CounterExpression &E) {
- auto It = ExpressionIndices.find(E);
- if (It != ExpressionIndices.end())
- return Counter::getExpression(It->second);
- unsigned I = Expressions.size();
- Expressions.push_back(E);
- ExpressionIndices[E] = I;
- return Counter::getExpression(I);
-}
-
-void CounterExpressionBuilder::extractTerms(
- Counter C, int Sign, SmallVectorImpl<std::pair<unsigned, int>> &Terms) {
- switch (C.getKind()) {
- case Counter::Zero:
- break;
- case Counter::CounterValueReference:
- Terms.push_back(std::make_pair(C.getCounterID(), Sign));
- break;
- case Counter::Expression:
- const auto &E = Expressions[C.getExpressionID()];
- extractTerms(E.LHS, Sign, Terms);
- extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign,
- Terms);
- break;
- }
-}
-
-Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {
- // Gather constant terms.
- llvm::SmallVector<std::pair<unsigned, int>, 32> Terms;
- extractTerms(ExpressionTree, +1, Terms);
-
- // If there are no terms, this is just a zero. The algorithm below assumes at
- // least one term.
- if (Terms.size() == 0)
- return Counter::getZero();
-
- // Group the terms by counter ID.
- std::sort(Terms.begin(), Terms.end(),
- [](const std::pair<unsigned, int> &LHS,
- const std::pair<unsigned, int> &RHS) {
- return LHS.first < RHS.first;
- });
-
- // Combine terms by counter ID to eliminate counters that sum to zero.
- auto Prev = Terms.begin();
- for (auto I = Prev + 1, E = Terms.end(); I != E; ++I) {
- if (I->first == Prev->first) {
- Prev->second += I->second;
- continue;
- }
- ++Prev;
- *Prev = *I;
- }
- Terms.erase(++Prev, Terms.end());
-
- Counter C;
- // Create additions. We do this before subtractions to avoid constructs like
- // ((0 - X) + Y), as opposed to (Y - X).
- for (auto Term : Terms) {
- if (Term.second <= 0)
- continue;
- for (int I = 0; I < Term.second; ++I)
- if (C.isZero())
- C = Counter::getCounter(Term.first);
- else
- C = get(CounterExpression(CounterExpression::Add, C,
- Counter::getCounter(Term.first)));
- }
-
- // Create subtractions.
- for (auto Term : Terms) {
- if (Term.second >= 0)
- continue;
- for (int I = 0; I < -Term.second; ++I)
- C = get(CounterExpression(CounterExpression::Subtract, C,
- Counter::getCounter(Term.first)));
- }
- return C;
-}
-
-Counter CounterExpressionBuilder::add(Counter LHS, Counter RHS) {
- return simplify(get(CounterExpression(CounterExpression::Add, LHS, RHS)));
-}
-
-Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS) {
- return simplify(
- get(CounterExpression(CounterExpression::Subtract, LHS, RHS)));
-}
-
-void CounterMappingContext::dump(const Counter &C,
- llvm::raw_ostream &OS) const {
- switch (C.getKind()) {
- case Counter::Zero:
- OS << '0';
- return;
- case Counter::CounterValueReference:
- OS << '#' << C.getCounterID();
- break;
- case Counter::Expression: {
- if (C.getExpressionID() >= Expressions.size())
- return;
- const auto &E = Expressions[C.getExpressionID()];
- OS << '(';
- dump(E.LHS, OS);
- OS << (E.Kind == CounterExpression::Subtract ? " - " : " + ");
- dump(E.RHS, OS);
- OS << ')';
- break;
- }
- }
- if (CounterValues.empty())
- return;
- ErrorOr<int64_t> Value = evaluate(C);
- if (!Value)
- return;
- OS << '[' << *Value << ']';
-}
-
-ErrorOr<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
- switch (C.getKind()) {
- case Counter::Zero:
- return 0;
- case Counter::CounterValueReference:
- if (C.getCounterID() >= CounterValues.size())
- return make_error_code(errc::argument_out_of_domain);
- return CounterValues[C.getCounterID()];
- case Counter::Expression: {
- if (C.getExpressionID() >= Expressions.size())
- return make_error_code(errc::argument_out_of_domain);
- const auto &E = Expressions[C.getExpressionID()];
- ErrorOr<int64_t> LHS = evaluate(E.LHS);
- if (!LHS)
- return LHS;
- ErrorOr<int64_t> RHS = evaluate(E.RHS);
- if (!RHS)
- return RHS;
- return E.Kind == CounterExpression::Subtract ? *LHS - *RHS : *LHS + *RHS;
- }
- }
- llvm_unreachable("Unhandled CounterKind");
-}
-
-void FunctionRecordIterator::skipOtherFiles() {
- while (Current != Records.end() && !Filename.empty() &&
- Filename != Current->Filenames[0])
- ++Current;
- if (Current == Records.end())
- *this = FunctionRecordIterator();
-}
-
-ErrorOr<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(CoverageMappingReader &CoverageReader,
- IndexedInstrProfReader &ProfileReader) {
- auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
-
- std::vector<uint64_t> Counts;
- for (const auto &Record : CoverageReader) {
- CounterMappingContext Ctx(Record.Expressions);
-
- Counts.clear();
- if (std::error_code EC = ProfileReader.getFunctionCounts(
- Record.FunctionName, Record.FunctionHash, Counts)) {
- if (EC == instrprof_error::hash_mismatch) {
- Coverage->MismatchedFunctionCount++;
- continue;
- } else if (EC != instrprof_error::unknown_function)
- return EC;
- Counts.assign(Record.MappingRegions.size(), 0);
- }
- Ctx.setCounts(Counts);
-
- assert(!Record.MappingRegions.empty() && "Function has no regions");
-
- StringRef OrigFuncName = Record.FunctionName;
- if (!Record.Filenames.empty())
- OrigFuncName =
- getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
- FunctionRecord Function(OrigFuncName, Record.Filenames);
- for (const auto &Region : Record.MappingRegions) {
- ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
- if (!ExecutionCount)
- break;
- Function.pushRegion(Region, *ExecutionCount);
- }
- if (Function.CountedRegions.size() != Record.MappingRegions.size()) {
- Coverage->MismatchedFunctionCount++;
- continue;
- }
-
- Coverage->Functions.push_back(std::move(Function));
- }
-
- return std::move(Coverage);
-}
-
-ErrorOr<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename,
- StringRef Arch) {
- auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
- if (std::error_code EC = CounterMappingBuff.getError())
- return EC;
- auto CoverageReaderOrErr =
- BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
- if (std::error_code EC = CoverageReaderOrErr.getError())
- return EC;
- auto CoverageReader = std::move(CoverageReaderOrErr.get());
- auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
- if (auto EC = ProfileReaderOrErr.getError())
- return EC;
- auto ProfileReader = std::move(ProfileReaderOrErr.get());
- return load(*CoverageReader, *ProfileReader);
-}
-
-namespace {
-/// \brief Distributes functions into instantiation sets.
-///
-/// An instantiation set is a collection of functions that have the same source
-/// code, ie, template functions specializations.
-class FunctionInstantiationSetCollector {
- typedef DenseMap<std::pair<unsigned, unsigned>,
- std::vector<const FunctionRecord *>> MapT;
- MapT InstantiatedFunctions;
-
-public:
- void insert(const FunctionRecord &Function, unsigned FileID) {
- auto I = Function.CountedRegions.begin(), E = Function.CountedRegions.end();
- while (I != E && I->FileID != FileID)
- ++I;
- assert(I != E && "function does not cover the given file");
- auto &Functions = InstantiatedFunctions[I->startLoc()];
- Functions.push_back(&Function);
- }
-
- MapT::iterator begin() { return InstantiatedFunctions.begin(); }
-
- MapT::iterator end() { return InstantiatedFunctions.end(); }
-};
-
-class SegmentBuilder {
- std::vector<CoverageSegment> Segments;
- SmallVector<const CountedRegion *, 8> ActiveRegions;
-
- /// Start a segment with no count specified.
- void startSegment(unsigned Line, unsigned Col) {
- DEBUG(dbgs() << "Top level segment at " << Line << ":" << Col << "\n");
- Segments.emplace_back(Line, Col, /*IsRegionEntry=*/false);
- }
-
- /// Start a segment with the given Region's count.
- void startSegment(unsigned Line, unsigned Col, bool IsRegionEntry,
- const CountedRegion &Region) {
- if (Segments.empty())
- Segments.emplace_back(Line, Col, IsRegionEntry);
- CoverageSegment S = Segments.back();
- // Avoid creating empty regions.
- if (S.Line != Line || S.Col != Col) {
- Segments.emplace_back(Line, Col, IsRegionEntry);
- S = Segments.back();
- }
- DEBUG(dbgs() << "Segment at " << Line << ":" << Col);
- // Set this region's count.
- if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) {
- DEBUG(dbgs() << " with count " << Region.ExecutionCount);
- Segments.back().setCount(Region.ExecutionCount);
- }
- DEBUG(dbgs() << "\n");
- }
-
- /// Start a segment for the given region.
- void startSegment(const CountedRegion &Region) {
- startSegment(Region.LineStart, Region.ColumnStart, true, Region);
- }
-
- /// Pop the top region off of the active stack, starting a new segment with
- /// the containing Region's count.
- void popRegion() {
- const CountedRegion *Active = ActiveRegions.back();
- unsigned Line = Active->LineEnd, Col = Active->ColumnEnd;
- ActiveRegions.pop_back();
- if (ActiveRegions.empty())
- startSegment(Line, Col);
- else
- startSegment(Line, Col, false, *ActiveRegions.back());
- }
-
-public:
- /// Build a list of CoverageSegments from a sorted list of Regions.
- std::vector<CoverageSegment> buildSegments(ArrayRef<CountedRegion> Regions) {
- const CountedRegion *PrevRegion = nullptr;
- for (const auto &Region : Regions) {
- // Pop any regions that end before this one starts.
- while (!ActiveRegions.empty() &&
- ActiveRegions.back()->endLoc() <= Region.startLoc())
- popRegion();
- if (PrevRegion && PrevRegion->startLoc() == Region.startLoc() &&
- PrevRegion->endLoc() == Region.endLoc()) {
- if (Region.Kind == coverage::CounterMappingRegion::CodeRegion)
- Segments.back().addCount(Region.ExecutionCount);
- } else {
- // Add this region to the stack.
- ActiveRegions.push_back(&Region);
- startSegment(Region);
- }
- PrevRegion = &Region;
- }
- // Pop any regions that are left in the stack.
- while (!ActiveRegions.empty())
- popRegion();
- return Segments;
- }
-};
-}
-
-std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
- std::vector<StringRef> Filenames;
- for (const auto &Function : getCoveredFunctions())
- Filenames.insert(Filenames.end(), Function.Filenames.begin(),
- Function.Filenames.end());
- std::sort(Filenames.begin(), Filenames.end());
- auto Last = std::unique(Filenames.begin(), Filenames.end());
- Filenames.erase(Last, Filenames.end());
- return Filenames;
-}
-
-static SmallBitVector gatherFileIDs(StringRef SourceFile,
- const FunctionRecord &Function) {
- SmallBitVector FilenameEquivalence(Function.Filenames.size(), false);
- for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I)
- if (SourceFile == Function.Filenames[I])
- FilenameEquivalence[I] = true;
- return FilenameEquivalence;
-}
-
-static Optional<unsigned> findMainViewFileID(StringRef SourceFile,
- const FunctionRecord &Function) {
- SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
- SmallBitVector FilenameEquivalence = gatherFileIDs(SourceFile, Function);
- for (const auto &CR : Function.CountedRegions)
- if (CR.Kind == CounterMappingRegion::ExpansionRegion &&
- FilenameEquivalence[CR.FileID])
- IsNotExpandedFile[CR.ExpandedFileID] = false;
- IsNotExpandedFile &= FilenameEquivalence;
- int I = IsNotExpandedFile.find_first();
- if (I == -1)
- return None;
- return I;
-}
-
-static Optional<unsigned> findMainViewFileID(const FunctionRecord &Function) {
- SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
- for (const auto &CR : Function.CountedRegions)
- if (CR.Kind == CounterMappingRegion::ExpansionRegion)
- IsNotExpandedFile[CR.ExpandedFileID] = false;
- int I = IsNotExpandedFile.find_first();
- if (I == -1)
- return None;
- return I;
-}
-
-/// Sort a nested sequence of regions from a single file.
-template <class It> static void sortNestedRegions(It First, It Last) {
- std::sort(First, Last,
- [](const CountedRegion &LHS, const CountedRegion &RHS) {
- if (LHS.startLoc() == RHS.startLoc())
- // When LHS completely contains RHS, we sort LHS first.
- return RHS.endLoc() < LHS.endLoc();
- return LHS.startLoc() < RHS.startLoc();
- });
-}
-
-static bool isExpansion(const CountedRegion &R, unsigned FileID) {
- return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
-}
-
-CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) {
- CoverageData FileCoverage(Filename);
- std::vector<coverage::CountedRegion> Regions;
-
- for (const auto &Function : Functions) {
- auto MainFileID = findMainViewFileID(Filename, Function);
- if (!MainFileID)
- continue;
- auto FileIDs = gatherFileIDs(Filename, Function);
- for (const auto &CR : Function.CountedRegions)
- if (FileIDs.test(CR.FileID)) {
- Regions.push_back(CR);
- if (isExpansion(CR, *MainFileID))
- FileCoverage.Expansions.emplace_back(CR, Function);
- }
- }
-
- sortNestedRegions(Regions.begin(), Regions.end());
- DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
- FileCoverage.Segments = SegmentBuilder().buildSegments(Regions);
-
- return FileCoverage;
-}
-
-std::vector<const FunctionRecord *>
-CoverageMapping::getInstantiations(StringRef Filename) {
- FunctionInstantiationSetCollector InstantiationSetCollector;
- for (const auto &Function : Functions) {
- auto MainFileID = findMainViewFileID(Filename, Function);
- if (!MainFileID)
- continue;
- InstantiationSetCollector.insert(Function, *MainFileID);
- }
-
- std::vector<const FunctionRecord *> Result;
- for (const auto &InstantiationSet : InstantiationSetCollector) {
- if (InstantiationSet.second.size() < 2)
- continue;
- Result.insert(Result.end(), InstantiationSet.second.begin(),
- InstantiationSet.second.end());
- }
- return Result;
-}
-
-CoverageData
-CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) {
- auto MainFileID = findMainViewFileID(Function);
- if (!MainFileID)
- return CoverageData();
-
- CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
- std::vector<coverage::CountedRegion> Regions;
- for (const auto &CR : Function.CountedRegions)
- if (CR.FileID == *MainFileID) {
- Regions.push_back(CR);
- if (isExpansion(CR, *MainFileID))
- FunctionCoverage.Expansions.emplace_back(CR, Function);
- }
-
- sortNestedRegions(Regions.begin(), Regions.end());
- DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n");
- FunctionCoverage.Segments = SegmentBuilder().buildSegments(Regions);
-
- return FunctionCoverage;
-}
-
-CoverageData
-CoverageMapping::getCoverageForExpansion(const ExpansionRecord &Expansion) {
- CoverageData ExpansionCoverage(
- Expansion.Function.Filenames[Expansion.FileID]);
- std::vector<coverage::CountedRegion> Regions;
- for (const auto &CR : Expansion.Function.CountedRegions)
- if (CR.FileID == Expansion.FileID) {
- Regions.push_back(CR);
- if (isExpansion(CR, Expansion.FileID))
- ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function);
- }
-
- sortNestedRegions(Regions.begin(), Regions.end());
- DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID
- << "\n");
- ExpansionCoverage.Segments = SegmentBuilder().buildSegments(Regions);
-
- return ExpansionCoverage;
-}
-
-namespace {
-class CoverageMappingErrorCategoryType : public std::error_category {
- const char *name() const LLVM_NOEXCEPT override { return "llvm.coveragemap"; }
- std::string message(int IE) const override {
- auto E = static_cast<coveragemap_error>(IE);
- switch (E) {
- case coveragemap_error::success:
- return "Success";
- case coveragemap_error::eof:
- return "End of File";
- case coveragemap_error::no_data_found:
- return "No coverage data found";
- case coveragemap_error::unsupported_version:
- return "Unsupported coverage format version";
- case coveragemap_error::truncated:
- return "Truncated coverage data";
- case coveragemap_error::malformed:
- return "Malformed coverage data";
- }
- llvm_unreachable("A value of coveragemap_error has no message.");
- }
-};
-}
-
-static ManagedStatic<CoverageMappingErrorCategoryType> ErrorCategory;
-
-const std::error_category &llvm::coverage::coveragemap_category() {
- return *ErrorCategory;
-}
diff --git a/gnu/llvm/lib/ProfileData/CoverageMappingReader.cpp b/gnu/llvm/lib/ProfileData/CoverageMappingReader.cpp
deleted file mode 100644
index 89e1cf42c57..00000000000
--- a/gnu/llvm/lib/ProfileData/CoverageMappingReader.cpp
+++ /dev/null
@@ -1,547 +0,0 @@
-//=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for reading coverage mapping data for
-// instrumentation based coverage.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ProfileData/CoverageMappingReader.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/Object/MachOUniversal.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/LEB128.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-using namespace coverage;
-using namespace object;
-
-#define DEBUG_TYPE "coverage-mapping"
-
-void CoverageMappingIterator::increment() {
- // Check if all the records were read or if an error occurred while reading
- // the next record.
- if (Reader->readNextRecord(Record))
- *this = CoverageMappingIterator();
-}
-
-std::error_code RawCoverageReader::readULEB128(uint64_t &Result) {
- if (Data.size() < 1)
- return coveragemap_error::truncated;
- unsigned N = 0;
- Result = decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
- if (N > Data.size())
- return coveragemap_error::malformed;
- Data = Data.substr(N);
- return std::error_code();
-}
-
-std::error_code RawCoverageReader::readIntMax(uint64_t &Result,
- uint64_t MaxPlus1) {
- if (auto Err = readULEB128(Result))
- return Err;
- if (Result >= MaxPlus1)
- return coveragemap_error::malformed;
- return std::error_code();
-}
-
-std::error_code RawCoverageReader::readSize(uint64_t &Result) {
- if (auto Err = readULEB128(Result))
- return Err;
- // Sanity check the number.
- if (Result > Data.size())
- return coveragemap_error::malformed;
- return std::error_code();
-}
-
-std::error_code RawCoverageReader::readString(StringRef &Result) {
- uint64_t Length;
- if (auto Err = readSize(Length))
- return Err;
- Result = Data.substr(0, Length);
- Data = Data.substr(Length);
- return std::error_code();
-}
-
-std::error_code RawCoverageFilenamesReader::read() {
- uint64_t NumFilenames;
- if (auto Err = readSize(NumFilenames))
- return Err;
- for (size_t I = 0; I < NumFilenames; ++I) {
- StringRef Filename;
- if (auto Err = readString(Filename))
- return Err;
- Filenames.push_back(Filename);
- }
- return std::error_code();
-}
-
-std::error_code RawCoverageMappingReader::decodeCounter(unsigned Value,
- Counter &C) {
- auto Tag = Value & Counter::EncodingTagMask;
- switch (Tag) {
- case Counter::Zero:
- C = Counter::getZero();
- return std::error_code();
- case Counter::CounterValueReference:
- C = Counter::getCounter(Value >> Counter::EncodingTagBits);
- return std::error_code();
- default:
- break;
- }
- Tag -= Counter::Expression;
- switch (Tag) {
- case CounterExpression::Subtract:
- case CounterExpression::Add: {
- auto ID = Value >> Counter::EncodingTagBits;
- if (ID >= Expressions.size())
- return coveragemap_error::malformed;
- Expressions[ID].Kind = CounterExpression::ExprKind(Tag);
- C = Counter::getExpression(ID);
- break;
- }
- default:
- return coveragemap_error::malformed;
- }
- return std::error_code();
-}
-
-std::error_code RawCoverageMappingReader::readCounter(Counter &C) {
- uint64_t EncodedCounter;
- if (auto Err =
- readIntMax(EncodedCounter, std::numeric_limits<unsigned>::max()))
- return Err;
- if (auto Err = decodeCounter(EncodedCounter, C))
- return Err;
- return std::error_code();
-}
-
-static const unsigned EncodingExpansionRegionBit = 1
- << Counter::EncodingTagBits;
-
-/// \brief Read the sub-array of regions for the given inferred file id.
-/// \param NumFileIDs the number of file ids that are defined for this
-/// function.
-std::error_code RawCoverageMappingReader::readMappingRegionsSubArray(
- std::vector<CounterMappingRegion> &MappingRegions, unsigned InferredFileID,
- size_t NumFileIDs) {
- uint64_t NumRegions;
- if (auto Err = readSize(NumRegions))
- return Err;
- unsigned LineStart = 0;
- for (size_t I = 0; I < NumRegions; ++I) {
- Counter C;
- CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
-
- // Read the combined counter + region kind.
- uint64_t EncodedCounterAndRegion;
- if (auto Err = readIntMax(EncodedCounterAndRegion,
- std::numeric_limits<unsigned>::max()))
- return Err;
- unsigned Tag = EncodedCounterAndRegion & Counter::EncodingTagMask;
- uint64_t ExpandedFileID = 0;
- if (Tag != Counter::Zero) {
- if (auto Err = decodeCounter(EncodedCounterAndRegion, C))
- return Err;
- } else {
- // Is it an expansion region?
- if (EncodedCounterAndRegion & EncodingExpansionRegionBit) {
- Kind = CounterMappingRegion::ExpansionRegion;
- ExpandedFileID = EncodedCounterAndRegion >>
- Counter::EncodingCounterTagAndExpansionRegionTagBits;
- if (ExpandedFileID >= NumFileIDs)
- return coveragemap_error::malformed;
- } else {
- switch (EncodedCounterAndRegion >>
- Counter::EncodingCounterTagAndExpansionRegionTagBits) {
- case CounterMappingRegion::CodeRegion:
- // Don't do anything when we have a code region with a zero counter.
- break;
- case CounterMappingRegion::SkippedRegion:
- Kind = CounterMappingRegion::SkippedRegion;
- break;
- default:
- return coveragemap_error::malformed;
- }
- }
- }
-
- // Read the source range.
- uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd;
- if (auto Err =
- readIntMax(LineStartDelta, std::numeric_limits<unsigned>::max()))
- return Err;
- if (auto Err = readULEB128(ColumnStart))
- return Err;
- if (ColumnStart > std::numeric_limits<unsigned>::max())
- return coveragemap_error::malformed;
- if (auto Err = readIntMax(NumLines, std::numeric_limits<unsigned>::max()))
- return Err;
- if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
- return Err;
- LineStart += LineStartDelta;
- // Adjust the column locations for the empty regions that are supposed to
- // cover whole lines. Those regions should be encoded with the
- // column range (1 -> std::numeric_limits<unsigned>::max()), but because
- // the encoded std::numeric_limits<unsigned>::max() is several bytes long,
- // we set the column range to (0 -> 0) to ensure that the column start and
- // column end take up one byte each.
- // The std::numeric_limits<unsigned>::max() is used to represent a column
- // position at the end of the line without knowing the length of that line.
- if (ColumnStart == 0 && ColumnEnd == 0) {
- ColumnStart = 1;
- ColumnEnd = std::numeric_limits<unsigned>::max();
- }
-
- DEBUG({
- dbgs() << "Counter in file " << InferredFileID << " " << LineStart << ":"
- << ColumnStart << " -> " << (LineStart + NumLines) << ":"
- << ColumnEnd << ", ";
- if (Kind == CounterMappingRegion::ExpansionRegion)
- dbgs() << "Expands to file " << ExpandedFileID;
- else
- CounterMappingContext(Expressions).dump(C, dbgs());
- dbgs() << "\n";
- });
-
- MappingRegions.push_back(CounterMappingRegion(
- C, InferredFileID, ExpandedFileID, LineStart, ColumnStart,
- LineStart + NumLines, ColumnEnd, Kind));
- }
- return std::error_code();
-}
-
-std::error_code RawCoverageMappingReader::read() {
-
- // Read the virtual file mapping.
- llvm::SmallVector<unsigned, 8> VirtualFileMapping;
- uint64_t NumFileMappings;
- if (auto Err = readSize(NumFileMappings))
- return Err;
- for (size_t I = 0; I < NumFileMappings; ++I) {
- uint64_t FilenameIndex;
- if (auto Err = readIntMax(FilenameIndex, TranslationUnitFilenames.size()))
- return Err;
- VirtualFileMapping.push_back(FilenameIndex);
- }
-
- // Construct the files using unique filenames and virtual file mapping.
- for (auto I : VirtualFileMapping) {
- Filenames.push_back(TranslationUnitFilenames[I]);
- }
-
- // Read the expressions.
- uint64_t NumExpressions;
- if (auto Err = readSize(NumExpressions))
- return Err;
- // Create an array of dummy expressions that get the proper counters
- // when the expressions are read, and the proper kinds when the counters
- // are decoded.
- Expressions.resize(
- NumExpressions,
- CounterExpression(CounterExpression::Subtract, Counter(), Counter()));
- for (size_t I = 0; I < NumExpressions; ++I) {
- if (auto Err = readCounter(Expressions[I].LHS))
- return Err;
- if (auto Err = readCounter(Expressions[I].RHS))
- return Err;
- }
-
- // Read the mapping regions sub-arrays.
- for (unsigned InferredFileID = 0, S = VirtualFileMapping.size();
- InferredFileID < S; ++InferredFileID) {
- if (auto Err = readMappingRegionsSubArray(MappingRegions, InferredFileID,
- VirtualFileMapping.size()))
- return Err;
- }
-
- // Set the counters for the expansion regions.
- // i.e. Counter of expansion region = counter of the first region
- // from the expanded file.
- // Perform multiple passes to correctly propagate the counters through
- // all the nested expansion regions.
- SmallVector<CounterMappingRegion *, 8> FileIDExpansionRegionMapping;
- FileIDExpansionRegionMapping.resize(VirtualFileMapping.size(), nullptr);
- for (unsigned Pass = 1, S = VirtualFileMapping.size(); Pass < S; ++Pass) {
- for (auto &R : MappingRegions) {
- if (R.Kind != CounterMappingRegion::ExpansionRegion)
- continue;
- assert(!FileIDExpansionRegionMapping[R.ExpandedFileID]);
- FileIDExpansionRegionMapping[R.ExpandedFileID] = &R;
- }
- for (auto &R : MappingRegions) {
- if (FileIDExpansionRegionMapping[R.FileID]) {
- FileIDExpansionRegionMapping[R.FileID]->Count = R.Count;
- FileIDExpansionRegionMapping[R.FileID] = nullptr;
- }
- }
- }
-
- return std::error_code();
-}
-
-std::error_code InstrProfSymtab::create(SectionRef &Section) {
- if (auto Err = Section.getContents(Data))
- return Err;
- Address = Section.getAddress();
- return std::error_code();
-}
-
-StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
- if (Pointer < Address)
- return StringRef();
- auto Offset = Pointer - Address;
- if (Offset + Size > Data.size())
- return StringRef();
- return Data.substr(Pointer - Address, Size);
-}
-
-template <typename T, support::endianness Endian>
-static std::error_code readCoverageMappingData(
- InstrProfSymtab &ProfileNames, StringRef Data,
- std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
- std::vector<StringRef> &Filenames) {
- using namespace support;
- llvm::DenseSet<T> UniqueFunctionMappingData;
-
- // Read the records in the coverage data section.
- for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
- if (Buf + sizeof(CovMapHeader) > End)
- return coveragemap_error::malformed;
- auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
- uint32_t NRecords = CovHeader->getNRecords<Endian>();
- uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
- uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
- uint32_t Version = CovHeader->getVersion<Endian>();
- Buf = reinterpret_cast<const char *>(++CovHeader);
-
- if (Version > coverage::CoverageMappingCurrentVersion)
- return coveragemap_error::unsupported_version;
-
- // Skip past the function records, saving the start and end for later.
- const char *FunBuf = Buf;
- Buf += NRecords * sizeof(coverage::CovMapFunctionRecord<T>);
- const char *FunEnd = Buf;
-
- // Get the filenames.
- if (Buf + FilenamesSize > End)
- return coveragemap_error::malformed;
- size_t FilenamesBegin = Filenames.size();
- RawCoverageFilenamesReader Reader(StringRef(Buf, FilenamesSize), Filenames);
- if (auto Err = Reader.read())
- return Err;
- Buf += FilenamesSize;
-
- // We'll read the coverage mapping records in the loop below.
- const char *CovBuf = Buf;
- Buf += CoverageSize;
- const char *CovEnd = Buf;
-
- if (Buf > End)
- return coveragemap_error::malformed;
- // Each coverage map has an alignment of 8, so we need to adjust alignment
- // before reading the next map.
- Buf += alignmentAdjustment(Buf, 8);
-
- auto CFR =
- reinterpret_cast<const coverage::CovMapFunctionRecord<T> *>(FunBuf);
- while ((const char *)CFR < FunEnd) {
- // Read the function information
- uint32_t DataSize = CFR->template getDataSize<Endian>();
- uint64_t FuncHash = CFR->template getFuncHash<Endian>();
-
- // Now use that to read the coverage data.
- if (CovBuf + DataSize > CovEnd)
- return coveragemap_error::malformed;
- auto Mapping = StringRef(CovBuf, DataSize);
- CovBuf += DataSize;
-
- // Ignore this record if we already have a record that points to the same
- // function name. This is useful to ignore the redundant records for the
- // functions with ODR linkage.
- T NameRef = CFR->template getFuncNameRef<Endian>();
- if (!UniqueFunctionMappingData.insert(NameRef).second)
- continue;
-
- StringRef FuncName;
- if (std::error_code EC =
- CFR->template getFuncName<Endian>(ProfileNames, FuncName))
- return EC;
- Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
- CoverageMappingVersion(Version), FuncName, FuncHash, Mapping,
- FilenamesBegin, Filenames.size() - FilenamesBegin));
- CFR++;
- }
- }
-
- return std::error_code();
-}
-
-static const char *TestingFormatMagic = "llvmcovmtestdata";
-
-static std::error_code loadTestingFormat(StringRef Data,
- InstrProfSymtab &ProfileNames,
- StringRef &CoverageMapping,
- uint8_t &BytesInAddress,
- support::endianness &Endian) {
- BytesInAddress = 8;
- Endian = support::endianness::little;
-
- Data = Data.substr(StringRef(TestingFormatMagic).size());
- if (Data.size() < 1)
- return coveragemap_error::truncated;
- unsigned N = 0;
- auto ProfileNamesSize =
- decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
- if (N > Data.size())
- return coveragemap_error::malformed;
- Data = Data.substr(N);
- if (Data.size() < 1)
- return coveragemap_error::truncated;
- N = 0;
- uint64_t Address =
- decodeULEB128(reinterpret_cast<const uint8_t *>(Data.data()), &N);
- if (N > Data.size())
- return coveragemap_error::malformed;
- Data = Data.substr(N);
- if (Data.size() < ProfileNamesSize)
- return coveragemap_error::malformed;
- ProfileNames.create(Data.substr(0, ProfileNamesSize), Address);
- CoverageMapping = Data.substr(ProfileNamesSize);
- return std::error_code();
-}
-
-static ErrorOr<SectionRef> lookupSection(ObjectFile &OF, StringRef Name) {
- StringRef FoundName;
- for (const auto &Section : OF.sections()) {
- if (auto EC = Section.getName(FoundName))
- return EC;
- if (FoundName == Name)
- return Section;
- }
- return coveragemap_error::no_data_found;
-}
-
-static std::error_code
-loadBinaryFormat(MemoryBufferRef ObjectBuffer, InstrProfSymtab &ProfileNames,
- StringRef &CoverageMapping, uint8_t &BytesInAddress,
- support::endianness &Endian, StringRef Arch) {
- auto BinOrErr = object::createBinary(ObjectBuffer);
- if (std::error_code EC = BinOrErr.getError())
- return EC;
- auto Bin = std::move(BinOrErr.get());
- std::unique_ptr<ObjectFile> OF;
- if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
- // If we have a universal binary, try to look up the object for the
- // appropriate architecture.
- auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
- if (std::error_code EC = ObjectFileOrErr.getError())
- return EC;
- OF = std::move(ObjectFileOrErr.get());
- } else if (isa<object::ObjectFile>(Bin.get())) {
- // For any other object file, upcast and take ownership.
- OF.reset(cast<object::ObjectFile>(Bin.release()));
- // If we've asked for a particular arch, make sure they match.
- if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
- return object_error::arch_not_found;
- } else
- // We can only handle object files.
- return coveragemap_error::malformed;
-
- // The coverage uses native pointer sizes for the object it's written in.
- BytesInAddress = OF->getBytesInAddress();
- Endian = OF->isLittleEndian() ? support::endianness::little
- : support::endianness::big;
-
- // Look for the sections that we are interested in.
- auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
- if (auto EC = NamesSection.getError())
- return EC;
- auto CoverageSection =
- lookupSection(*OF, getInstrProfCoverageSectionName(false));
- if (auto EC = CoverageSection.getError())
- return EC;
-
- // Get the contents of the given sections.
- if (std::error_code EC = CoverageSection->getContents(CoverageMapping))
- return EC;
- if (std::error_code EC = ProfileNames.create(*NamesSection))
- return EC;
-
- return std::error_code();
-}
-
-ErrorOr<std::unique_ptr<BinaryCoverageReader>>
-BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
- StringRef Arch) {
- std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader());
-
- InstrProfSymtab ProfileNames;
- StringRef Coverage;
- uint8_t BytesInAddress;
- support::endianness Endian;
- std::error_code EC;
- if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
- // This is a special format used for testing.
- EC = loadTestingFormat(ObjectBuffer->getBuffer(), ProfileNames, Coverage,
- BytesInAddress, Endian);
- else
- EC = loadBinaryFormat(ObjectBuffer->getMemBufferRef(), ProfileNames,
- Coverage, BytesInAddress, Endian, Arch);
- if (EC)
- return EC;
-
- if (BytesInAddress == 4 && Endian == support::endianness::little)
- EC = readCoverageMappingData<uint32_t, support::endianness::little>(
- ProfileNames, Coverage, Reader->MappingRecords, Reader->Filenames);
- else if (BytesInAddress == 4 && Endian == support::endianness::big)
- EC = readCoverageMappingData<uint32_t, support::endianness::big>(
- ProfileNames, Coverage, Reader->MappingRecords, Reader->Filenames);
- else if (BytesInAddress == 8 && Endian == support::endianness::little)
- EC = readCoverageMappingData<uint64_t, support::endianness::little>(
- ProfileNames, Coverage, Reader->MappingRecords, Reader->Filenames);
- else if (BytesInAddress == 8 && Endian == support::endianness::big)
- EC = readCoverageMappingData<uint64_t, support::endianness::big>(
- ProfileNames, Coverage, Reader->MappingRecords, Reader->Filenames);
- else
- return coveragemap_error::malformed;
- if (EC)
- return EC;
- return std::move(Reader);
-}
-
-std::error_code
-BinaryCoverageReader::readNextRecord(CoverageMappingRecord &Record) {
- if (CurrentRecord >= MappingRecords.size())
- return coveragemap_error::eof;
-
- FunctionsFilenames.clear();
- Expressions.clear();
- MappingRegions.clear();
- auto &R = MappingRecords[CurrentRecord];
- RawCoverageMappingReader Reader(
- R.CoverageMapping,
- makeArrayRef(Filenames).slice(R.FilenamesBegin, R.FilenamesSize),
- FunctionsFilenames, Expressions, MappingRegions);
- if (auto Err = Reader.read())
- return Err;
-
- Record.FunctionName = R.FunctionName;
- Record.FunctionHash = R.FunctionHash;
- Record.Filenames = FunctionsFilenames;
- Record.Expressions = Expressions;
- Record.MappingRegions = MappingRegions;
-
- ++CurrentRecord;
- return std::error_code();
-}
diff --git a/gnu/llvm/lib/ProfileData/CoverageMappingWriter.cpp b/gnu/llvm/lib/ProfileData/CoverageMappingWriter.cpp
deleted file mode 100644
index d90d2f56515..00000000000
--- a/gnu/llvm/lib/ProfileData/CoverageMappingWriter.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-//=-- CoverageMappingWriter.cpp - Code coverage mapping writer -------------=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing coverage mapping data for
-// instrumentation based coverage.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ProfileData/CoverageMappingWriter.h"
-#include "llvm/Support/LEB128.h"
-
-using namespace llvm;
-using namespace coverage;
-
-void CoverageFilenamesSectionWriter::write(raw_ostream &OS) {
- encodeULEB128(Filenames.size(), OS);
- for (const auto &Filename : Filenames) {
- encodeULEB128(Filename.size(), OS);
- OS << Filename;
- }
-}
-
-namespace {
-/// \brief Gather only the expressions that are used by the mapping
-/// regions in this function.
-class CounterExpressionsMinimizer {
- ArrayRef<CounterExpression> Expressions;
- llvm::SmallVector<CounterExpression, 16> UsedExpressions;
- std::vector<unsigned> AdjustedExpressionIDs;
-
-public:
- void mark(Counter C) {
- if (!C.isExpression())
- return;
- unsigned ID = C.getExpressionID();
- AdjustedExpressionIDs[ID] = 1;
- mark(Expressions[ID].LHS);
- mark(Expressions[ID].RHS);
- }
-
- void gatherUsed(Counter C) {
- if (!C.isExpression() || !AdjustedExpressionIDs[C.getExpressionID()])
- return;
- AdjustedExpressionIDs[C.getExpressionID()] = UsedExpressions.size();
- const auto &E = Expressions[C.getExpressionID()];
- UsedExpressions.push_back(E);
- gatherUsed(E.LHS);
- gatherUsed(E.RHS);
- }
-
- CounterExpressionsMinimizer(ArrayRef<CounterExpression> Expressions,
- ArrayRef<CounterMappingRegion> MappingRegions)
- : Expressions(Expressions) {
- AdjustedExpressionIDs.resize(Expressions.size(), 0);
- for (const auto &I : MappingRegions)
- mark(I.Count);
- for (const auto &I : MappingRegions)
- gatherUsed(I.Count);
- }
-
- ArrayRef<CounterExpression> getExpressions() const { return UsedExpressions; }
-
- /// \brief Adjust the given counter to correctly transition from the old
- /// expression ids to the new expression ids.
- Counter adjust(Counter C) const {
- if (C.isExpression())
- C = Counter::getExpression(AdjustedExpressionIDs[C.getExpressionID()]);
- return C;
- }
-};
-}
-
-/// \brief Encode the counter.
-///
-/// The encoding uses the following format:
-/// Low 2 bits - Tag:
-/// Counter::Zero(0) - A Counter with kind Counter::Zero
-/// Counter::CounterValueReference(1) - A counter with kind
-/// Counter::CounterValueReference
-/// Counter::Expression(2) + CounterExpression::Subtract(0) -
-/// A counter with kind Counter::Expression and an expression
-/// with kind CounterExpression::Subtract
-/// Counter::Expression(2) + CounterExpression::Add(1) -
-/// A counter with kind Counter::Expression and an expression
-/// with kind CounterExpression::Add
-/// Remaining bits - Counter/Expression ID.
-static unsigned encodeCounter(ArrayRef<CounterExpression> Expressions,
- Counter C) {
- unsigned Tag = unsigned(C.getKind());
- if (C.isExpression())
- Tag += Expressions[C.getExpressionID()].Kind;
- unsigned ID = C.getCounterID();
- assert(ID <=
- (std::numeric_limits<unsigned>::max() >> Counter::EncodingTagBits));
- return Tag | (ID << Counter::EncodingTagBits);
-}
-
-static void writeCounter(ArrayRef<CounterExpression> Expressions, Counter C,
- raw_ostream &OS) {
- encodeULEB128(encodeCounter(Expressions, C), OS);
-}
-
-void CoverageMappingWriter::write(raw_ostream &OS) {
- // Sort the regions in an ascending order by the file id and the starting
- // location.
- std::stable_sort(MappingRegions.begin(), MappingRegions.end());
-
- // Write out the fileid -> filename mapping.
- encodeULEB128(VirtualFileMapping.size(), OS);
- for (const auto &FileID : VirtualFileMapping)
- encodeULEB128(FileID, OS);
-
- // Write out the expressions.
- CounterExpressionsMinimizer Minimizer(Expressions, MappingRegions);
- auto MinExpressions = Minimizer.getExpressions();
- encodeULEB128(MinExpressions.size(), OS);
- for (const auto &E : MinExpressions) {
- writeCounter(MinExpressions, Minimizer.adjust(E.LHS), OS);
- writeCounter(MinExpressions, Minimizer.adjust(E.RHS), OS);
- }
-
- // Write out the mapping regions.
- // Split the regions into subarrays where each region in a
- // subarray has a fileID which is the index of that subarray.
- unsigned PrevLineStart = 0;
- unsigned CurrentFileID = ~0U;
- for (auto I = MappingRegions.begin(), E = MappingRegions.end(); I != E; ++I) {
- if (I->FileID != CurrentFileID) {
- // Ensure that all file ids have at least one mapping region.
- assert(I->FileID == (CurrentFileID + 1));
- // Find the number of regions with this file id.
- unsigned RegionCount = 1;
- for (auto J = I + 1; J != E && I->FileID == J->FileID; ++J)
- ++RegionCount;
- // Start a new region sub-array.
- encodeULEB128(RegionCount, OS);
-
- CurrentFileID = I->FileID;
- PrevLineStart = 0;
- }
- Counter Count = Minimizer.adjust(I->Count);
- switch (I->Kind) {
- case CounterMappingRegion::CodeRegion:
- writeCounter(MinExpressions, Count, OS);
- break;
- case CounterMappingRegion::ExpansionRegion: {
- assert(Count.isZero());
- assert(I->ExpandedFileID <=
- (std::numeric_limits<unsigned>::max() >>
- Counter::EncodingCounterTagAndExpansionRegionTagBits));
- // Mark an expansion region with a set bit that follows the counter tag,
- // and pack the expanded file id into the remaining bits.
- unsigned EncodedTagExpandedFileID =
- (1 << Counter::EncodingTagBits) |
- (I->ExpandedFileID
- << Counter::EncodingCounterTagAndExpansionRegionTagBits);
- encodeULEB128(EncodedTagExpandedFileID, OS);
- break;
- }
- case CounterMappingRegion::SkippedRegion:
- assert(Count.isZero());
- encodeULEB128(unsigned(I->Kind)
- << Counter::EncodingCounterTagAndExpansionRegionTagBits,
- OS);
- break;
- }
- assert(I->LineStart >= PrevLineStart);
- encodeULEB128(I->LineStart - PrevLineStart, OS);
- encodeULEB128(I->ColumnStart, OS);
- assert(I->LineEnd >= I->LineStart);
- encodeULEB128(I->LineEnd - I->LineStart, OS);
- encodeULEB128(I->ColumnEnd, OS);
- PrevLineStart = I->LineStart;
- }
- // Ensure that all file ids have at least one mapping region.
- assert(CurrentFileID == (VirtualFileMapping.size() - 1));
-}
diff --git a/gnu/llvm/lib/ProfileData/Makefile b/gnu/llvm/lib/ProfileData/Makefile
deleted file mode 100644
index 26743612d3d..00000000000
--- a/gnu/llvm/lib/ProfileData/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/ProfileData/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMProfileData
-BUILD_ARCHIVE := 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Support/Makefile b/gnu/llvm/lib/Support/Makefile
deleted file mode 100644
index 39426aaaace..00000000000
--- a/gnu/llvm/lib/Support/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Support/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMSupport
-BUILD_ARCHIVE = 1
-
-EXTRA_DIST = Unix Win32 README.txt
-
-include $(LEVEL)/Makefile.common
-
-CompileCommonOpts := $(filter-out -pedantic,$(CompileCommonOpts))
-CompileCommonOpts := $(filter-out -Wno-long-long,$(CompileCommonOpts))
-
-ifdef LLVM_VERSION_INFO
-CompileCommonOpts += -DLLVM_VERSION_INFO='"$(LLVM_VERSION_INFO)"'
-endif
diff --git a/gnu/llvm/lib/TableGen/Makefile b/gnu/llvm/lib/TableGen/Makefile
deleted file mode 100644
index 345db3465cf..00000000000
--- a/gnu/llvm/lib/TableGen/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- lib/TableGen/Makefile -------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMTableGen
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/TableGen/module.modulemap b/gnu/llvm/lib/TableGen/module.modulemap
deleted file mode 100644
index 8dac0a22c14..00000000000
--- a/gnu/llvm/lib/TableGen/module.modulemap
+++ /dev/null
@@ -1 +0,0 @@
-module TableGen { requires cplusplus umbrella "." module * { export * } }
diff --git a/gnu/llvm/lib/Target/AArch64/AsmParser/Makefile b/gnu/llvm/lib/Target/AArch64/AsmParser/Makefile
deleted file mode 100644
index 00268c76f8e..00000000000
--- a/gnu/llvm/lib/Target/AArch64/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/AArch64/AsmParser/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64AsmParser
-
-# Hack: we need to include 'main' ARM target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/Disassembler/Makefile b/gnu/llvm/lib/Target/AArch64/Disassembler/Makefile
deleted file mode 100644
index 741bb817a63..00000000000
--- a/gnu/llvm/lib/Target/AArch64/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AArch64/Disassembler/Makefile ------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64Disassembler
-
-# Hack: we need to include 'main' arm target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/InstPrinter/Makefile b/gnu/llvm/lib/Target/AArch64/InstPrinter/Makefile
deleted file mode 100644
index b17e8d08011..00000000000
--- a/gnu/llvm/lib/Target/AArch64/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/AArch64/AsmPrinter/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64AsmPrinter
-
-# Hack: we need to include 'main' arm target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/AArch64/MCTargetDesc/Makefile
deleted file mode 100644
index 5779ac5ac60..00000000000
--- a/gnu/llvm/lib/Target/AArch64/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AArch64/TargetDesc/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64Desc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/Makefile b/gnu/llvm/lib/Target/AArch64/Makefile
deleted file mode 100644
index f356c585041..00000000000
--- a/gnu/llvm/lib/Target/AArch64/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===- lib/Target/AArch64/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMAArch64CodeGen
-TARGET = AArch64
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = AArch64GenRegisterInfo.inc AArch64GenInstrInfo.inc \
- AArch64GenAsmWriter.inc AArch64GenAsmWriter1.inc \
- AArch64GenDAGISel.inc \
- AArch64GenCallingConv.inc AArch64GenAsmMatcher.inc \
- AArch64GenSubtargetInfo.inc AArch64GenMCCodeEmitter.inc \
- AArch64GenFastISel.inc AArch64GenDisassemblerTables.inc \
- AArch64GenMCPseudoLowering.inc
-
-DIRS = TargetInfo InstPrinter AsmParser Disassembler MCTargetDesc Utils
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/TargetInfo/Makefile b/gnu/llvm/lib/Target/AArch64/TargetInfo/Makefile
deleted file mode 100644
index 9dc9aa4bccf..00000000000
--- a/gnu/llvm/lib/Target/AArch64/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/AArch64/TargetInfo/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64Info
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AArch64/Utils/Makefile b/gnu/llvm/lib/Target/AArch64/Utils/Makefile
deleted file mode 100644
index 0b80f82f2b9..00000000000
--- a/gnu/llvm/lib/Target/AArch64/Utils/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AArch64/Utils/Makefile -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAArch64Utils
-
-# Hack: we need to include 'main' AArch64 target directory to grab private
-# headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.cpp b/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.cpp
deleted file mode 100644
index 2f6b3022dd6..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-//===-- AMDGPUDiagnosticInfoUnsupported.cpp -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AMDGPUDiagnosticInfoUnsupported.h"
-
-using namespace llvm;
-
-DiagnosticInfoUnsupported::DiagnosticInfoUnsupported(
- const Function &Fn,
- const Twine &Desc,
- DiagnosticSeverity Severity)
- : DiagnosticInfo(getKindID(), Severity),
- Description(Desc),
- Fn(Fn) { }
-
-int DiagnosticInfoUnsupported::KindID = 0;
-
-void DiagnosticInfoUnsupported::print(DiagnosticPrinter &DP) const {
- DP << "unsupported " << getDescription() << " in " << Fn.getName();
-}
diff --git a/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.h b/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.h
deleted file mode 100644
index 0fd37e1ede6..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/AMDGPUDiagnosticInfoUnsupported.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- AMDGPUDiagnosticInfoUnsupported.h - Error reporting -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUDIAGNOSTICINFOUNSUPPORTED_H
-#define LLVM_LIB_TARGET_AMDGPU_AMDGPUDIAGNOSTICINFOUNSUPPORTED_H
-
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/DiagnosticPrinter.h"
-
-namespace llvm {
-
-/// Diagnostic information for unimplemented or unsupported feature reporting.
-class DiagnosticInfoUnsupported : public DiagnosticInfo {
-private:
- const Twine &Description;
- const Function &Fn;
-
- static int KindID;
-
- static int getKindID() {
- if (KindID == 0)
- KindID = llvm::getNextAvailablePluginDiagnosticKind();
- return KindID;
- }
-
-public:
- DiagnosticInfoUnsupported(const Function &Fn, const Twine &Desc,
- DiagnosticSeverity Severity = DS_Error);
-
- const Function &getFunction() const { return Fn; }
- const Twine &getDescription() const { return Description; }
-
- void print(DiagnosticPrinter &DP) const override;
-
- static bool classof(const DiagnosticInfo *DI) {
- return DI->getKind() == getKindID();
- }
-};
-
-}
-
-#endif
diff --git a/gnu/llvm/lib/Target/AMDGPU/AsmParser/Makefile b/gnu/llvm/lib/Target/AMDGPU/AsmParser/Makefile
deleted file mode 100644
index 5ad21902803..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/AMDGPU/AsmParser/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAMDGPUAsmParser
-
-# Hack: we need to include 'main' AMDGPU target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/InstPrinter/Makefile b/gnu/llvm/lib/Target/AMDGPU/InstPrinter/Makefile
deleted file mode 100644
index 4e48ac7e28a..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#===- lib/Target/R600/AsmPrinter/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAMDGPUAsmPrinter
-
-# Hack: we need to include 'main' x86 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/AMDGPU/MCTargetDesc/Makefile
deleted file mode 100644
index 5ad68662d98..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AMDGPU/TargetDesc/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAMDGPUDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/Makefile b/gnu/llvm/lib/Target/AMDGPU/Makefile
deleted file mode 100644
index 219f34daa24..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Target/R600/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMAMDGPUCodeGen
-TARGET = AMDGPU
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = AMDGPUGenRegisterInfo.inc AMDGPUGenInstrInfo.inc \
- AMDGPUGenDAGISel.inc AMDGPUGenSubtargetInfo.inc \
- AMDGPUGenMCCodeEmitter.inc AMDGPUGenCallingConv.inc \
- AMDGPUGenIntrinsics.inc AMDGPUGenDFAPacketizer.inc \
- AMDGPUGenAsmWriter.inc AMDGPUGenAsmMatcher.inc
-
-DIRS = AsmParser InstPrinter TargetInfo MCTargetDesc Utils
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/R600TextureIntrinsicsReplacer.cpp b/gnu/llvm/lib/Target/AMDGPU/R600TextureIntrinsicsReplacer.cpp
deleted file mode 100644
index 2fc7b02f673..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/R600TextureIntrinsicsReplacer.cpp
+++ /dev/null
@@ -1,303 +0,0 @@
-//===-- R600TextureIntrinsicsReplacer.cpp ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file
-/// This pass translates tgsi-like texture intrinsics into R600 texture
-/// closer to hardware intrinsics.
-//===----------------------------------------------------------------------===//
-
-#include "AMDGPU.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/Passes.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InstVisitor.h"
-
-using namespace llvm;
-
-namespace {
-class R600TextureIntrinsicsReplacer :
- public FunctionPass, public InstVisitor<R600TextureIntrinsicsReplacer> {
- static char ID;
-
- Module *Mod;
- Type *FloatType;
- Type *Int32Type;
- Type *V4f32Type;
- Type *V4i32Type;
- FunctionType *TexSign;
- FunctionType *TexQSign;
-
- void getAdjustmentFromTextureTarget(unsigned TextureType, bool hasLOD,
- unsigned SrcSelect[4], unsigned CT[4],
- bool &useShadowVariant) {
- enum TextureTypes {
- TEXTURE_1D = 1,
- TEXTURE_2D,
- TEXTURE_3D,
- TEXTURE_CUBE,
- TEXTURE_RECT,
- TEXTURE_SHADOW1D,
- TEXTURE_SHADOW2D,
- TEXTURE_SHADOWRECT,
- TEXTURE_1D_ARRAY,
- TEXTURE_2D_ARRAY,
- TEXTURE_SHADOW1D_ARRAY,
- TEXTURE_SHADOW2D_ARRAY,
- TEXTURE_SHADOWCUBE,
- TEXTURE_2D_MSAA,
- TEXTURE_2D_ARRAY_MSAA,
- TEXTURE_CUBE_ARRAY,
- TEXTURE_SHADOWCUBE_ARRAY
- };
-
- switch (TextureType) {
- case 0:
- useShadowVariant = false;
- return;
- case TEXTURE_RECT:
- case TEXTURE_1D:
- case TEXTURE_2D:
- case TEXTURE_3D:
- case TEXTURE_CUBE:
- case TEXTURE_1D_ARRAY:
- case TEXTURE_2D_ARRAY:
- case TEXTURE_CUBE_ARRAY:
- case TEXTURE_2D_MSAA:
- case TEXTURE_2D_ARRAY_MSAA:
- useShadowVariant = false;
- break;
- case TEXTURE_SHADOW1D:
- case TEXTURE_SHADOW2D:
- case TEXTURE_SHADOWRECT:
- case TEXTURE_SHADOW1D_ARRAY:
- case TEXTURE_SHADOW2D_ARRAY:
- case TEXTURE_SHADOWCUBE:
- case TEXTURE_SHADOWCUBE_ARRAY:
- useShadowVariant = true;
- break;
- default:
- llvm_unreachable("Unknow Texture Type");
- }
-
- if (TextureType == TEXTURE_RECT ||
- TextureType == TEXTURE_SHADOWRECT) {
- CT[0] = 0;
- CT[1] = 0;
- }
-
- if (TextureType == TEXTURE_CUBE_ARRAY ||
- TextureType == TEXTURE_SHADOWCUBE_ARRAY)
- CT[2] = 0;
-
- if (TextureType == TEXTURE_1D_ARRAY ||
- TextureType == TEXTURE_SHADOW1D_ARRAY) {
- if (hasLOD && useShadowVariant) {
- CT[1] = 0;
- } else {
- CT[2] = 0;
- SrcSelect[2] = 1;
- }
- } else if (TextureType == TEXTURE_2D_ARRAY ||
- TextureType == TEXTURE_SHADOW2D_ARRAY) {
- CT[2] = 0;
- }
-
- if ((TextureType == TEXTURE_SHADOW1D ||
- TextureType == TEXTURE_SHADOW2D ||
- TextureType == TEXTURE_SHADOWRECT ||
- TextureType == TEXTURE_SHADOW1D_ARRAY) &&
- !(hasLOD && useShadowVariant))
- SrcSelect[3] = 2;
- }
-
- void ReplaceCallInst(CallInst &I, FunctionType *FT, const char *Name,
- unsigned SrcSelect[4], Value *Offset[3], Value *Resource,
- Value *Sampler, unsigned CT[4], Value *Coord) {
- IRBuilder<> Builder(&I);
- Constant *Mask[] = {
- ConstantInt::get(Int32Type, SrcSelect[0]),
- ConstantInt::get(Int32Type, SrcSelect[1]),
- ConstantInt::get(Int32Type, SrcSelect[2]),
- ConstantInt::get(Int32Type, SrcSelect[3])
- };
- Value *SwizzleMask = ConstantVector::get(Mask);
- Value *SwizzledCoord =
- Builder.CreateShuffleVector(Coord, Coord, SwizzleMask);
-
- Value *Args[] = {
- SwizzledCoord,
- Offset[0],
- Offset[1],
- Offset[2],
- Resource,
- Sampler,
- ConstantInt::get(Int32Type, CT[0]),
- ConstantInt::get(Int32Type, CT[1]),
- ConstantInt::get(Int32Type, CT[2]),
- ConstantInt::get(Int32Type, CT[3])
- };
-
- Function *F = Mod->getFunction(Name);
- if (!F) {
- F = Function::Create(FT, GlobalValue::ExternalLinkage, Name, Mod);
- F->addFnAttr(Attribute::ReadNone);
- }
- I.replaceAllUsesWith(Builder.CreateCall(F, Args));
- I.eraseFromParent();
- }
-
- void ReplaceTexIntrinsic(CallInst &I, bool hasLOD, FunctionType *FT,
- const char *VanillaInt,
- const char *ShadowInt) {
- Value *Coord = I.getArgOperand(0);
- Value *ResourceId = I.getArgOperand(1);
- Value *SamplerId = I.getArgOperand(2);
-
- unsigned TextureType =
- cast<ConstantInt>(I.getArgOperand(3))->getZExtValue();
-
- unsigned SrcSelect[4] = { 0, 1, 2, 3 };
- unsigned CT[4] = {1, 1, 1, 1};
- Value *Offset[3] = {
- ConstantInt::get(Int32Type, 0),
- ConstantInt::get(Int32Type, 0),
- ConstantInt::get(Int32Type, 0)
- };
- bool useShadowVariant;
-
- getAdjustmentFromTextureTarget(TextureType, hasLOD, SrcSelect, CT,
- useShadowVariant);
-
- ReplaceCallInst(I, FT, useShadowVariant?ShadowInt:VanillaInt, SrcSelect,
- Offset, ResourceId, SamplerId, CT, Coord);
- }
-
- void ReplaceTXF(CallInst &I) {
- Value *Coord = I.getArgOperand(0);
- Value *ResourceId = I.getArgOperand(4);
- Value *SamplerId = I.getArgOperand(5);
-
- unsigned TextureType =
- cast<ConstantInt>(I.getArgOperand(6))->getZExtValue();
-
- unsigned SrcSelect[4] = { 0, 1, 2, 3 };
- unsigned CT[4] = {1, 1, 1, 1};
- Value *Offset[3] = {
- I.getArgOperand(1),
- I.getArgOperand(2),
- I.getArgOperand(3),
- };
- bool useShadowVariant;
-
- getAdjustmentFromTextureTarget(TextureType, false, SrcSelect, CT,
- useShadowVariant);
-
- ReplaceCallInst(I, TexQSign, "llvm.R600.txf", SrcSelect,
- Offset, ResourceId, SamplerId, CT, Coord);
- }
-
-public:
- R600TextureIntrinsicsReplacer():
- FunctionPass(ID) {
- }
-
- bool doInitialization(Module &M) override {
- LLVMContext &Ctx = M.getContext();
- Mod = &M;
- FloatType = Type::getFloatTy(Ctx);
- Int32Type = Type::getInt32Ty(Ctx);
- V4f32Type = VectorType::get(FloatType, 4);
- V4i32Type = VectorType::get(Int32Type, 4);
- Type *ArgsType[] = {
- V4f32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- };
- TexSign = FunctionType::get(V4f32Type, ArgsType, /*isVarArg=*/false);
- Type *ArgsQType[] = {
- V4i32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- Int32Type,
- };
- TexQSign = FunctionType::get(V4f32Type, ArgsQType, /*isVarArg=*/false);
- return false;
- }
-
- bool runOnFunction(Function &F) override {
- visit(F);
- return false;
- }
-
- const char *getPassName() const override {
- return "R600 Texture Intrinsics Replacer";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- }
-
- void visitCallInst(CallInst &I) {
- if (!I.getCalledFunction())
- return;
-
- StringRef Name = I.getCalledFunction()->getName();
- if (Name == "llvm.AMDGPU.tex") {
- ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.tex", "llvm.R600.texc");
- return;
- }
- if (Name == "llvm.AMDGPU.txl") {
- ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txl", "llvm.R600.txlc");
- return;
- }
- if (Name == "llvm.AMDGPU.txb") {
- ReplaceTexIntrinsic(I, true, TexSign, "llvm.R600.txb", "llvm.R600.txbc");
- return;
- }
- if (Name == "llvm.AMDGPU.txf") {
- ReplaceTXF(I);
- return;
- }
- if (Name == "llvm.AMDGPU.txq") {
- ReplaceTexIntrinsic(I, false, TexQSign, "llvm.R600.txq", "llvm.R600.txq");
- return;
- }
- if (Name == "llvm.AMDGPU.ddx") {
- ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddx", "llvm.R600.ddx");
- return;
- }
- if (Name == "llvm.AMDGPU.ddy") {
- ReplaceTexIntrinsic(I, false, TexSign, "llvm.R600.ddy", "llvm.R600.ddy");
- return;
- }
- }
-
-};
-
-char R600TextureIntrinsicsReplacer::ID = 0;
-
-}
-
-FunctionPass *llvm::createR600TextureIntrinsicsReplacer() {
- return new R600TextureIntrinsicsReplacer();
-}
diff --git a/gnu/llvm/lib/Target/AMDGPU/SIFixSGPRLiveRanges.cpp b/gnu/llvm/lib/Target/AMDGPU/SIFixSGPRLiveRanges.cpp
deleted file mode 100644
index 8bda283f0fc..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/SIFixSGPRLiveRanges.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-//===-- SIFixSGPRLiveRanges.cpp - Fix SGPR live ranges ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-/// \file SALU instructions ignore the execution mask, so we need to modify the
-/// live ranges of the registers they define in some cases.
-///
-/// The main case we need to handle is when a def is used in one side of a
-/// branch and not another. For example:
-///
-/// %def
-/// IF
-/// ...
-/// ...
-/// ELSE
-/// %use
-/// ...
-/// ENDIF
-///
-/// Here we need the register allocator to avoid assigning any of the defs
-/// inside of the IF to the same register as %def. In traditional live
-/// interval analysis %def is not live inside the IF branch, however, since
-/// SALU instructions inside of IF will be executed even if the branch is not
-/// taken, there is the chance that one of the instructions will overwrite the
-/// value of %def, so the use in ELSE will see the wrong value.
-///
-/// The strategy we use for solving this is to add an extra use after the ENDIF:
-///
-/// %def
-/// IF
-/// ...
-/// ...
-/// ELSE
-/// %use
-/// ...
-/// ENDIF
-/// %use
-///
-/// Adding this use will make the def live throughout the IF branch, which is
-/// what we want.
-
-#include "AMDGPU.h"
-#include "SIInstrInfo.h"
-#include "SIRegisterInfo.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/CodeGen/LiveIntervalAnalysis.h"
-#include "llvm/CodeGen/LiveVariables.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachinePostDominators.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetMachine.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "si-fix-sgpr-live-ranges"
-
-namespace {
-
-class SIFixSGPRLiveRanges : public MachineFunctionPass {
-public:
- static char ID;
-
-public:
- SIFixSGPRLiveRanges() : MachineFunctionPass(ID) {
- initializeSIFixSGPRLiveRangesPass(*PassRegistry::getPassRegistry());
- }
-
- bool runOnMachineFunction(MachineFunction &MF) override;
-
- const char *getPassName() const override {
- return "SI Fix SGPR live ranges";
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<LiveVariables>();
- AU.addPreserved<LiveVariables>();
-
- AU.addRequired<MachinePostDominatorTree>();
- AU.addPreserved<MachinePostDominatorTree>();
- AU.setPreservesCFG();
-
- MachineFunctionPass::getAnalysisUsage(AU);
- }
-};
-
-} // End anonymous namespace.
-
-INITIALIZE_PASS_BEGIN(SIFixSGPRLiveRanges, DEBUG_TYPE,
- "SI Fix SGPR Live Ranges", false, false)
-INITIALIZE_PASS_DEPENDENCY(LiveVariables)
-INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTree)
-INITIALIZE_PASS_END(SIFixSGPRLiveRanges, DEBUG_TYPE,
- "SI Fix SGPR Live Ranges", false, false)
-
-char SIFixSGPRLiveRanges::ID = 0;
-
-char &llvm::SIFixSGPRLiveRangesID = SIFixSGPRLiveRanges::ID;
-
-FunctionPass *llvm::createSIFixSGPRLiveRangesPass() {
- return new SIFixSGPRLiveRanges();
-}
-
-bool SIFixSGPRLiveRanges::runOnMachineFunction(MachineFunction &MF) {
- MachineRegisterInfo &MRI = MF.getRegInfo();
- const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
- const SIRegisterInfo *TRI = static_cast<const SIRegisterInfo *>(
- MF.getSubtarget().getRegisterInfo());
- bool MadeChange = false;
-
- MachinePostDominatorTree *PDT = &getAnalysis<MachinePostDominatorTree>();
- SmallVector<unsigned, 16> SGPRLiveRanges;
-
- LiveVariables *LV = &getAnalysis<LiveVariables>();
- MachineBasicBlock *Entry = &MF.front();
-
- // Use a depth first order so that in SSA, we encounter all defs before
- // uses. Once the defs of the block have been found, attempt to insert
- // SGPR_USE instructions in successor blocks if required.
- for (MachineBasicBlock *MBB : depth_first(Entry)) {
- for (const MachineInstr &MI : *MBB) {
- for (const MachineOperand &MO : MI.defs()) {
- // We should never see a live out def of a physical register, so we also
- // do not need to worry about implicit_defs().
- unsigned Def = MO.getReg();
- if (TargetRegisterInfo::isVirtualRegister(Def)) {
- if (TRI->isSGPRClass(MRI.getRegClass(Def))) {
- // Only consider defs that are live outs. We don't care about def /
- // use within the same block.
-
- // LiveVariables does not consider registers that are only used in a
- // phi in a sucessor block as live out, unlike LiveIntervals.
- //
- // This is OK because SIFixSGPRCopies replaced any SGPR phis with
- // VGPRs.
- if (LV->isLiveOut(Def, *MBB))
- SGPRLiveRanges.push_back(Def);
- }
- }
- }
- }
-
- if (MBB->succ_size() < 2)
- continue;
-
- // We have structured control flow, so the number of successors should be
- // two.
- assert(MBB->succ_size() == 2);
- MachineBasicBlock *SuccA = *MBB->succ_begin();
- MachineBasicBlock *SuccB = *(++MBB->succ_begin());
- MachineBasicBlock *NCD = PDT->findNearestCommonDominator(SuccA, SuccB);
-
- if (!NCD)
- continue;
-
- MachineBasicBlock::iterator NCDTerm = NCD->getFirstTerminator();
-
- if (NCDTerm != NCD->end() && NCDTerm->getOpcode() == AMDGPU::SI_ELSE) {
- assert(NCD->succ_size() == 2);
- // We want to make sure we insert the Use after the ENDIF, not after
- // the ELSE.
- NCD = PDT->findNearestCommonDominator(*NCD->succ_begin(),
- *(++NCD->succ_begin()));
- }
-
- for (unsigned Reg : SGPRLiveRanges) {
- // FIXME: We could be smarter here. If the register is Live-In to one
- // block, but the other doesn't have any SGPR defs, then there won't be a
- // conflict. Also, if the branch condition is uniform then there will be
- // no conflict.
- bool LiveInToA = LV->isLiveIn(Reg, *SuccA);
- bool LiveInToB = LV->isLiveIn(Reg, *SuccB);
-
- if (!LiveInToA && !LiveInToB) {
- DEBUG(dbgs() << PrintReg(Reg, TRI, 0)
- << " is live into neither successor\n");
- continue;
- }
-
- if (LiveInToA && LiveInToB) {
- DEBUG(dbgs() << PrintReg(Reg, TRI, 0)
- << " is live into both successors\n");
- continue;
- }
-
- // This interval is live in to one successor, but not the other, so
- // we need to update its range so it is live in to both.
- DEBUG(dbgs() << "Possible SGPR conflict detected for "
- << PrintReg(Reg, TRI, 0)
- << " BB#" << SuccA->getNumber()
- << ", BB#" << SuccB->getNumber()
- << " with NCD = BB#" << NCD->getNumber() << '\n');
-
- assert(TargetRegisterInfo::isVirtualRegister(Reg) &&
- "Not expecting to extend live range of physreg");
-
- // FIXME: Need to figure out how to update LiveRange here so this pass
- // will be able to preserve LiveInterval analysis.
- MachineInstr *NCDSGPRUse =
- BuildMI(*NCD, NCD->getFirstNonPHI(), DebugLoc(),
- TII->get(AMDGPU::SGPR_USE))
- .addReg(Reg, RegState::Implicit);
-
- MadeChange = true;
- LV->HandleVirtRegUse(Reg, NCD, NCDSGPRUse);
-
- DEBUG(NCDSGPRUse->dump());
- }
- }
-
- return MadeChange;
-}
diff --git a/gnu/llvm/lib/Target/AMDGPU/TargetInfo/Makefile b/gnu/llvm/lib/Target/AMDGPU/TargetInfo/Makefile
deleted file mode 100644
index 1b232871bd6..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/AMDGPU/TargetInfo/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAMDGPUInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AMDGPU/Utils/Makefile b/gnu/llvm/lib/Target/AMDGPU/Utils/Makefile
deleted file mode 100644
index 1019e726d50..00000000000
--- a/gnu/llvm/lib/Target/AMDGPU/Utils/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AMDGPU/Utils/Makefile --------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAMDGPUUtils
-
-# Hack: we need to include 'main' AMDGPU target directory to grab private
-# headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/AsmParser/Makefile b/gnu/llvm/lib/Target/ARM/AsmParser/Makefile
deleted file mode 100644
index 841516fffbd..00000000000
--- a/gnu/llvm/lib/Target/ARM/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/ARM/AsmParser/Makefile -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMAsmParser
-
-# Hack: we need to include 'main' ARM target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/Disassembler/Makefile b/gnu/llvm/lib/Target/ARM/Disassembler/Makefile
deleted file mode 100644
index 031b6aca5a4..00000000000
--- a/gnu/llvm/lib/Target/ARM/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/ARM/Disassembler/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMDisassembler
-
-# Hack: we need to include 'main' arm target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/InstPrinter/Makefile b/gnu/llvm/lib/Target/ARM/InstPrinter/Makefile
deleted file mode 100644
index 65d372e44b8..00000000000
--- a/gnu/llvm/lib/Target/ARM/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/ARM/AsmPrinter/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMAsmPrinter
-
-# Hack: we need to include 'main' arm target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/ARM/MCTargetDesc/Makefile
deleted file mode 100644
index 448ed9df2bf..00000000000
--- a/gnu/llvm/lib/Target/ARM/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/ARM/TargetDesc/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/Makefile b/gnu/llvm/lib/Target/ARM/Makefile
deleted file mode 100644
index c1601a3f29d..00000000000
--- a/gnu/llvm/lib/Target/ARM/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- lib/Target/ARM/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMARMCodeGen
-TARGET = ARM
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = ARMGenRegisterInfo.inc ARMGenInstrInfo.inc \
- ARMGenAsmWriter.inc ARMGenAsmMatcher.inc \
- ARMGenDAGISel.inc ARMGenSubtargetInfo.inc \
- ARMGenCallingConv.inc \
- ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
- ARMGenMCPseudoLowering.inc ARMGenDisassemblerTables.inc
-
-DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/ARM/TargetInfo/Makefile b/gnu/llvm/lib/Target/ARM/TargetInfo/Makefile
deleted file mode 100644
index 6292ab14b34..00000000000
--- a/gnu/llvm/lib/Target/ARM/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/ARM/TargetInfo/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMARMInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AVR/AVRConfig.h b/gnu/llvm/lib/Target/AVR/AVRConfig.h
deleted file mode 100644
index 65588bc5084..00000000000
--- a/gnu/llvm/lib/Target/AVR/AVRConfig.h
+++ /dev/null
@@ -1,15 +0,0 @@
-//===-- AVRConfig.h - AVR Backend Configuration Header ----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_AVR_CONFIG_H
-#define LLVM_AVR_CONFIG_H
-
-#define LLVM_AVR_GCC_COMPAT
-
-#endif // LLVM_AVR_CONFIG_H
diff --git a/gnu/llvm/lib/Target/AVR/Makefile b/gnu/llvm/lib/Target/AVR/Makefile
deleted file mode 100644
index c91b6f5c0ae..00000000000
--- a/gnu/llvm/lib/Target/AVR/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-##===- lib/Target/AVR/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMAVRCodeGen
-TARGET = AVR
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = AVRGenRegisterInfo.inc
-
-DIRS = TargetInfo
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/AVR/TargetInfo/Makefile b/gnu/llvm/lib/Target/AVR/TargetInfo/Makefile
deleted file mode 100644
index 92b483dd028..00000000000
--- a/gnu/llvm/lib/Target/AVR/TargetInfo/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/AVR/TargetInfo/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMAVRInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/BPF/InstPrinter/Makefile b/gnu/llvm/lib/Target/BPF/InstPrinter/Makefile
deleted file mode 100644
index f46af83346d..00000000000
--- a/gnu/llvm/lib/Target/BPF/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/BPF/InstPrinter/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMBPFAsmPrinter
-
-# Hack: we need to include 'main' BPF target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/BPF/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/BPF/MCTargetDesc/Makefile
deleted file mode 100644
index af70cd059e5..00000000000
--- a/gnu/llvm/lib/Target/BPF/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/BPF/MCTargetDesc/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMBPFDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/BPF/Makefile b/gnu/llvm/lib/Target/BPF/Makefile
deleted file mode 100644
index 7492f5edd51..00000000000
--- a/gnu/llvm/lib/Target/BPF/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-##===- lib/Target/BPF/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMBPFCodeGen
-TARGET = BPF
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = BPFGenRegisterInfo.inc BPFGenInstrInfo.inc \
- BPFGenAsmWriter.inc BPFGenAsmMatcher.inc BPFGenDAGISel.inc \
- BPFGenMCCodeEmitter.inc BPFGenSubtargetInfo.inc BPFGenCallingConv.inc
-
-DIRS = InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/BPF/TargetInfo/Makefile b/gnu/llvm/lib/Target/BPF/TargetInfo/Makefile
deleted file mode 100644
index 02af58ea187..00000000000
--- a/gnu/llvm/lib/Target/BPF/TargetInfo/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/BPF/TargetInfo/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMBPFInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/CppBackend/CMakeLists.txt b/gnu/llvm/lib/Target/CppBackend/CMakeLists.txt
deleted file mode 100644
index 515e1dd7e39..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-add_llvm_target(CppBackendCodeGen
- CPPBackend.cpp
- )
-
-add_subdirectory(TargetInfo)
diff --git a/gnu/llvm/lib/Target/CppBackend/CPPBackend.cpp b/gnu/llvm/lib/Target/CppBackend/CPPBackend.cpp
deleted file mode 100644
index 5ea6551ebc9..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/CPPBackend.cpp
+++ /dev/null
@@ -1,2143 +0,0 @@
-//===-- CPPBackend.cpp - Library for converting LLVM code to C++ code -----===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the writing of the LLVM IR as a set of C++ calls to the
-// LLVM IR interface. The input module is assumed to be verified.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CPPTargetMachine.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Config/config.h"
-#include "llvm/IR/CallingConv.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/LegacyPassManager.h"
-#include "llvm/IR/Module.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCInstrInfo.h"
-#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/TargetRegistry.h"
-#include <algorithm>
-#include <cctype>
-#include <cstdio>
-#include <map>
-#include <set>
-using namespace llvm;
-
-static cl::opt<std::string>
-FuncName("cppfname", cl::desc("Specify the name of the generated function"),
- cl::value_desc("function name"));
-
-enum WhatToGenerate {
- GenProgram,
- GenModule,
- GenContents,
- GenFunction,
- GenFunctions,
- GenInline,
- GenVariable,
- GenType
-};
-
-static cl::opt<WhatToGenerate> GenerationType("cppgen", cl::Optional,
- cl::desc("Choose what kind of output to generate"),
- cl::init(GenProgram),
- cl::values(
- clEnumValN(GenProgram, "program", "Generate a complete program"),
- clEnumValN(GenModule, "module", "Generate a module definition"),
- clEnumValN(GenContents, "contents", "Generate contents of a module"),
- clEnumValN(GenFunction, "function", "Generate a function definition"),
- clEnumValN(GenFunctions,"functions", "Generate all function definitions"),
- clEnumValN(GenInline, "inline", "Generate an inline function"),
- clEnumValN(GenVariable, "variable", "Generate a variable definition"),
- clEnumValN(GenType, "type", "Generate a type definition"),
- clEnumValEnd
- )
-);
-
-static cl::opt<std::string> NameToGenerate("cppfor", cl::Optional,
- cl::desc("Specify the name of the thing to generate"),
- cl::init("!bad!"));
-
-extern "C" void LLVMInitializeCppBackendTarget() {
- // Register the target.
- RegisterTargetMachine<CPPTargetMachine> X(TheCppBackendTarget);
-}
-
-namespace {
- typedef std::vector<Type*> TypeList;
- typedef std::map<Type*,std::string> TypeMap;
- typedef std::map<const Value*,std::string> ValueMap;
- typedef std::set<std::string> NameSet;
- typedef std::set<Type*> TypeSet;
- typedef std::set<const Value*> ValueSet;
- typedef std::map<const Value*,std::string> ForwardRefMap;
-
- /// CppWriter - This class is the main chunk of code that converts an LLVM
- /// module to a C++ translation unit.
- class CppWriter : public ModulePass {
- std::unique_ptr<formatted_raw_ostream> OutOwner;
- formatted_raw_ostream &Out;
- const Module *TheModule;
- uint64_t uniqueNum;
- TypeMap TypeNames;
- ValueMap ValueNames;
- NameSet UsedNames;
- TypeSet DefinedTypes;
- ValueSet DefinedValues;
- ForwardRefMap ForwardRefs;
- bool is_inline;
- unsigned indent_level;
-
- public:
- static char ID;
- explicit CppWriter(std::unique_ptr<formatted_raw_ostream> o)
- : ModulePass(ID), OutOwner(std::move(o)), Out(*OutOwner), uniqueNum(0),
- is_inline(false), indent_level(0) {}
-
- const char *getPassName() const override { return "C++ backend"; }
-
- bool runOnModule(Module &M) override;
-
- void printProgram(const std::string& fname, const std::string& modName );
- void printModule(const std::string& fname, const std::string& modName );
- void printContents(const std::string& fname, const std::string& modName );
- void printFunction(const std::string& fname, const std::string& funcName );
- void printFunctions();
- void printInline(const std::string& fname, const std::string& funcName );
- void printVariable(const std::string& fname, const std::string& varName );
- void printType(const std::string& fname, const std::string& typeName );
-
- void error(const std::string& msg);
-
-
- formatted_raw_ostream& nl(formatted_raw_ostream &Out, int delta = 0);
- inline void in() { indent_level++; }
- inline void out() { if (indent_level >0) indent_level--; }
-
- private:
- void printLinkageType(GlobalValue::LinkageTypes LT);
- void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
- void printDLLStorageClassType(GlobalValue::DLLStorageClassTypes DSCType);
- void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM);
- void printCallingConv(CallingConv::ID cc);
- void printEscapedString(const std::string& str);
- void printCFP(const ConstantFP* CFP);
-
- std::string getCppName(Type* val);
- inline void printCppName(Type* val);
-
- std::string getCppName(const Value* val);
- inline void printCppName(const Value* val);
-
- void printAttributes(const AttributeSet &PAL, const std::string &name);
- void printType(Type* Ty);
- void printTypes(const Module* M);
-
- void printConstant(const Constant *CPV);
- void printConstants(const Module* M);
-
- void printVariableUses(const GlobalVariable *GV);
- void printVariableHead(const GlobalVariable *GV);
- void printVariableBody(const GlobalVariable *GV);
-
- void printFunctionUses(const Function *F);
- void printFunctionHead(const Function *F);
- void printFunctionBody(const Function *F);
- void printInstruction(const Instruction *I, const std::string& bbname);
- std::string getOpName(const Value*);
-
- void printModuleBody();
- };
-} // end anonymous namespace.
-
-formatted_raw_ostream &CppWriter::nl(formatted_raw_ostream &Out, int delta) {
- Out << '\n';
- if (delta >= 0 || indent_level >= unsigned(-delta))
- indent_level += delta;
- Out.indent(indent_level);
- return Out;
-}
-
-static inline void sanitize(std::string &str) {
- for (size_t i = 0; i < str.length(); ++i)
- if (!isalnum(str[i]) && str[i] != '_')
- str[i] = '_';
-}
-
-static std::string getTypePrefix(Type *Ty) {
- switch (Ty->getTypeID()) {
- case Type::VoidTyID: return "void_";
- case Type::IntegerTyID:
- return "int" + utostr(cast<IntegerType>(Ty)->getBitWidth()) + "_";
- case Type::FloatTyID: return "float_";
- case Type::DoubleTyID: return "double_";
- case Type::LabelTyID: return "label_";
- case Type::FunctionTyID: return "func_";
- case Type::StructTyID: return "struct_";
- case Type::ArrayTyID: return "array_";
- case Type::PointerTyID: return "ptr_";
- case Type::VectorTyID: return "packed_";
- default: return "other_";
- }
-}
-
-void CppWriter::error(const std::string& msg) {
- report_fatal_error(msg);
-}
-
-static inline std::string ftostr(const APFloat& V) {
- std::string Buf;
- if (&V.getSemantics() == &APFloat::IEEEdouble) {
- raw_string_ostream(Buf) << V.convertToDouble();
- return Buf;
- } else if (&V.getSemantics() == &APFloat::IEEEsingle) {
- raw_string_ostream(Buf) << (double)V.convertToFloat();
- return Buf;
- }
- return "<unknown format in ftostr>"; // error
-}
-
-// printCFP - Print a floating point constant .. very carefully :)
-// This makes sure that conversion to/from floating yields the same binary
-// result so that we don't lose precision.
-void CppWriter::printCFP(const ConstantFP *CFP) {
- bool ignored;
- APFloat APF = APFloat(CFP->getValueAPF()); // copy
- if (CFP->getType() == Type::getFloatTy(CFP->getContext()))
- APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, &ignored);
- Out << "ConstantFP::get(mod->getContext(), ";
- Out << "APFloat(";
-#if HAVE_PRINTF_A
- char Buffer[100];
- sprintf(Buffer, "%A", APF.convertToDouble());
- if ((!strncmp(Buffer, "0x", 2) ||
- !strncmp(Buffer, "-0x", 3) ||
- !strncmp(Buffer, "+0x", 3)) &&
- APF.bitwiseIsEqual(APFloat(atof(Buffer)))) {
- if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
- Out << "BitsToDouble(" << Buffer << ")";
- else
- Out << "BitsToFloat((float)" << Buffer << ")";
- Out << ")";
- } else {
-#endif
- std::string StrVal = ftostr(CFP->getValueAPF());
-
- while (StrVal[0] == ' ')
- StrVal.erase(StrVal.begin());
-
- // Check to make sure that the stringized number is not some string like
- // "Inf" or NaN. Check that the string matches the "[-+]?[0-9]" regex.
- if (((StrVal[0] >= '0' && StrVal[0] <= '9') ||
- ((StrVal[0] == '-' || StrVal[0] == '+') &&
- (StrVal[1] >= '0' && StrVal[1] <= '9'))) &&
- (CFP->isExactlyValue(atof(StrVal.c_str())))) {
- if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
- Out << StrVal;
- else
- Out << StrVal << "f";
- } else if (CFP->getType() == Type::getDoubleTy(CFP->getContext()))
- Out << "BitsToDouble(0x"
- << utohexstr(CFP->getValueAPF().bitcastToAPInt().getZExtValue())
- << "ULL) /* " << StrVal << " */";
- else
- Out << "BitsToFloat(0x"
- << utohexstr((uint32_t)CFP->getValueAPF().
- bitcastToAPInt().getZExtValue())
- << "U) /* " << StrVal << " */";
- Out << ")";
-#if HAVE_PRINTF_A
- }
-#endif
- Out << ")";
-}
-
-void CppWriter::printCallingConv(CallingConv::ID cc){
- // Print the calling convention.
- switch (cc) {
- case CallingConv::C: Out << "CallingConv::C"; break;
- case CallingConv::Fast: Out << "CallingConv::Fast"; break;
- case CallingConv::Cold: Out << "CallingConv::Cold"; break;
- case CallingConv::FirstTargetCC: Out << "CallingConv::FirstTargetCC"; break;
- default: Out << cc; break;
- }
-}
-
-void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
- switch (LT) {
- case GlobalValue::InternalLinkage:
- Out << "GlobalValue::InternalLinkage"; break;
- case GlobalValue::PrivateLinkage:
- Out << "GlobalValue::PrivateLinkage"; break;
- case GlobalValue::AvailableExternallyLinkage:
- Out << "GlobalValue::AvailableExternallyLinkage "; break;
- case GlobalValue::LinkOnceAnyLinkage:
- Out << "GlobalValue::LinkOnceAnyLinkage "; break;
- case GlobalValue::LinkOnceODRLinkage:
- Out << "GlobalValue::LinkOnceODRLinkage "; break;
- case GlobalValue::WeakAnyLinkage:
- Out << "GlobalValue::WeakAnyLinkage"; break;
- case GlobalValue::WeakODRLinkage:
- Out << "GlobalValue::WeakODRLinkage"; break;
- case GlobalValue::AppendingLinkage:
- Out << "GlobalValue::AppendingLinkage"; break;
- case GlobalValue::ExternalLinkage:
- Out << "GlobalValue::ExternalLinkage"; break;
- case GlobalValue::ExternalWeakLinkage:
- Out << "GlobalValue::ExternalWeakLinkage"; break;
- case GlobalValue::CommonLinkage:
- Out << "GlobalValue::CommonLinkage"; break;
- }
-}
-
-void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
- switch (VisType) {
- case GlobalValue::DefaultVisibility:
- Out << "GlobalValue::DefaultVisibility";
- break;
- case GlobalValue::HiddenVisibility:
- Out << "GlobalValue::HiddenVisibility";
- break;
- case GlobalValue::ProtectedVisibility:
- Out << "GlobalValue::ProtectedVisibility";
- break;
- }
-}
-
-void CppWriter::printDLLStorageClassType(
- GlobalValue::DLLStorageClassTypes DSCType) {
- switch (DSCType) {
- case GlobalValue::DefaultStorageClass:
- Out << "GlobalValue::DefaultStorageClass";
- break;
- case GlobalValue::DLLImportStorageClass:
- Out << "GlobalValue::DLLImportStorageClass";
- break;
- case GlobalValue::DLLExportStorageClass:
- Out << "GlobalValue::DLLExportStorageClass";
- break;
- }
-}
-
-void CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) {
- switch (TLM) {
- case GlobalVariable::NotThreadLocal:
- Out << "GlobalVariable::NotThreadLocal";
- break;
- case GlobalVariable::GeneralDynamicTLSModel:
- Out << "GlobalVariable::GeneralDynamicTLSModel";
- break;
- case GlobalVariable::LocalDynamicTLSModel:
- Out << "GlobalVariable::LocalDynamicTLSModel";
- break;
- case GlobalVariable::InitialExecTLSModel:
- Out << "GlobalVariable::InitialExecTLSModel";
- break;
- case GlobalVariable::LocalExecTLSModel:
- Out << "GlobalVariable::LocalExecTLSModel";
- break;
- }
-}
-
-// printEscapedString - Print each character of the specified string, escaping
-// it if it is not printable or if it is an escape char.
-void CppWriter::printEscapedString(const std::string &Str) {
- for (unsigned i = 0, e = Str.size(); i != e; ++i) {
- unsigned char C = Str[i];
- if (isprint(C) && C != '"' && C != '\\') {
- Out << C;
- } else {
- Out << "\\x"
- << (char) ((C/16 < 10) ? ( C/16 +'0') : ( C/16 -10+'A'))
- << (char)(((C&15) < 10) ? ((C&15)+'0') : ((C&15)-10+'A'));
- }
- }
-}
-
-std::string CppWriter::getCppName(Type* Ty) {
- switch (Ty->getTypeID()) {
- default:
- break;
- case Type::VoidTyID:
- return "Type::getVoidTy(mod->getContext())";
- case Type::IntegerTyID: {
- unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
- return "IntegerType::get(mod->getContext(), " + utostr(BitWidth) + ")";
- }
- case Type::X86_FP80TyID:
- return "Type::getX86_FP80Ty(mod->getContext())";
- case Type::FloatTyID:
- return "Type::getFloatTy(mod->getContext())";
- case Type::DoubleTyID:
- return "Type::getDoubleTy(mod->getContext())";
- case Type::LabelTyID:
- return "Type::getLabelTy(mod->getContext())";
- case Type::X86_MMXTyID:
- return "Type::getX86_MMXTy(mod->getContext())";
- }
-
- // Now, see if we've seen the type before and return that
- TypeMap::iterator I = TypeNames.find(Ty);
- if (I != TypeNames.end())
- return I->second;
-
- // Okay, let's build a new name for this type. Start with a prefix
- const char* prefix = nullptr;
- switch (Ty->getTypeID()) {
- case Type::FunctionTyID: prefix = "FuncTy_"; break;
- case Type::StructTyID: prefix = "StructTy_"; break;
- case Type::ArrayTyID: prefix = "ArrayTy_"; break;
- case Type::PointerTyID: prefix = "PointerTy_"; break;
- case Type::VectorTyID: prefix = "VectorTy_"; break;
- default: prefix = "OtherTy_"; break; // prevent breakage
- }
-
- // See if the type has a name in the symboltable and build accordingly
- std::string name;
- if (StructType *STy = dyn_cast<StructType>(Ty))
- if (STy->hasName())
- name = STy->getName();
-
- if (name.empty())
- name = utostr(uniqueNum++);
-
- name = std::string(prefix) + name;
- sanitize(name);
-
- // Save the name
- return TypeNames[Ty] = name;
-}
-
-void CppWriter::printCppName(Type* Ty) {
- printEscapedString(getCppName(Ty));
-}
-
-std::string CppWriter::getCppName(const Value* val) {
- std::string name;
- ValueMap::iterator I = ValueNames.find(val);
- if (I != ValueNames.end() && I->first == val)
- return I->second;
-
- if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(val)) {
- name = std::string("gvar_") +
- getTypePrefix(GV->getType()->getElementType());
- } else if (isa<Function>(val)) {
- name = std::string("func_");
- } else if (const Constant* C = dyn_cast<Constant>(val)) {
- name = std::string("const_") + getTypePrefix(C->getType());
- } else if (const Argument* Arg = dyn_cast<Argument>(val)) {
- if (is_inline) {
- unsigned argNum = std::distance(Arg->getParent()->arg_begin(),
- Function::const_arg_iterator(Arg)) + 1;
- name = std::string("arg_") + utostr(argNum);
- NameSet::iterator NI = UsedNames.find(name);
- if (NI != UsedNames.end())
- name += std::string("_") + utostr(uniqueNum++);
- UsedNames.insert(name);
- return ValueNames[val] = name;
- } else {
- name = getTypePrefix(val->getType());
- }
- } else {
- name = getTypePrefix(val->getType());
- }
- if (val->hasName())
- name += val->getName();
- else
- name += utostr(uniqueNum++);
- sanitize(name);
- NameSet::iterator NI = UsedNames.find(name);
- if (NI != UsedNames.end())
- name += std::string("_") + utostr(uniqueNum++);
- UsedNames.insert(name);
- return ValueNames[val] = name;
-}
-
-void CppWriter::printCppName(const Value* val) {
- printEscapedString(getCppName(val));
-}
-
-void CppWriter::printAttributes(const AttributeSet &PAL,
- const std::string &name) {
- Out << "AttributeSet " << name << "_PAL;";
- nl(Out);
- if (!PAL.isEmpty()) {
- Out << '{'; in(); nl(Out);
- Out << "SmallVector<AttributeSet, 4> Attrs;"; nl(Out);
- Out << "AttributeSet PAS;"; in(); nl(Out);
- for (unsigned i = 0; i < PAL.getNumSlots(); ++i) {
- unsigned index = PAL.getSlotIndex(i);
- AttrBuilder attrs(PAL.getSlotAttributes(i), index);
- Out << "{"; in(); nl(Out);
- Out << "AttrBuilder B;"; nl(Out);
-
-#define HANDLE_ATTR(X) \
- if (attrs.contains(Attribute::X)) { \
- Out << "B.addAttribute(Attribute::" #X ");"; nl(Out); \
- attrs.removeAttribute(Attribute::X); \
- }
-
- HANDLE_ATTR(SExt);
- HANDLE_ATTR(ZExt);
- HANDLE_ATTR(NoReturn);
- HANDLE_ATTR(InReg);
- HANDLE_ATTR(StructRet);
- HANDLE_ATTR(NoUnwind);
- HANDLE_ATTR(NoAlias);
- HANDLE_ATTR(ByVal);
- HANDLE_ATTR(InAlloca);
- HANDLE_ATTR(Nest);
- HANDLE_ATTR(ReadNone);
- HANDLE_ATTR(ReadOnly);
- HANDLE_ATTR(NoInline);
- HANDLE_ATTR(AlwaysInline);
- HANDLE_ATTR(OptimizeNone);
- HANDLE_ATTR(OptimizeForSize);
- HANDLE_ATTR(StackProtect);
- HANDLE_ATTR(StackProtectReq);
- HANDLE_ATTR(StackProtectStrong);
- HANDLE_ATTR(SafeStack);
- HANDLE_ATTR(NoCapture);
- HANDLE_ATTR(NoRedZone);
- HANDLE_ATTR(NoImplicitFloat);
- HANDLE_ATTR(Naked);
- HANDLE_ATTR(InlineHint);
- HANDLE_ATTR(ReturnsTwice);
- HANDLE_ATTR(UWTable);
- HANDLE_ATTR(NonLazyBind);
- HANDLE_ATTR(MinSize);
-#undef HANDLE_ATTR
-
- if (attrs.contains(Attribute::StackAlignment)) {
- Out << "B.addStackAlignmentAttr(" << attrs.getStackAlignment()<<')';
- nl(Out);
- attrs.removeAttribute(Attribute::StackAlignment);
- }
-
- Out << "PAS = AttributeSet::get(mod->getContext(), ";
- if (index == ~0U)
- Out << "~0U,";
- else
- Out << index << "U,";
- Out << " B);"; out(); nl(Out);
- Out << "}"; out(); nl(Out);
- nl(Out);
- Out << "Attrs.push_back(PAS);"; nl(Out);
- }
- Out << name << "_PAL = AttributeSet::get(mod->getContext(), Attrs);";
- nl(Out);
- out(); nl(Out);
- Out << '}'; nl(Out);
- }
-}
-
-void CppWriter::printType(Type* Ty) {
- // We don't print definitions for primitive types
- if (Ty->isFloatingPointTy() || Ty->isX86_MMXTy() || Ty->isIntegerTy() ||
- Ty->isLabelTy() || Ty->isMetadataTy() || Ty->isVoidTy() ||
- Ty->isTokenTy())
- return;
-
- // If we already defined this type, we don't need to define it again.
- if (DefinedTypes.find(Ty) != DefinedTypes.end())
- return;
-
- // Everything below needs the name for the type so get it now.
- std::string typeName(getCppName(Ty));
-
- // Print the type definition
- switch (Ty->getTypeID()) {
- case Type::FunctionTyID: {
- FunctionType* FT = cast<FunctionType>(Ty);
- Out << "std::vector<Type*>" << typeName << "_args;";
- nl(Out);
- FunctionType::param_iterator PI = FT->param_begin();
- FunctionType::param_iterator PE = FT->param_end();
- for (; PI != PE; ++PI) {
- Type* argTy = static_cast<Type*>(*PI);
- printType(argTy);
- std::string argName(getCppName(argTy));
- Out << typeName << "_args.push_back(" << argName;
- Out << ");";
- nl(Out);
- }
- printType(FT->getReturnType());
- std::string retTypeName(getCppName(FT->getReturnType()));
- Out << "FunctionType* " << typeName << " = FunctionType::get(";
- in(); nl(Out) << "/*Result=*/" << retTypeName;
- Out << ",";
- nl(Out) << "/*Params=*/" << typeName << "_args,";
- nl(Out) << "/*isVarArg=*/" << (FT->isVarArg() ? "true" : "false") << ");";
- out();
- nl(Out);
- break;
- }
- case Type::StructTyID: {
- StructType* ST = cast<StructType>(Ty);
- if (!ST->isLiteral()) {
- Out << "StructType *" << typeName << " = mod->getTypeByName(\"";
- printEscapedString(ST->getName());
- Out << "\");";
- nl(Out);
- Out << "if (!" << typeName << ") {";
- nl(Out);
- Out << typeName << " = ";
- Out << "StructType::create(mod->getContext(), \"";
- printEscapedString(ST->getName());
- Out << "\");";
- nl(Out);
- Out << "}";
- nl(Out);
- // Indicate that this type is now defined.
- DefinedTypes.insert(Ty);
- }
-
- Out << "std::vector<Type*>" << typeName << "_fields;";
- nl(Out);
- StructType::element_iterator EI = ST->element_begin();
- StructType::element_iterator EE = ST->element_end();
- for (; EI != EE; ++EI) {
- Type* fieldTy = static_cast<Type*>(*EI);
- printType(fieldTy);
- std::string fieldName(getCppName(fieldTy));
- Out << typeName << "_fields.push_back(" << fieldName;
- Out << ");";
- nl(Out);
- }
-
- if (ST->isLiteral()) {
- Out << "StructType *" << typeName << " = ";
- Out << "StructType::get(" << "mod->getContext(), ";
- } else {
- Out << "if (" << typeName << "->isOpaque()) {";
- nl(Out);
- Out << typeName << "->setBody(";
- }
-
- Out << typeName << "_fields, /*isPacked=*/"
- << (ST->isPacked() ? "true" : "false") << ");";
- nl(Out);
- if (!ST->isLiteral()) {
- Out << "}";
- nl(Out);
- }
- break;
- }
- case Type::ArrayTyID: {
- ArrayType* AT = cast<ArrayType>(Ty);
- Type* ET = AT->getElementType();
- printType(ET);
- if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
- std::string elemName(getCppName(ET));
- Out << "ArrayType* " << typeName << " = ArrayType::get("
- << elemName << ", " << AT->getNumElements() << ");";
- nl(Out);
- }
- break;
- }
- case Type::PointerTyID: {
- PointerType* PT = cast<PointerType>(Ty);
- Type* ET = PT->getElementType();
- printType(ET);
- if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
- std::string elemName(getCppName(ET));
- Out << "PointerType* " << typeName << " = PointerType::get("
- << elemName << ", " << PT->getAddressSpace() << ");";
- nl(Out);
- }
- break;
- }
- case Type::VectorTyID: {
- VectorType* PT = cast<VectorType>(Ty);
- Type* ET = PT->getElementType();
- printType(ET);
- if (DefinedTypes.find(Ty) == DefinedTypes.end()) {
- std::string elemName(getCppName(ET));
- Out << "VectorType* " << typeName << " = VectorType::get("
- << elemName << ", " << PT->getNumElements() << ");";
- nl(Out);
- }
- break;
- }
- default:
- error("Invalid TypeID");
- }
-
- // Indicate that this type is now defined.
- DefinedTypes.insert(Ty);
-
- // Finally, separate the type definition from other with a newline.
- nl(Out);
-}
-
-void CppWriter::printTypes(const Module* M) {
- // Add all of the global variables to the value table.
- for (Module::const_global_iterator I = TheModule->global_begin(),
- E = TheModule->global_end(); I != E; ++I) {
- if (I->hasInitializer())
- printType(I->getInitializer()->getType());
- printType(I->getType());
- }
-
- // Add all the functions to the table
- for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
- FI != FE; ++FI) {
- printType(FI->getReturnType());
- printType(FI->getFunctionType());
- // Add all the function arguments
- for (Function::const_arg_iterator AI = FI->arg_begin(),
- AE = FI->arg_end(); AI != AE; ++AI) {
- printType(AI->getType());
- }
-
- // Add all of the basic blocks and instructions
- for (Function::const_iterator BB = FI->begin(),
- E = FI->end(); BB != E; ++BB) {
- printType(BB->getType());
- for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
- ++I) {
- printType(I->getType());
- for (unsigned i = 0; i < I->getNumOperands(); ++i)
- printType(I->getOperand(i)->getType());
- }
- }
- }
-}
-
-
-// printConstant - Print out a constant pool entry...
-void CppWriter::printConstant(const Constant *CV) {
- // First, if the constant is actually a GlobalValue (variable or function)
- // or its already in the constant list then we've printed it already and we
- // can just return.
- if (isa<GlobalValue>(CV) || ValueNames.find(CV) != ValueNames.end())
- return;
-
- std::string constName(getCppName(CV));
- std::string typeName(getCppName(CV->getType()));
-
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
- std::string constValue = CI->getValue().toString(10, true);
- Out << "ConstantInt* " << constName
- << " = ConstantInt::get(mod->getContext(), APInt("
- << cast<IntegerType>(CI->getType())->getBitWidth()
- << ", StringRef(\"" << constValue << "\"), 10));";
- } else if (isa<ConstantAggregateZero>(CV)) {
- Out << "ConstantAggregateZero* " << constName
- << " = ConstantAggregateZero::get(" << typeName << ");";
- } else if (isa<ConstantPointerNull>(CV)) {
- Out << "ConstantPointerNull* " << constName
- << " = ConstantPointerNull::get(" << typeName << ");";
- } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) {
- Out << "ConstantFP* " << constName << " = ";
- printCFP(CFP);
- Out << ";";
- } else if (const ConstantArray *CA = dyn_cast<ConstantArray>(CV)) {
- Out << "std::vector<Constant*> " << constName << "_elems;";
- nl(Out);
- unsigned N = CA->getNumOperands();
- for (unsigned i = 0; i < N; ++i) {
- printConstant(CA->getOperand(i)); // recurse to print operands
- Out << constName << "_elems.push_back("
- << getCppName(CA->getOperand(i)) << ");";
- nl(Out);
- }
- Out << "Constant* " << constName << " = ConstantArray::get("
- << typeName << ", " << constName << "_elems);";
- } else if (const ConstantStruct *CS = dyn_cast<ConstantStruct>(CV)) {
- Out << "std::vector<Constant*> " << constName << "_fields;";
- nl(Out);
- unsigned N = CS->getNumOperands();
- for (unsigned i = 0; i < N; i++) {
- printConstant(CS->getOperand(i));
- Out << constName << "_fields.push_back("
- << getCppName(CS->getOperand(i)) << ");";
- nl(Out);
- }
- Out << "Constant* " << constName << " = ConstantStruct::get("
- << typeName << ", " << constName << "_fields);";
- } else if (const ConstantVector *CVec = dyn_cast<ConstantVector>(CV)) {
- Out << "std::vector<Constant*> " << constName << "_elems;";
- nl(Out);
- unsigned N = CVec->getNumOperands();
- for (unsigned i = 0; i < N; ++i) {
- printConstant(CVec->getOperand(i));
- Out << constName << "_elems.push_back("
- << getCppName(CVec->getOperand(i)) << ");";
- nl(Out);
- }
- Out << "Constant* " << constName << " = ConstantVector::get("
- << typeName << ", " << constName << "_elems);";
- } else if (isa<UndefValue>(CV)) {
- Out << "UndefValue* " << constName << " = UndefValue::get("
- << typeName << ");";
- } else if (const ConstantDataSequential *CDS =
- dyn_cast<ConstantDataSequential>(CV)) {
- if (CDS->isString()) {
- Out << "Constant *" << constName <<
- " = ConstantDataArray::getString(mod->getContext(), \"";
- StringRef Str = CDS->getAsString();
- bool nullTerminate = false;
- if (Str.back() == 0) {
- Str = Str.drop_back();
- nullTerminate = true;
- }
- printEscapedString(Str);
- // Determine if we want null termination or not.
- if (nullTerminate)
- Out << "\", true);";
- else
- Out << "\", false);";// No null terminator
- } else {
- // TODO: Could generate more efficient code generating CDS calls instead.
- Out << "std::vector<Constant*> " << constName << "_elems;";
- nl(Out);
- for (unsigned i = 0; i != CDS->getNumElements(); ++i) {
- Constant *Elt = CDS->getElementAsConstant(i);
- printConstant(Elt);
- Out << constName << "_elems.push_back(" << getCppName(Elt) << ");";
- nl(Out);
- }
- Out << "Constant* " << constName;
-
- if (isa<ArrayType>(CDS->getType()))
- Out << " = ConstantArray::get(";
- else
- Out << " = ConstantVector::get(";
- Out << typeName << ", " << constName << "_elems);";
- }
- } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
- if (CE->getOpcode() == Instruction::GetElementPtr) {
- Out << "std::vector<Constant*> " << constName << "_indices;";
- nl(Out);
- printConstant(CE->getOperand(0));
- for (unsigned i = 1; i < CE->getNumOperands(); ++i ) {
- printConstant(CE->getOperand(i));
- Out << constName << "_indices.push_back("
- << getCppName(CE->getOperand(i)) << ");";
- nl(Out);
- }
- Out << "Constant* " << constName
- << " = ConstantExpr::getGetElementPtr("
- << getCppName(CE->getOperand(0)) << ", "
- << constName << "_indices);";
- } else if (CE->isCast()) {
- printConstant(CE->getOperand(0));
- Out << "Constant* " << constName << " = ConstantExpr::getCast(";
- switch (CE->getOpcode()) {
- default: llvm_unreachable("Invalid cast opcode");
- case Instruction::Trunc: Out << "Instruction::Trunc"; break;
- case Instruction::ZExt: Out << "Instruction::ZExt"; break;
- case Instruction::SExt: Out << "Instruction::SExt"; break;
- case Instruction::FPTrunc: Out << "Instruction::FPTrunc"; break;
- case Instruction::FPExt: Out << "Instruction::FPExt"; break;
- case Instruction::FPToUI: Out << "Instruction::FPToUI"; break;
- case Instruction::FPToSI: Out << "Instruction::FPToSI"; break;
- case Instruction::UIToFP: Out << "Instruction::UIToFP"; break;
- case Instruction::SIToFP: Out << "Instruction::SIToFP"; break;
- case Instruction::PtrToInt: Out << "Instruction::PtrToInt"; break;
- case Instruction::IntToPtr: Out << "Instruction::IntToPtr"; break;
- case Instruction::BitCast: Out << "Instruction::BitCast"; break;
- }
- Out << ", " << getCppName(CE->getOperand(0)) << ", "
- << getCppName(CE->getType()) << ");";
- } else {
- unsigned N = CE->getNumOperands();
- for (unsigned i = 0; i < N; ++i ) {
- printConstant(CE->getOperand(i));
- }
- Out << "Constant* " << constName << " = ConstantExpr::";
- switch (CE->getOpcode()) {
- case Instruction::Add: Out << "getAdd("; break;
- case Instruction::FAdd: Out << "getFAdd("; break;
- case Instruction::Sub: Out << "getSub("; break;
- case Instruction::FSub: Out << "getFSub("; break;
- case Instruction::Mul: Out << "getMul("; break;
- case Instruction::FMul: Out << "getFMul("; break;
- case Instruction::UDiv: Out << "getUDiv("; break;
- case Instruction::SDiv: Out << "getSDiv("; break;
- case Instruction::FDiv: Out << "getFDiv("; break;
- case Instruction::URem: Out << "getURem("; break;
- case Instruction::SRem: Out << "getSRem("; break;
- case Instruction::FRem: Out << "getFRem("; break;
- case Instruction::And: Out << "getAnd("; break;
- case Instruction::Or: Out << "getOr("; break;
- case Instruction::Xor: Out << "getXor("; break;
- case Instruction::ICmp:
- Out << "getICmp(ICmpInst::ICMP_";
- switch (CE->getPredicate()) {
- case ICmpInst::ICMP_EQ: Out << "EQ"; break;
- case ICmpInst::ICMP_NE: Out << "NE"; break;
- case ICmpInst::ICMP_SLT: Out << "SLT"; break;
- case ICmpInst::ICMP_ULT: Out << "ULT"; break;
- case ICmpInst::ICMP_SGT: Out << "SGT"; break;
- case ICmpInst::ICMP_UGT: Out << "UGT"; break;
- case ICmpInst::ICMP_SLE: Out << "SLE"; break;
- case ICmpInst::ICMP_ULE: Out << "ULE"; break;
- case ICmpInst::ICMP_SGE: Out << "SGE"; break;
- case ICmpInst::ICMP_UGE: Out << "UGE"; break;
- default: error("Invalid ICmp Predicate");
- }
- break;
- case Instruction::FCmp:
- Out << "getFCmp(FCmpInst::FCMP_";
- switch (CE->getPredicate()) {
- case FCmpInst::FCMP_FALSE: Out << "FALSE"; break;
- case FCmpInst::FCMP_ORD: Out << "ORD"; break;
- case FCmpInst::FCMP_UNO: Out << "UNO"; break;
- case FCmpInst::FCMP_OEQ: Out << "OEQ"; break;
- case FCmpInst::FCMP_UEQ: Out << "UEQ"; break;
- case FCmpInst::FCMP_ONE: Out << "ONE"; break;
- case FCmpInst::FCMP_UNE: Out << "UNE"; break;
- case FCmpInst::FCMP_OLT: Out << "OLT"; break;
- case FCmpInst::FCMP_ULT: Out << "ULT"; break;
- case FCmpInst::FCMP_OGT: Out << "OGT"; break;
- case FCmpInst::FCMP_UGT: Out << "UGT"; break;
- case FCmpInst::FCMP_OLE: Out << "OLE"; break;
- case FCmpInst::FCMP_ULE: Out << "ULE"; break;
- case FCmpInst::FCMP_OGE: Out << "OGE"; break;
- case FCmpInst::FCMP_UGE: Out << "UGE"; break;
- case FCmpInst::FCMP_TRUE: Out << "TRUE"; break;
- default: error("Invalid FCmp Predicate");
- }
- break;
- case Instruction::Shl: Out << "getShl("; break;
- case Instruction::LShr: Out << "getLShr("; break;
- case Instruction::AShr: Out << "getAShr("; break;
- case Instruction::Select: Out << "getSelect("; break;
- case Instruction::ExtractElement: Out << "getExtractElement("; break;
- case Instruction::InsertElement: Out << "getInsertElement("; break;
- case Instruction::ShuffleVector: Out << "getShuffleVector("; break;
- default:
- error("Invalid constant expression");
- break;
- }
- Out << getCppName(CE->getOperand(0));
- for (unsigned i = 1; i < CE->getNumOperands(); ++i)
- Out << ", " << getCppName(CE->getOperand(i));
- Out << ");";
- }
- } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) {
- Out << "Constant* " << constName << " = ";
- Out << "BlockAddress::get(" << getOpName(BA->getBasicBlock()) << ");";
- } else {
- error("Bad Constant");
- Out << "Constant* " << constName << " = 0; ";
- }
- nl(Out);
-}
-
-void CppWriter::printConstants(const Module* M) {
- // Traverse all the global variables looking for constant initializers
- for (Module::const_global_iterator I = TheModule->global_begin(),
- E = TheModule->global_end(); I != E; ++I)
- if (I->hasInitializer())
- printConstant(I->getInitializer());
-
- // Traverse the LLVM functions looking for constants
- for (Module::const_iterator FI = TheModule->begin(), FE = TheModule->end();
- FI != FE; ++FI) {
- // Add all of the basic blocks and instructions
- for (Function::const_iterator BB = FI->begin(),
- E = FI->end(); BB != E; ++BB) {
- for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E;
- ++I) {
- for (unsigned i = 0; i < I->getNumOperands(); ++i) {
- if (Constant* C = dyn_cast<Constant>(I->getOperand(i))) {
- printConstant(C);
- }
- }
- }
- }
- }
-}
-
-void CppWriter::printVariableUses(const GlobalVariable *GV) {
- nl(Out) << "// Type Definitions";
- nl(Out);
- printType(GV->getType());
- if (GV->hasInitializer()) {
- const Constant *Init = GV->getInitializer();
- printType(Init->getType());
- if (const Function *F = dyn_cast<Function>(Init)) {
- nl(Out)<< "/ Function Declarations"; nl(Out);
- printFunctionHead(F);
- } else if (const GlobalVariable* gv = dyn_cast<GlobalVariable>(Init)) {
- nl(Out) << "// Global Variable Declarations"; nl(Out);
- printVariableHead(gv);
-
- nl(Out) << "// Global Variable Definitions"; nl(Out);
- printVariableBody(gv);
- } else {
- nl(Out) << "// Constant Definitions"; nl(Out);
- printConstant(Init);
- }
- }
-}
-
-void CppWriter::printVariableHead(const GlobalVariable *GV) {
- nl(Out) << "GlobalVariable* " << getCppName(GV);
- if (is_inline) {
- Out << " = mod->getGlobalVariable(mod->getContext(), ";
- printEscapedString(GV->getName());
- Out << ", " << getCppName(GV->getType()->getElementType()) << ",true)";
- nl(Out) << "if (!" << getCppName(GV) << ") {";
- in(); nl(Out) << getCppName(GV);
- }
- Out << " = new GlobalVariable(/*Module=*/*mod, ";
- nl(Out) << "/*Type=*/";
- printCppName(GV->getType()->getElementType());
- Out << ",";
- nl(Out) << "/*isConstant=*/" << (GV->isConstant()?"true":"false");
- Out << ",";
- nl(Out) << "/*Linkage=*/";
- printLinkageType(GV->getLinkage());
- Out << ",";
- nl(Out) << "/*Initializer=*/0, ";
- if (GV->hasInitializer()) {
- Out << "// has initializer, specified below";
- }
- nl(Out) << "/*Name=*/\"";
- printEscapedString(GV->getName());
- Out << "\");";
- nl(Out);
-
- if (GV->hasSection()) {
- printCppName(GV);
- Out << "->setSection(\"";
- printEscapedString(GV->getSection());
- Out << "\");";
- nl(Out);
- }
- if (GV->getAlignment()) {
- printCppName(GV);
- Out << "->setAlignment(" << GV->getAlignment() << ");";
- nl(Out);
- }
- if (GV->getVisibility() != GlobalValue::DefaultVisibility) {
- printCppName(GV);
- Out << "->setVisibility(";
- printVisibilityType(GV->getVisibility());
- Out << ");";
- nl(Out);
- }
- if (GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
- printCppName(GV);
- Out << "->setDLLStorageClass(";
- printDLLStorageClassType(GV->getDLLStorageClass());
- Out << ");";
- nl(Out);
- }
- if (GV->isThreadLocal()) {
- printCppName(GV);
- Out << "->setThreadLocalMode(";
- printThreadLocalMode(GV->getThreadLocalMode());
- Out << ");";
- nl(Out);
- }
- if (is_inline) {
- out(); Out << "}"; nl(Out);
- }
-}
-
-void CppWriter::printVariableBody(const GlobalVariable *GV) {
- if (GV->hasInitializer()) {
- printCppName(GV);
- Out << "->setInitializer(";
- Out << getCppName(GV->getInitializer()) << ");";
- nl(Out);
- }
-}
-
-std::string CppWriter::getOpName(const Value* V) {
- if (!isa<Instruction>(V) || DefinedValues.find(V) != DefinedValues.end())
- return getCppName(V);
-
- // See if its alread in the map of forward references, if so just return the
- // name we already set up for it
- ForwardRefMap::const_iterator I = ForwardRefs.find(V);
- if (I != ForwardRefs.end())
- return I->second;
-
- // This is a new forward reference. Generate a unique name for it
- std::string result(std::string("fwdref_") + utostr(uniqueNum++));
-
- // Yes, this is a hack. An Argument is the smallest instantiable value that
- // we can make as a placeholder for the real value. We'll replace these
- // Argument instances later.
- Out << "Argument* " << result << " = new Argument("
- << getCppName(V->getType()) << ");";
- nl(Out);
- ForwardRefs[V] = result;
- return result;
-}
-
-static StringRef ConvertAtomicOrdering(AtomicOrdering Ordering) {
- switch (Ordering) {
- case NotAtomic: return "NotAtomic";
- case Unordered: return "Unordered";
- case Monotonic: return "Monotonic";
- case Acquire: return "Acquire";
- case Release: return "Release";
- case AcquireRelease: return "AcquireRelease";
- case SequentiallyConsistent: return "SequentiallyConsistent";
- }
- llvm_unreachable("Unknown ordering");
-}
-
-static StringRef ConvertAtomicSynchScope(SynchronizationScope SynchScope) {
- switch (SynchScope) {
- case SingleThread: return "SingleThread";
- case CrossThread: return "CrossThread";
- }
- llvm_unreachable("Unknown synch scope");
-}
-
-// printInstruction - This member is called for each Instruction in a function.
-void CppWriter::printInstruction(const Instruction *I,
- const std::string& bbname) {
- std::string iName(getCppName(I));
-
- // Before we emit this instruction, we need to take care of generating any
- // forward references. So, we get the names of all the operands in advance
- const unsigned Ops(I->getNumOperands());
- std::string* opNames = new std::string[Ops];
- for (unsigned i = 0; i < Ops; i++)
- opNames[i] = getOpName(I->getOperand(i));
-
- switch (I->getOpcode()) {
- default:
- error("Invalid instruction");
- break;
-
- case Instruction::Ret: {
- const ReturnInst* ret = cast<ReturnInst>(I);
- Out << "ReturnInst::Create(mod->getContext(), "
- << (ret->getReturnValue() ? opNames[0] + ", " : "") << bbname << ");";
- break;
- }
- case Instruction::Br: {
- const BranchInst* br = cast<BranchInst>(I);
- Out << "BranchInst::Create(" ;
- if (br->getNumOperands() == 3) {
- Out << opNames[2] << ", "
- << opNames[1] << ", "
- << opNames[0] << ", ";
-
- } else if (br->getNumOperands() == 1) {
- Out << opNames[0] << ", ";
- } else {
- error("Branch with 2 operands?");
- }
- Out << bbname << ");";
- break;
- }
- case Instruction::Switch: {
- const SwitchInst *SI = cast<SwitchInst>(I);
- Out << "SwitchInst* " << iName << " = SwitchInst::Create("
- << getOpName(SI->getCondition()) << ", "
- << getOpName(SI->getDefaultDest()) << ", "
- << SI->getNumCases() << ", " << bbname << ");";
- nl(Out);
- for (SwitchInst::ConstCaseIt i = SI->case_begin(), e = SI->case_end();
- i != e; ++i) {
- const ConstantInt* CaseVal = i.getCaseValue();
- const BasicBlock *BB = i.getCaseSuccessor();
- Out << iName << "->addCase("
- << getOpName(CaseVal) << ", "
- << getOpName(BB) << ");";
- nl(Out);
- }
- break;
- }
- case Instruction::IndirectBr: {
- const IndirectBrInst *IBI = cast<IndirectBrInst>(I);
- Out << "IndirectBrInst *" << iName << " = IndirectBrInst::Create("
- << opNames[0] << ", " << IBI->getNumDestinations() << ");";
- nl(Out);
- for (unsigned i = 1; i != IBI->getNumOperands(); ++i) {
- Out << iName << "->addDestination(" << opNames[i] << ");";
- nl(Out);
- }
- break;
- }
- case Instruction::Resume: {
- Out << "ResumeInst::Create(" << opNames[0] << ", " << bbname << ");";
- break;
- }
- case Instruction::Invoke: {
- const InvokeInst* inv = cast<InvokeInst>(I);
- Out << "std::vector<Value*> " << iName << "_params;";
- nl(Out);
- for (unsigned i = 0; i < inv->getNumArgOperands(); ++i) {
- Out << iName << "_params.push_back("
- << getOpName(inv->getArgOperand(i)) << ");";
- nl(Out);
- }
- // FIXME: This shouldn't use magic numbers -3, -2, and -1.
- Out << "InvokeInst *" << iName << " = InvokeInst::Create("
- << getOpName(inv->getCalledValue()) << ", "
- << getOpName(inv->getNormalDest()) << ", "
- << getOpName(inv->getUnwindDest()) << ", "
- << iName << "_params, \"";
- printEscapedString(inv->getName());
- Out << "\", " << bbname << ");";
- nl(Out) << iName << "->setCallingConv(";
- printCallingConv(inv->getCallingConv());
- Out << ");";
- printAttributes(inv->getAttributes(), iName);
- Out << iName << "->setAttributes(" << iName << "_PAL);";
- nl(Out);
- break;
- }
- case Instruction::Unreachable: {
- Out << "new UnreachableInst("
- << "mod->getContext(), "
- << bbname << ");";
- break;
- }
- case Instruction::Add:
- case Instruction::FAdd:
- case Instruction::Sub:
- case Instruction::FSub:
- case Instruction::Mul:
- case Instruction::FMul:
- case Instruction::UDiv:
- case Instruction::SDiv:
- case Instruction::FDiv:
- case Instruction::URem:
- case Instruction::SRem:
- case Instruction::FRem:
- case Instruction::And:
- case Instruction::Or:
- case Instruction::Xor:
- case Instruction::Shl:
- case Instruction::LShr:
- case Instruction::AShr:{
- Out << "BinaryOperator* " << iName << " = BinaryOperator::Create(";
- switch (I->getOpcode()) {
- case Instruction::Add: Out << "Instruction::Add"; break;
- case Instruction::FAdd: Out << "Instruction::FAdd"; break;
- case Instruction::Sub: Out << "Instruction::Sub"; break;
- case Instruction::FSub: Out << "Instruction::FSub"; break;
- case Instruction::Mul: Out << "Instruction::Mul"; break;
- case Instruction::FMul: Out << "Instruction::FMul"; break;
- case Instruction::UDiv:Out << "Instruction::UDiv"; break;
- case Instruction::SDiv:Out << "Instruction::SDiv"; break;
- case Instruction::FDiv:Out << "Instruction::FDiv"; break;
- case Instruction::URem:Out << "Instruction::URem"; break;
- case Instruction::SRem:Out << "Instruction::SRem"; break;
- case Instruction::FRem:Out << "Instruction::FRem"; break;
- case Instruction::And: Out << "Instruction::And"; break;
- case Instruction::Or: Out << "Instruction::Or"; break;
- case Instruction::Xor: Out << "Instruction::Xor"; break;
- case Instruction::Shl: Out << "Instruction::Shl"; break;
- case Instruction::LShr:Out << "Instruction::LShr"; break;
- case Instruction::AShr:Out << "Instruction::AShr"; break;
- default: Out << "Instruction::BadOpCode"; break;
- }
- Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
- printEscapedString(I->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::FCmp: {
- Out << "FCmpInst* " << iName << " = new FCmpInst(*" << bbname << ", ";
- switch (cast<FCmpInst>(I)->getPredicate()) {
- case FCmpInst::FCMP_FALSE: Out << "FCmpInst::FCMP_FALSE"; break;
- case FCmpInst::FCMP_OEQ : Out << "FCmpInst::FCMP_OEQ"; break;
- case FCmpInst::FCMP_OGT : Out << "FCmpInst::FCMP_OGT"; break;
- case FCmpInst::FCMP_OGE : Out << "FCmpInst::FCMP_OGE"; break;
- case FCmpInst::FCMP_OLT : Out << "FCmpInst::FCMP_OLT"; break;
- case FCmpInst::FCMP_OLE : Out << "FCmpInst::FCMP_OLE"; break;
- case FCmpInst::FCMP_ONE : Out << "FCmpInst::FCMP_ONE"; break;
- case FCmpInst::FCMP_ORD : Out << "FCmpInst::FCMP_ORD"; break;
- case FCmpInst::FCMP_UNO : Out << "FCmpInst::FCMP_UNO"; break;
- case FCmpInst::FCMP_UEQ : Out << "FCmpInst::FCMP_UEQ"; break;
- case FCmpInst::FCMP_UGT : Out << "FCmpInst::FCMP_UGT"; break;
- case FCmpInst::FCMP_UGE : Out << "FCmpInst::FCMP_UGE"; break;
- case FCmpInst::FCMP_ULT : Out << "FCmpInst::FCMP_ULT"; break;
- case FCmpInst::FCMP_ULE : Out << "FCmpInst::FCMP_ULE"; break;
- case FCmpInst::FCMP_UNE : Out << "FCmpInst::FCMP_UNE"; break;
- case FCmpInst::FCMP_TRUE : Out << "FCmpInst::FCMP_TRUE"; break;
- default: Out << "FCmpInst::BAD_ICMP_PREDICATE"; break;
- }
- Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
- printEscapedString(I->getName());
- Out << "\");";
- break;
- }
- case Instruction::ICmp: {
- Out << "ICmpInst* " << iName << " = new ICmpInst(*" << bbname << ", ";
- switch (cast<ICmpInst>(I)->getPredicate()) {
- case ICmpInst::ICMP_EQ: Out << "ICmpInst::ICMP_EQ"; break;
- case ICmpInst::ICMP_NE: Out << "ICmpInst::ICMP_NE"; break;
- case ICmpInst::ICMP_ULE: Out << "ICmpInst::ICMP_ULE"; break;
- case ICmpInst::ICMP_SLE: Out << "ICmpInst::ICMP_SLE"; break;
- case ICmpInst::ICMP_UGE: Out << "ICmpInst::ICMP_UGE"; break;
- case ICmpInst::ICMP_SGE: Out << "ICmpInst::ICMP_SGE"; break;
- case ICmpInst::ICMP_ULT: Out << "ICmpInst::ICMP_ULT"; break;
- case ICmpInst::ICMP_SLT: Out << "ICmpInst::ICMP_SLT"; break;
- case ICmpInst::ICMP_UGT: Out << "ICmpInst::ICMP_UGT"; break;
- case ICmpInst::ICMP_SGT: Out << "ICmpInst::ICMP_SGT"; break;
- default: Out << "ICmpInst::BAD_ICMP_PREDICATE"; break;
- }
- Out << ", " << opNames[0] << ", " << opNames[1] << ", \"";
- printEscapedString(I->getName());
- Out << "\");";
- break;
- }
- case Instruction::Alloca: {
- const AllocaInst* allocaI = cast<AllocaInst>(I);
- Out << "AllocaInst* " << iName << " = new AllocaInst("
- << getCppName(allocaI->getAllocatedType()) << ", ";
- if (allocaI->isArrayAllocation())
- Out << opNames[0] << ", ";
- Out << "\"";
- printEscapedString(allocaI->getName());
- Out << "\", " << bbname << ");";
- if (allocaI->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << allocaI->getAlignment() << ");";
- break;
- }
- case Instruction::Load: {
- const LoadInst* load = cast<LoadInst>(I);
- Out << "LoadInst* " << iName << " = new LoadInst("
- << opNames[0] << ", \"";
- printEscapedString(load->getName());
- Out << "\", " << (load->isVolatile() ? "true" : "false" )
- << ", " << bbname << ");";
- if (load->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << load->getAlignment() << ");";
- if (load->isAtomic()) {
- StringRef Ordering = ConvertAtomicOrdering(load->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(load->getSynchScope());
- nl(Out) << iName << "->setAtomic("
- << Ordering << ", " << CrossThread << ");";
- }
- break;
- }
- case Instruction::Store: {
- const StoreInst* store = cast<StoreInst>(I);
- Out << "StoreInst* " << iName << " = new StoreInst("
- << opNames[0] << ", "
- << opNames[1] << ", "
- << (store->isVolatile() ? "true" : "false")
- << ", " << bbname << ");";
- if (store->getAlignment())
- nl(Out) << iName << "->setAlignment("
- << store->getAlignment() << ");";
- if (store->isAtomic()) {
- StringRef Ordering = ConvertAtomicOrdering(store->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(store->getSynchScope());
- nl(Out) << iName << "->setAtomic("
- << Ordering << ", " << CrossThread << ");";
- }
- break;
- }
- case Instruction::GetElementPtr: {
- const GetElementPtrInst* gep = cast<GetElementPtrInst>(I);
- Out << "GetElementPtrInst* " << iName << " = GetElementPtrInst::Create("
- << getCppName(gep->getSourceElementType()) << ", " << opNames[0] << ", {";
- in();
- for (unsigned i = 1; i < gep->getNumOperands(); ++i ) {
- if (i != 1) {
- Out << ", ";
- }
- nl(Out);
- Out << opNames[i];
- }
- out();
- nl(Out) << "}, \"";
- printEscapedString(gep->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::PHI: {
- const PHINode* phi = cast<PHINode>(I);
-
- Out << "PHINode* " << iName << " = PHINode::Create("
- << getCppName(phi->getType()) << ", "
- << phi->getNumIncomingValues() << ", \"";
- printEscapedString(phi->getName());
- Out << "\", " << bbname << ");";
- nl(Out);
- for (unsigned i = 0; i < phi->getNumIncomingValues(); ++i) {
- Out << iName << "->addIncoming("
- << opNames[PHINode::getOperandNumForIncomingValue(i)] << ", "
- << getOpName(phi->getIncomingBlock(i)) << ");";
- nl(Out);
- }
- break;
- }
- case Instruction::Trunc:
- case Instruction::ZExt:
- case Instruction::SExt:
- case Instruction::FPTrunc:
- case Instruction::FPExt:
- case Instruction::FPToUI:
- case Instruction::FPToSI:
- case Instruction::UIToFP:
- case Instruction::SIToFP:
- case Instruction::PtrToInt:
- case Instruction::IntToPtr:
- case Instruction::BitCast: {
- const CastInst* cst = cast<CastInst>(I);
- Out << "CastInst* " << iName << " = new ";
- switch (I->getOpcode()) {
- case Instruction::Trunc: Out << "TruncInst"; break;
- case Instruction::ZExt: Out << "ZExtInst"; break;
- case Instruction::SExt: Out << "SExtInst"; break;
- case Instruction::FPTrunc: Out << "FPTruncInst"; break;
- case Instruction::FPExt: Out << "FPExtInst"; break;
- case Instruction::FPToUI: Out << "FPToUIInst"; break;
- case Instruction::FPToSI: Out << "FPToSIInst"; break;
- case Instruction::UIToFP: Out << "UIToFPInst"; break;
- case Instruction::SIToFP: Out << "SIToFPInst"; break;
- case Instruction::PtrToInt: Out << "PtrToIntInst"; break;
- case Instruction::IntToPtr: Out << "IntToPtrInst"; break;
- case Instruction::BitCast: Out << "BitCastInst"; break;
- default: llvm_unreachable("Unreachable");
- }
- Out << "(" << opNames[0] << ", "
- << getCppName(cst->getType()) << ", \"";
- printEscapedString(cst->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::Call: {
- const CallInst* call = cast<CallInst>(I);
- if (const InlineAsm* ila = dyn_cast<InlineAsm>(call->getCalledValue())) {
- Out << "InlineAsm* " << getCppName(ila) << " = InlineAsm::get("
- << getCppName(ila->getFunctionType()) << ", \""
- << ila->getAsmString() << "\", \""
- << ila->getConstraintString() << "\","
- << (ila->hasSideEffects() ? "true" : "false") << ");";
- nl(Out);
- }
- if (call->getNumArgOperands() > 1) {
- Out << "std::vector<Value*> " << iName << "_params;";
- nl(Out);
- for (unsigned i = 0; i < call->getNumArgOperands(); ++i) {
- Out << iName << "_params.push_back(" << opNames[i] << ");";
- nl(Out);
- }
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", "
- << iName << "_params, \"";
- } else if (call->getNumArgOperands() == 1) {
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", " << opNames[0] << ", \"";
- } else {
- Out << "CallInst* " << iName << " = CallInst::Create("
- << opNames[call->getNumArgOperands()] << ", \"";
- }
- printEscapedString(call->getName());
- Out << "\", " << bbname << ");";
- nl(Out) << iName << "->setCallingConv(";
- printCallingConv(call->getCallingConv());
- Out << ");";
- nl(Out) << iName << "->setTailCall("
- << (call->isTailCall() ? "true" : "false");
- Out << ");";
- nl(Out);
- printAttributes(call->getAttributes(), iName);
- Out << iName << "->setAttributes(" << iName << "_PAL);";
- nl(Out);
- break;
- }
- case Instruction::Select: {
- const SelectInst* sel = cast<SelectInst>(I);
- Out << "SelectInst* " << getCppName(sel) << " = SelectInst::Create(";
- Out << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", \"";
- printEscapedString(sel->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::UserOp1:
- /// FALL THROUGH
- case Instruction::UserOp2: {
- /// FIXME: What should be done here?
- break;
- }
- case Instruction::VAArg: {
- const VAArgInst* va = cast<VAArgInst>(I);
- Out << "VAArgInst* " << getCppName(va) << " = new VAArgInst("
- << opNames[0] << ", " << getCppName(va->getType()) << ", \"";
- printEscapedString(va->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::ExtractElement: {
- const ExtractElementInst* eei = cast<ExtractElementInst>(I);
- Out << "ExtractElementInst* " << getCppName(eei)
- << " = new ExtractElementInst(" << opNames[0]
- << ", " << opNames[1] << ", \"";
- printEscapedString(eei->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::InsertElement: {
- const InsertElementInst* iei = cast<InsertElementInst>(I);
- Out << "InsertElementInst* " << getCppName(iei)
- << " = InsertElementInst::Create(" << opNames[0]
- << ", " << opNames[1] << ", " << opNames[2] << ", \"";
- printEscapedString(iei->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::ShuffleVector: {
- const ShuffleVectorInst* svi = cast<ShuffleVectorInst>(I);
- Out << "ShuffleVectorInst* " << getCppName(svi)
- << " = new ShuffleVectorInst(" << opNames[0]
- << ", " << opNames[1] << ", " << opNames[2] << ", \"";
- printEscapedString(svi->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::ExtractValue: {
- const ExtractValueInst *evi = cast<ExtractValueInst>(I);
- Out << "std::vector<unsigned> " << iName << "_indices;";
- nl(Out);
- for (unsigned i = 0; i < evi->getNumIndices(); ++i) {
- Out << iName << "_indices.push_back("
- << evi->idx_begin()[i] << ");";
- nl(Out);
- }
- Out << "ExtractValueInst* " << getCppName(evi)
- << " = ExtractValueInst::Create(" << opNames[0]
- << ", "
- << iName << "_indices, \"";
- printEscapedString(evi->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::InsertValue: {
- const InsertValueInst *ivi = cast<InsertValueInst>(I);
- Out << "std::vector<unsigned> " << iName << "_indices;";
- nl(Out);
- for (unsigned i = 0; i < ivi->getNumIndices(); ++i) {
- Out << iName << "_indices.push_back("
- << ivi->idx_begin()[i] << ");";
- nl(Out);
- }
- Out << "InsertValueInst* " << getCppName(ivi)
- << " = InsertValueInst::Create(" << opNames[0]
- << ", " << opNames[1] << ", "
- << iName << "_indices, \"";
- printEscapedString(ivi->getName());
- Out << "\", " << bbname << ");";
- break;
- }
- case Instruction::Fence: {
- const FenceInst *fi = cast<FenceInst>(I);
- StringRef Ordering = ConvertAtomicOrdering(fi->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(fi->getSynchScope());
- Out << "FenceInst* " << iName
- << " = new FenceInst(mod->getContext(), "
- << Ordering << ", " << CrossThread << ", " << bbname
- << ");";
- break;
- }
- case Instruction::AtomicCmpXchg: {
- const AtomicCmpXchgInst *cxi = cast<AtomicCmpXchgInst>(I);
- StringRef SuccessOrdering =
- ConvertAtomicOrdering(cxi->getSuccessOrdering());
- StringRef FailureOrdering =
- ConvertAtomicOrdering(cxi->getFailureOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(cxi->getSynchScope());
- Out << "AtomicCmpXchgInst* " << iName
- << " = new AtomicCmpXchgInst("
- << opNames[0] << ", " << opNames[1] << ", " << opNames[2] << ", "
- << SuccessOrdering << ", " << FailureOrdering << ", "
- << CrossThread << ", " << bbname
- << ");";
- nl(Out) << iName << "->setName(\"";
- printEscapedString(cxi->getName());
- Out << "\");";
- nl(Out) << iName << "->setVolatile("
- << (cxi->isVolatile() ? "true" : "false") << ");";
- nl(Out) << iName << "->setWeak("
- << (cxi->isWeak() ? "true" : "false") << ");";
- break;
- }
- case Instruction::AtomicRMW: {
- const AtomicRMWInst *rmwi = cast<AtomicRMWInst>(I);
- StringRef Ordering = ConvertAtomicOrdering(rmwi->getOrdering());
- StringRef CrossThread = ConvertAtomicSynchScope(rmwi->getSynchScope());
- StringRef Operation;
- switch (rmwi->getOperation()) {
- case AtomicRMWInst::Xchg: Operation = "AtomicRMWInst::Xchg"; break;
- case AtomicRMWInst::Add: Operation = "AtomicRMWInst::Add"; break;
- case AtomicRMWInst::Sub: Operation = "AtomicRMWInst::Sub"; break;
- case AtomicRMWInst::And: Operation = "AtomicRMWInst::And"; break;
- case AtomicRMWInst::Nand: Operation = "AtomicRMWInst::Nand"; break;
- case AtomicRMWInst::Or: Operation = "AtomicRMWInst::Or"; break;
- case AtomicRMWInst::Xor: Operation = "AtomicRMWInst::Xor"; break;
- case AtomicRMWInst::Max: Operation = "AtomicRMWInst::Max"; break;
- case AtomicRMWInst::Min: Operation = "AtomicRMWInst::Min"; break;
- case AtomicRMWInst::UMax: Operation = "AtomicRMWInst::UMax"; break;
- case AtomicRMWInst::UMin: Operation = "AtomicRMWInst::UMin"; break;
- case AtomicRMWInst::BAD_BINOP: llvm_unreachable("Bad atomic operation");
- }
- Out << "AtomicRMWInst* " << iName
- << " = new AtomicRMWInst("
- << Operation << ", "
- << opNames[0] << ", " << opNames[1] << ", "
- << Ordering << ", " << CrossThread << ", " << bbname
- << ");";
- nl(Out) << iName << "->setName(\"";
- printEscapedString(rmwi->getName());
- Out << "\");";
- nl(Out) << iName << "->setVolatile("
- << (rmwi->isVolatile() ? "true" : "false") << ");";
- break;
- }
- case Instruction::LandingPad: {
- const LandingPadInst *lpi = cast<LandingPadInst>(I);
- Out << "LandingPadInst* " << iName << " = LandingPadInst::Create(";
- printCppName(lpi->getType());
- Out << ", " << opNames[0] << ", " << lpi->getNumClauses() << ", \"";
- printEscapedString(lpi->getName());
- Out << "\", " << bbname << ");";
- nl(Out) << iName << "->setCleanup("
- << (lpi->isCleanup() ? "true" : "false")
- << ");";
- for (unsigned i = 0, e = lpi->getNumClauses(); i != e; ++i)
- nl(Out) << iName << "->addClause(" << opNames[i+1] << ");";
- break;
- }
- }
- DefinedValues.insert(I);
- nl(Out);
- delete [] opNames;
-}
-
-// Print out the types, constants and declarations needed by one function
-void CppWriter::printFunctionUses(const Function* F) {
- nl(Out) << "// Type Definitions"; nl(Out);
- if (!is_inline) {
- // Print the function's return type
- printType(F->getReturnType());
-
- // Print the function's function type
- printType(F->getFunctionType());
-
- // Print the types of each of the function's arguments
- for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- AI != AE; ++AI) {
- printType(AI->getType());
- }
- }
-
- // Print type definitions for every type referenced by an instruction and
- // make a note of any global values or constants that are referenced
- SmallPtrSet<GlobalValue*,64> gvs;
- SmallPtrSet<Constant*,64> consts;
- for (Function::const_iterator BB = F->begin(), BE = F->end();
- BB != BE; ++BB){
- for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
- I != E; ++I) {
- // Print the type of the instruction itself
- printType(I->getType());
-
- // Print the type of each of the instruction's operands
- for (unsigned i = 0; i < I->getNumOperands(); ++i) {
- Value* operand = I->getOperand(i);
- printType(operand->getType());
-
- // If the operand references a GVal or Constant, make a note of it
- if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
- gvs.insert(GV);
- if (GenerationType != GenFunction)
- if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
- if (GVar->hasInitializer())
- consts.insert(GVar->getInitializer());
- } else if (Constant* C = dyn_cast<Constant>(operand)) {
- consts.insert(C);
- for (Value* operand : C->operands()) {
- // If the operand references a GVal or Constant, make a note of it
- printType(operand->getType());
- if (GlobalValue* GV = dyn_cast<GlobalValue>(operand)) {
- gvs.insert(GV);
- if (GenerationType != GenFunction)
- if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
- if (GVar->hasInitializer())
- consts.insert(GVar->getInitializer());
- }
- }
- }
- }
- }
- }
-
- // Print the function declarations for any functions encountered
- nl(Out) << "// Function Declarations"; nl(Out);
- for (auto *GV : gvs) {
- if (Function *Fun = dyn_cast<Function>(GV)) {
- if (!is_inline || Fun != F)
- printFunctionHead(Fun);
- }
- }
-
- // Print the global variable declarations for any variables encountered
- nl(Out) << "// Global Variable Declarations"; nl(Out);
- for (auto *GV : gvs) {
- if (GlobalVariable *F = dyn_cast<GlobalVariable>(GV))
- printVariableHead(F);
- }
-
- // Print the constants found
- nl(Out) << "// Constant Definitions"; nl(Out);
- for (const auto *C : consts) {
- printConstant(C);
- }
-
- // Process the global variables definitions now that all the constants have
- // been emitted. These definitions just couple the gvars with their constant
- // initializers.
- if (GenerationType != GenFunction) {
- nl(Out) << "// Global Variable Definitions"; nl(Out);
- for (auto *GV : gvs) {
- if (GlobalVariable *Var = dyn_cast<GlobalVariable>(GV))
- printVariableBody(Var);
- }
- }
-}
-
-void CppWriter::printFunctionHead(const Function* F) {
- nl(Out) << "Function* " << getCppName(F);
- Out << " = mod->getFunction(\"";
- printEscapedString(F->getName());
- Out << "\");";
- nl(Out) << "if (!" << getCppName(F) << ") {";
- nl(Out) << getCppName(F);
-
- Out<< " = Function::Create(";
- nl(Out,1) << "/*Type=*/" << getCppName(F->getFunctionType()) << ",";
- nl(Out) << "/*Linkage=*/";
- printLinkageType(F->getLinkage());
- Out << ",";
- nl(Out) << "/*Name=*/\"";
- printEscapedString(F->getName());
- Out << "\", mod); " << (F->isDeclaration()? "// (external, no body)" : "");
- nl(Out,-1);
- printCppName(F);
- Out << "->setCallingConv(";
- printCallingConv(F->getCallingConv());
- Out << ");";
- nl(Out);
- if (F->hasSection()) {
- printCppName(F);
- Out << "->setSection(\"" << F->getSection() << "\");";
- nl(Out);
- }
- if (F->getAlignment()) {
- printCppName(F);
- Out << "->setAlignment(" << F->getAlignment() << ");";
- nl(Out);
- }
- if (F->getVisibility() != GlobalValue::DefaultVisibility) {
- printCppName(F);
- Out << "->setVisibility(";
- printVisibilityType(F->getVisibility());
- Out << ");";
- nl(Out);
- }
- if (F->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
- printCppName(F);
- Out << "->setDLLStorageClass(";
- printDLLStorageClassType(F->getDLLStorageClass());
- Out << ");";
- nl(Out);
- }
- if (F->hasGC()) {
- printCppName(F);
- Out << "->setGC(\"" << F->getGC() << "\");";
- nl(Out);
- }
- Out << "}";
- nl(Out);
- printAttributes(F->getAttributes(), getCppName(F));
- printCppName(F);
- Out << "->setAttributes(" << getCppName(F) << "_PAL);";
- nl(Out);
-}
-
-void CppWriter::printFunctionBody(const Function *F) {
- if (F->isDeclaration())
- return; // external functions have no bodies.
-
- // Clear the DefinedValues and ForwardRefs maps because we can't have
- // cross-function forward refs
- ForwardRefs.clear();
- DefinedValues.clear();
-
- // Create all the argument values
- if (!is_inline) {
- if (!F->arg_empty()) {
- Out << "Function::arg_iterator args = " << getCppName(F)
- << "->arg_begin();";
- nl(Out);
- }
- for (const Argument &AI : F->args()) {
- Out << "Value* " << getCppName(&AI) << " = args++;";
- nl(Out);
- if (AI.hasName()) {
- Out << getCppName(&AI) << "->setName(\"";
- printEscapedString(AI.getName());
- Out << "\");";
- nl(Out);
- }
- }
- }
-
- // Create all the basic blocks
- nl(Out);
- for (const BasicBlock &BI : *F) {
- std::string bbname(getCppName(&BI));
- Out << "BasicBlock* " << bbname <<
- " = BasicBlock::Create(mod->getContext(), \"";
- if (BI.hasName())
- printEscapedString(BI.getName());
- Out << "\"," << getCppName(BI.getParent()) << ",0);";
- nl(Out);
- }
-
- // Output all of its basic blocks... for the function
- for (const BasicBlock &BI : *F) {
- std::string bbname(getCppName(&BI));
- nl(Out) << "// Block " << BI.getName() << " (" << bbname << ")";
- nl(Out);
-
- // Output all of the instructions in the basic block...
- for (const Instruction &I : BI)
- printInstruction(&I, bbname);
- }
-
- // Loop over the ForwardRefs and resolve them now that all instructions
- // are generated.
- if (!ForwardRefs.empty()) {
- nl(Out) << "// Resolve Forward References";
- nl(Out);
- }
-
- while (!ForwardRefs.empty()) {
- ForwardRefMap::iterator I = ForwardRefs.begin();
- Out << I->second << "->replaceAllUsesWith("
- << getCppName(I->first) << "); delete " << I->second << ";";
- nl(Out);
- ForwardRefs.erase(I);
- }
-}
-
-void CppWriter::printInline(const std::string& fname,
- const std::string& func) {
- const Function* F = TheModule->getFunction(func);
- if (!F) {
- error(std::string("Function '") + func + "' not found in input module");
- return;
- }
- if (F->isDeclaration()) {
- error(std::string("Function '") + func + "' is external!");
- return;
- }
- nl(Out) << "BasicBlock* " << fname << "(Module* mod, Function *"
- << getCppName(F);
- unsigned arg_count = 1;
- for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
- AI != AE; ++AI) {
- Out << ", Value* arg_" << arg_count++;
- }
- Out << ") {";
- nl(Out);
- is_inline = true;
- printFunctionUses(F);
- printFunctionBody(F);
- is_inline = false;
- Out << "return " << getCppName(&F->front()) << ";";
- nl(Out) << "}";
- nl(Out);
-}
-
-void CppWriter::printModuleBody() {
- // Print out all the type definitions
- nl(Out) << "// Type Definitions"; nl(Out);
- printTypes(TheModule);
-
- // Functions can call each other and global variables can reference them so
- // define all the functions first before emitting their function bodies.
- nl(Out) << "// Function Declarations"; nl(Out);
- for (const Function &I : *TheModule)
- printFunctionHead(&I);
-
- // Process the global variables declarations. We can't initialze them until
- // after the constants are printed so just print a header for each global
- nl(Out) << "// Global Variable Declarations\n"; nl(Out);
- for (const GlobalVariable &I : TheModule->globals())
- printVariableHead(&I);
-
- // Print out all the constants definitions. Constants don't recurse except
- // through GlobalValues. All GlobalValues have been declared at this point
- // so we can proceed to generate the constants.
- nl(Out) << "// Constant Definitions"; nl(Out);
- printConstants(TheModule);
-
- // Process the global variables definitions now that all the constants have
- // been emitted. These definitions just couple the gvars with their constant
- // initializers.
- nl(Out) << "// Global Variable Definitions"; nl(Out);
- for (const GlobalVariable &I : TheModule->globals())
- printVariableBody(&I);
-
- // Finally, we can safely put out all of the function bodies.
- nl(Out) << "// Function Definitions"; nl(Out);
- for (const Function &I : *TheModule) {
- if (!I.isDeclaration()) {
- nl(Out) << "// Function: " << I.getName() << " (" << getCppName(&I)
- << ")";
- nl(Out) << "{";
- nl(Out,1);
- printFunctionBody(&I);
- nl(Out,-1) << "}";
- nl(Out);
- }
- }
-}
-
-void CppWriter::printProgram(const std::string& fname,
- const std::string& mName) {
- Out << "#include <llvm/Pass.h>\n";
-
- Out << "#include <llvm/ADT/SmallVector.h>\n";
- Out << "#include <llvm/Analysis/Verifier.h>\n";
- Out << "#include <llvm/IR/BasicBlock.h>\n";
- Out << "#include <llvm/IR/CallingConv.h>\n";
- Out << "#include <llvm/IR/Constants.h>\n";
- Out << "#include <llvm/IR/DerivedTypes.h>\n";
- Out << "#include <llvm/IR/Function.h>\n";
- Out << "#include <llvm/IR/GlobalVariable.h>\n";
- Out << "#include <llvm/IR/IRPrintingPasses.h>\n";
- Out << "#include <llvm/IR/InlineAsm.h>\n";
- Out << "#include <llvm/IR/Instructions.h>\n";
- Out << "#include <llvm/IR/LLVMContext.h>\n";
- Out << "#include <llvm/IR/LegacyPassManager.h>\n";
- Out << "#include <llvm/IR/Module.h>\n";
- Out << "#include <llvm/Support/FormattedStream.h>\n";
- Out << "#include <llvm/Support/MathExtras.h>\n";
- Out << "#include <algorithm>\n";
- Out << "using namespace llvm;\n\n";
- Out << "Module* " << fname << "();\n\n";
- Out << "int main(int argc, char**argv) {\n";
- Out << " Module* Mod = " << fname << "();\n";
- Out << " verifyModule(*Mod, PrintMessageAction);\n";
- Out << " PassManager PM;\n";
- Out << " PM.add(createPrintModulePass(&outs()));\n";
- Out << " PM.run(*Mod);\n";
- Out << " return 0;\n";
- Out << "}\n\n";
- printModule(fname,mName);
-}
-
-void CppWriter::printModule(const std::string& fname,
- const std::string& mName) {
- nl(Out) << "Module* " << fname << "() {";
- nl(Out,1) << "// Module Construction";
- nl(Out) << "Module* mod = new Module(\"";
- printEscapedString(mName);
- Out << "\", getGlobalContext());";
- if (!TheModule->getTargetTriple().empty()) {
- nl(Out) << "mod->setDataLayout(\"" << TheModule->getDataLayoutStr()
- << "\");";
- }
- if (!TheModule->getTargetTriple().empty()) {
- nl(Out) << "mod->setTargetTriple(\"" << TheModule->getTargetTriple()
- << "\");";
- }
-
- if (!TheModule->getModuleInlineAsm().empty()) {
- nl(Out) << "mod->setModuleInlineAsm(\"";
- printEscapedString(TheModule->getModuleInlineAsm());
- Out << "\");";
- }
- nl(Out);
-
- printModuleBody();
- nl(Out) << "return mod;";
- nl(Out,-1) << "}";
- nl(Out);
-}
-
-void CppWriter::printContents(const std::string& fname,
- const std::string& mName) {
- Out << "\nModule* " << fname << "(Module *mod) {\n";
- Out << "\nmod->setModuleIdentifier(\"";
- printEscapedString(mName);
- Out << "\");\n";
- printModuleBody();
- Out << "\nreturn mod;\n";
- Out << "\n}\n";
-}
-
-void CppWriter::printFunction(const std::string& fname,
- const std::string& funcName) {
- const Function* F = TheModule->getFunction(funcName);
- if (!F) {
- error(std::string("Function '") + funcName + "' not found in input module");
- return;
- }
- Out << "\nFunction* " << fname << "(Module *mod) {\n";
- printFunctionUses(F);
- printFunctionHead(F);
- printFunctionBody(F);
- Out << "return " << getCppName(F) << ";\n";
- Out << "}\n";
-}
-
-void CppWriter::printFunctions() {
- const Module::FunctionListType &funcs = TheModule->getFunctionList();
- Module::const_iterator I = funcs.begin();
- Module::const_iterator IE = funcs.end();
-
- for (; I != IE; ++I) {
- const Function &func = *I;
- if (!func.isDeclaration()) {
- std::string name("define_");
- name += func.getName();
- printFunction(name, func.getName());
- }
- }
-}
-
-void CppWriter::printVariable(const std::string& fname,
- const std::string& varName) {
- const GlobalVariable* GV = TheModule->getNamedGlobal(varName);
-
- if (!GV) {
- error(std::string("Variable '") + varName + "' not found in input module");
- return;
- }
- Out << "\nGlobalVariable* " << fname << "(Module *mod) {\n";
- printVariableUses(GV);
- printVariableHead(GV);
- printVariableBody(GV);
- Out << "return " << getCppName(GV) << ";\n";
- Out << "}\n";
-}
-
-void CppWriter::printType(const std::string &fname,
- const std::string &typeName) {
- Type* Ty = TheModule->getTypeByName(typeName);
- if (!Ty) {
- error(std::string("Type '") + typeName + "' not found in input module");
- return;
- }
- Out << "\nType* " << fname << "(Module *mod) {\n";
- printType(Ty);
- Out << "return " << getCppName(Ty) << ";\n";
- Out << "}\n";
-}
-
-bool CppWriter::runOnModule(Module &M) {
- TheModule = &M;
-
- // Emit a header
- Out << "// Generated by llvm2cpp - DO NOT MODIFY!\n\n";
-
- // Get the name of the function we're supposed to generate
- std::string fname = FuncName.getValue();
-
- // Get the name of the thing we are to generate
- std::string tgtname = NameToGenerate.getValue();
- if (GenerationType == GenModule ||
- GenerationType == GenContents ||
- GenerationType == GenProgram ||
- GenerationType == GenFunctions) {
- if (tgtname == "!bad!") {
- if (M.getModuleIdentifier() == "-")
- tgtname = "<stdin>";
- else
- tgtname = M.getModuleIdentifier();
- }
- } else if (tgtname == "!bad!")
- error("You must use the -for option with -gen-{function,variable,type}");
-
- switch (WhatToGenerate(GenerationType)) {
- case GenProgram:
- if (fname.empty())
- fname = "makeLLVMModule";
- printProgram(fname,tgtname);
- break;
- case GenModule:
- if (fname.empty())
- fname = "makeLLVMModule";
- printModule(fname,tgtname);
- break;
- case GenContents:
- if (fname.empty())
- fname = "makeLLVMModuleContents";
- printContents(fname,tgtname);
- break;
- case GenFunction:
- if (fname.empty())
- fname = "makeLLVMFunction";
- printFunction(fname,tgtname);
- break;
- case GenFunctions:
- printFunctions();
- break;
- case GenInline:
- if (fname.empty())
- fname = "makeLLVMInline";
- printInline(fname,tgtname);
- break;
- case GenVariable:
- if (fname.empty())
- fname = "makeLLVMVariable";
- printVariable(fname,tgtname);
- break;
- case GenType:
- if (fname.empty())
- fname = "makeLLVMType";
- printType(fname,tgtname);
- break;
- }
-
- return false;
-}
-
-char CppWriter::ID = 0;
-
-//===----------------------------------------------------------------------===//
-// External Interface declaration
-//===----------------------------------------------------------------------===//
-
-bool CPPTargetMachine::addPassesToEmitFile(
- PassManagerBase &PM, raw_pwrite_stream &o, CodeGenFileType FileType,
- bool DisableVerify, AnalysisID StartBefore, AnalysisID StartAfter,
- AnalysisID StopAfter, MachineFunctionInitializer *MFInitializer) {
- if (FileType != TargetMachine::CGFT_AssemblyFile)
- return true;
- auto FOut = llvm::make_unique<formatted_raw_ostream>(o);
- PM.add(new CppWriter(std::move(FOut)));
- return false;
-}
diff --git a/gnu/llvm/lib/Target/CppBackend/CPPTargetMachine.h b/gnu/llvm/lib/Target/CppBackend/CPPTargetMachine.h
deleted file mode 100644
index 00e402feffb..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/CPPTargetMachine.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- CPPTargetMachine.h - TargetMachine for the C++ backend --*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the TargetMachine that is used by the C++ backend.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_CPPBACKEND_CPPTARGETMACHINE_H
-#define LLVM_LIB_TARGET_CPPBACKEND_CPPTARGETMACHINE_H
-
-#include "llvm/IR/DataLayout.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-
-namespace llvm {
-
-class formatted_raw_ostream;
-
-struct CPPTargetMachine : public TargetMachine {
- CPPTargetMachine(const Target &T, const Triple &TT, StringRef CPU,
- StringRef FS, const TargetOptions &Options, Reloc::Model RM,
- CodeModel::Model CM, CodeGenOpt::Level OL)
- : TargetMachine(T, "", TT, CPU, FS, Options) {}
-
-public:
- bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
- CodeGenFileType FileType, bool DisableVerify,
- AnalysisID StartBefore, AnalysisID StartAfter,
- AnalysisID StopAfter,
- MachineFunctionInitializer *MFInitializer) override;
-};
-
-extern Target TheCppBackendTarget;
-
-} // End llvm namespace
-
-
-#endif
diff --git a/gnu/llvm/lib/Target/CppBackend/LLVMBuild.txt b/gnu/llvm/lib/Target/CppBackend/LLVMBuild.txt
deleted file mode 100644
index 122b5e7502f..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/LLVMBuild.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-;===- ./lib/Target/CppBackend/LLVMBuild.txt --------------------*- Conf -*--===;
-;
-; The LLVM Compiler Infrastructure
-;
-; This file is distributed under the University of Illinois Open Source
-; License. See LICENSE.TXT for details.
-;
-;===------------------------------------------------------------------------===;
-;
-; This is an LLVMBuild description file for the components in this subdirectory.
-;
-; For more information on the LLVMBuild system, please see:
-;
-; http://llvm.org/docs/LLVMBuild.html
-;
-;===------------------------------------------------------------------------===;
-
-[common]
-subdirectories = TargetInfo
-
-[component_0]
-type = TargetGroup
-name = CppBackend
-parent = Target
-
-[component_1]
-type = Library
-name = CppBackendCodeGen
-parent = CppBackend
-required_libraries = Core CppBackendInfo Support Target
-add_to_library_groups = CppBackend
diff --git a/gnu/llvm/lib/Target/CppBackend/Makefile b/gnu/llvm/lib/Target/CppBackend/Makefile
deleted file mode 100644
index efc7463fda3..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/CppBackend/Makefile --- ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMCppBackendCodeGen
-DIRS = TargetInfo
-
-include $(LEVEL)/Makefile.common
-
-CompileCommonOpts += -Wno-format
diff --git a/gnu/llvm/lib/Target/CppBackend/TargetInfo/CMakeLists.txt b/gnu/llvm/lib/Target/CppBackend/TargetInfo/CMakeLists.txt
deleted file mode 100644
index d86446f6bc0..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/TargetInfo/CMakeLists.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-add_llvm_library(LLVMCppBackendInfo
- CppBackendTargetInfo.cpp
- )
diff --git a/gnu/llvm/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp b/gnu/llvm/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp
deleted file mode 100644
index f88d82228ca..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/TargetInfo/CppBackendTargetInfo.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===-- CppBackendTargetInfo.cpp - CppBackend Target Implementation -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "CPPTargetMachine.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/TargetRegistry.h"
-using namespace llvm;
-
-Target llvm::TheCppBackendTarget;
-
-static bool CppBackend_TripleMatchQuality(Triple::ArchType Arch) {
- // This backend doesn't correspond to any architecture. It must be explicitly
- // selected with -march.
- return false;
-}
-
-extern "C" void LLVMInitializeCppBackendTargetInfo() {
- TargetRegistry::RegisterTarget(TheCppBackendTarget, "cpp",
- "C++ backend",
- &CppBackend_TripleMatchQuality);
-}
-
-extern "C" void LLVMInitializeCppBackendTargetMC() {}
diff --git a/gnu/llvm/lib/Target/CppBackend/TargetInfo/LLVMBuild.txt b/gnu/llvm/lib/Target/CppBackend/TargetInfo/LLVMBuild.txt
deleted file mode 100644
index 9c186a52f4f..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/TargetInfo/LLVMBuild.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-;===- ./lib/Target/CppBackend/TargetInfo/LLVMBuild.txt ---------*- Conf -*--===;
-;
-; The LLVM Compiler Infrastructure
-;
-; This file is distributed under the University of Illinois Open Source
-; License. See LICENSE.TXT for details.
-;
-;===------------------------------------------------------------------------===;
-;
-; This is an LLVMBuild description file for the components in this subdirectory.
-;
-; For more information on the LLVMBuild system, please see:
-;
-; http://llvm.org/docs/LLVMBuild.html
-;
-;===------------------------------------------------------------------------===;
-
-[component_0]
-type = Library
-name = CppBackendInfo
-parent = CppBackend
-required_libraries = Support
-add_to_library_groups = CppBackend
diff --git a/gnu/llvm/lib/Target/CppBackend/TargetInfo/Makefile b/gnu/llvm/lib/Target/CppBackend/TargetInfo/Makefile
deleted file mode 100644
index 6e682838dae..00000000000
--- a/gnu/llvm/lib/Target/CppBackend/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/CppBackend/TargetInfo/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMCppBackendInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Hexagon/AsmParser/Makefile b/gnu/llvm/lib/Target/Hexagon/AsmParser/Makefile
deleted file mode 100644
index 0aa0b4140c3..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Hexagon/AsmParser/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMHexagonAsmParser
-
-# Hack: we need to include 'main' Hexagon target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Hexagon/Disassembler/Makefile b/gnu/llvm/lib/Target/Hexagon/Disassembler/Makefile
deleted file mode 100644
index 16c305fe407..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===-- lib/Target/Hexagon/Disassembler/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMHexagonDisassembler
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp b/gnu/llvm/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
deleted file mode 100644
index 6e2dbc06b12..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/HexagonExpandPredSpillCode.cpp
+++ /dev/null
@@ -1,357 +0,0 @@
-//===-- HexagonExpandPredSpillCode.cpp - Expand Predicate Spill Code ------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// The Hexagon processor has no instructions that load or store predicate
-// registers directly. So, when these registers must be spilled a general
-// purpose register must be found and the value copied to/from it from/to
-// the predicate register. This code currently does not use the register
-// scavenger mechanism available in the allocator. There are two registers
-// reserved to allow spilling/restoring predicate registers. One is used to
-// hold the predicate value. The other is used when stack frame offsets are
-// too large.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Hexagon.h"
-#include "HexagonMachineFunctionInfo.h"
-#include "HexagonSubtarget.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/LatencyPriorityQueue.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
-#include "llvm/CodeGen/SchedulerRegistry.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-
-using namespace llvm;
-
-
-namespace llvm {
- FunctionPass *createHexagonExpandPredSpillCode();
- void initializeHexagonExpandPredSpillCodePass(PassRegistry&);
-}
-
-
-namespace {
-
-class HexagonExpandPredSpillCode : public MachineFunctionPass {
- public:
- static char ID;
- HexagonExpandPredSpillCode() : MachineFunctionPass(ID) {
- PassRegistry &Registry = *PassRegistry::getPassRegistry();
- initializeHexagonExpandPredSpillCodePass(Registry);
- }
-
- const char *getPassName() const override {
- return "Hexagon Expand Predicate Spill Code";
- }
- bool runOnMachineFunction(MachineFunction &Fn) override;
-};
-
-
-char HexagonExpandPredSpillCode::ID = 0;
-
-
-bool HexagonExpandPredSpillCode::runOnMachineFunction(MachineFunction &Fn) {
-
- const HexagonSubtarget &QST = Fn.getSubtarget<HexagonSubtarget>();
- const HexagonInstrInfo *TII = QST.getInstrInfo();
-
- // Loop over all of the basic blocks.
- for (MachineFunction::iterator MBBb = Fn.begin(), MBBe = Fn.end();
- MBBb != MBBe; ++MBBb) {
- MachineBasicBlock *MBB = &*MBBb;
- // Traverse the basic block.
- for (MachineBasicBlock::iterator MII = MBB->begin(); MII != MBB->end();
- ++MII) {
- MachineInstr *MI = MII;
- int Opc = MI->getOpcode();
- if (Opc == Hexagon::S2_storerb_pci_pseudo ||
- Opc == Hexagon::S2_storerh_pci_pseudo ||
- Opc == Hexagon::S2_storeri_pci_pseudo ||
- Opc == Hexagon::S2_storerd_pci_pseudo ||
- Opc == Hexagon::S2_storerf_pci_pseudo) {
- unsigned Opcode;
- if (Opc == Hexagon::S2_storerd_pci_pseudo)
- Opcode = Hexagon::S2_storerd_pci;
- else if (Opc == Hexagon::S2_storeri_pci_pseudo)
- Opcode = Hexagon::S2_storeri_pci;
- else if (Opc == Hexagon::S2_storerh_pci_pseudo)
- Opcode = Hexagon::S2_storerh_pci;
- else if (Opc == Hexagon::S2_storerf_pci_pseudo)
- Opcode = Hexagon::S2_storerf_pci;
- else if (Opc == Hexagon::S2_storerb_pci_pseudo)
- Opcode = Hexagon::S2_storerb_pci;
- else
- llvm_unreachable("wrong Opc");
- MachineOperand &Op0 = MI->getOperand(0);
- MachineOperand &Op1 = MI->getOperand(1);
- MachineOperand &Op2 = MI->getOperand(2);
- MachineOperand &Op3 = MI->getOperand(3); // Modifier value.
- MachineOperand &Op4 = MI->getOperand(4);
- // Emit a "C6 = Rn, C6 is the control register for M0".
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr),
- Hexagon::C6)->addOperand(Op3);
- // Replace the pseude circ_ldd by the real circ_ldd.
- MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Opcode));
- NewMI->addOperand(Op0);
- NewMI->addOperand(Op1);
- NewMI->addOperand(Op4);
- NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0,
- false, /*isDef*/
- false, /*isImpl*/
- true /*isKill*/));
- NewMI->addOperand(Op2);
- MII = MBB->erase(MI);
- --MII;
- } else if (Opc == Hexagon::L2_loadrd_pci_pseudo ||
- Opc == Hexagon::L2_loadri_pci_pseudo ||
- Opc == Hexagon::L2_loadrh_pci_pseudo ||
- Opc == Hexagon::L2_loadruh_pci_pseudo||
- Opc == Hexagon::L2_loadrb_pci_pseudo ||
- Opc == Hexagon::L2_loadrub_pci_pseudo) {
- unsigned Opcode;
- if (Opc == Hexagon::L2_loadrd_pci_pseudo)
- Opcode = Hexagon::L2_loadrd_pci;
- else if (Opc == Hexagon::L2_loadri_pci_pseudo)
- Opcode = Hexagon::L2_loadri_pci;
- else if (Opc == Hexagon::L2_loadrh_pci_pseudo)
- Opcode = Hexagon::L2_loadrh_pci;
- else if (Opc == Hexagon::L2_loadruh_pci_pseudo)
- Opcode = Hexagon::L2_loadruh_pci;
- else if (Opc == Hexagon::L2_loadrb_pci_pseudo)
- Opcode = Hexagon::L2_loadrb_pci;
- else if (Opc == Hexagon::L2_loadrub_pci_pseudo)
- Opcode = Hexagon::L2_loadrub_pci;
- else
- llvm_unreachable("wrong Opc");
-
- MachineOperand &Op0 = MI->getOperand(0);
- MachineOperand &Op1 = MI->getOperand(1);
- MachineOperand &Op2 = MI->getOperand(2);
- MachineOperand &Op4 = MI->getOperand(4); // Modifier value.
- MachineOperand &Op5 = MI->getOperand(5);
- // Emit a "C6 = Rn, C6 is the control register for M0".
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr),
- Hexagon::C6)->addOperand(Op4);
- // Replace the pseude circ_ldd by the real circ_ldd.
- MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Opcode));
- NewMI->addOperand(Op1);
- NewMI->addOperand(Op0);
- NewMI->addOperand(Op2);
- NewMI->addOperand(Op5);
- NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0,
- false, /*isDef*/
- false, /*isImpl*/
- true /*isKill*/));
- MII = MBB->erase(MI);
- --MII;
- } else if (Opc == Hexagon::L2_loadrd_pbr_pseudo ||
- Opc == Hexagon::L2_loadri_pbr_pseudo ||
- Opc == Hexagon::L2_loadrh_pbr_pseudo ||
- Opc == Hexagon::L2_loadruh_pbr_pseudo||
- Opc == Hexagon::L2_loadrb_pbr_pseudo ||
- Opc == Hexagon::L2_loadrub_pbr_pseudo) {
- unsigned Opcode;
- if (Opc == Hexagon::L2_loadrd_pbr_pseudo)
- Opcode = Hexagon::L2_loadrd_pbr;
- else if (Opc == Hexagon::L2_loadri_pbr_pseudo)
- Opcode = Hexagon::L2_loadri_pbr;
- else if (Opc == Hexagon::L2_loadrh_pbr_pseudo)
- Opcode = Hexagon::L2_loadrh_pbr;
- else if (Opc == Hexagon::L2_loadruh_pbr_pseudo)
- Opcode = Hexagon::L2_loadruh_pbr;
- else if (Opc == Hexagon::L2_loadrb_pbr_pseudo)
- Opcode = Hexagon::L2_loadrb_pbr;
- else if (Opc == Hexagon::L2_loadrub_pbr_pseudo)
- Opcode = Hexagon::L2_loadrub_pbr;
- else
- llvm_unreachable("wrong Opc");
- MachineOperand &Op0 = MI->getOperand(0);
- MachineOperand &Op1 = MI->getOperand(1);
- MachineOperand &Op2 = MI->getOperand(2);
- MachineOperand &Op4 = MI->getOperand(4); // Modifier value.
- // Emit a "C6 = Rn, C6 is the control register for M0".
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr),
- Hexagon::C6)->addOperand(Op4);
- // Replace the pseudo brev_ldd by the real brev_ldd.
- MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Opcode));
- NewMI->addOperand(Op1);
- NewMI->addOperand(Op0);
- NewMI->addOperand(Op2);
- NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0,
- false, /*isDef*/
- false, /*isImpl*/
- true /*isKill*/));
- MII = MBB->erase(MI);
- --MII;
- } else if (Opc == Hexagon::S2_storerd_pbr_pseudo ||
- Opc == Hexagon::S2_storeri_pbr_pseudo ||
- Opc == Hexagon::S2_storerh_pbr_pseudo ||
- Opc == Hexagon::S2_storerb_pbr_pseudo ||
- Opc == Hexagon::S2_storerf_pbr_pseudo) {
- unsigned Opcode;
- if (Opc == Hexagon::S2_storerd_pbr_pseudo)
- Opcode = Hexagon::S2_storerd_pbr;
- else if (Opc == Hexagon::S2_storeri_pbr_pseudo)
- Opcode = Hexagon::S2_storeri_pbr;
- else if (Opc == Hexagon::S2_storerh_pbr_pseudo)
- Opcode = Hexagon::S2_storerh_pbr;
- else if (Opc == Hexagon::S2_storerf_pbr_pseudo)
- Opcode = Hexagon::S2_storerf_pbr;
- else if (Opc == Hexagon::S2_storerb_pbr_pseudo)
- Opcode = Hexagon::S2_storerb_pbr;
- else
- llvm_unreachable("wrong Opc");
- MachineOperand &Op0 = MI->getOperand(0);
- MachineOperand &Op1 = MI->getOperand(1);
- MachineOperand &Op2 = MI->getOperand(2);
- MachineOperand &Op3 = MI->getOperand(3); // Modifier value.
- // Emit a "C6 = Rn, C6 is the control register for M0".
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_tfrrcr),
- Hexagon::C6)->addOperand(Op3);
- // Replace the pseudo brev_ldd by the real brev_ldd.
- MachineInstr *NewMI = BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Opcode));
- NewMI->addOperand(Op0);
- NewMI->addOperand(Op1);
- NewMI->addOperand(MachineOperand::CreateReg(Hexagon::M0,
- false, /*isDef*/
- false, /*isImpl*/
- true /*isKill*/));
- NewMI->addOperand(Op2);
- MII = MBB->erase(MI);
- --MII;
- } else if (Opc == Hexagon::STriw_pred) {
- // STriw_pred [R30], ofst, SrcReg;
- unsigned FP = MI->getOperand(0).getReg();
- assert(FP == QST.getRegisterInfo()->getFrameRegister() &&
- "Not a Frame Pointer, Nor a Spill Slot");
- assert(MI->getOperand(1).isImm() && "Not an offset");
- int Offset = MI->getOperand(1).getImm();
- int SrcReg = MI->getOperand(2).getReg();
- assert(Hexagon::PredRegsRegClass.contains(SrcReg) &&
- "Not a predicate register");
- if (!TII->isValidOffset(Hexagon::S2_storeri_io, Offset)) {
- if (!TII->isValidOffset(Hexagon::A2_addi, Offset)) {
- BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::CONST32_Int_Real),
- HEXAGON_RESERVED_REG_1).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
- HEXAGON_RESERVED_REG_1)
- .addReg(FP).addReg(HEXAGON_RESERVED_REG_1);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
- HEXAGON_RESERVED_REG_2).addReg(SrcReg);
- BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::S2_storeri_io))
- .addReg(HEXAGON_RESERVED_REG_1)
- .addImm(0).addReg(HEXAGON_RESERVED_REG_2);
- } else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_addi),
- HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
- HEXAGON_RESERVED_REG_2).addReg(SrcReg);
- BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::S2_storeri_io))
- .addReg(HEXAGON_RESERVED_REG_1)
- .addImm(0)
- .addReg(HEXAGON_RESERVED_REG_2);
- }
- } else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrpr),
- HEXAGON_RESERVED_REG_2).addReg(SrcReg);
- BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::S2_storeri_io)).
- addReg(FP).addImm(Offset).addReg(HEXAGON_RESERVED_REG_2);
- }
- MII = MBB->erase(MI);
- --MII;
- } else if (Opc == Hexagon::LDriw_pred) {
- // DstReg = LDriw_pred [R30], ofst.
- int DstReg = MI->getOperand(0).getReg();
- assert(Hexagon::PredRegsRegClass.contains(DstReg) &&
- "Not a predicate register");
- unsigned FP = MI->getOperand(1).getReg();
- assert(FP == QST.getRegisterInfo()->getFrameRegister() &&
- "Not a Frame Pointer, Nor a Spill Slot");
- assert(MI->getOperand(2).isImm() && "Not an offset");
- int Offset = MI->getOperand(2).getImm();
- if (!TII->isValidOffset(Hexagon::L2_loadri_io, Offset)) {
- if (!TII->isValidOffset(Hexagon::A2_addi, Offset)) {
- BuildMI(*MBB, MII, MI->getDebugLoc(),
- TII->get(Hexagon::CONST32_Int_Real),
- HEXAGON_RESERVED_REG_1).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_add),
- HEXAGON_RESERVED_REG_1)
- .addReg(FP)
- .addReg(HEXAGON_RESERVED_REG_1);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
- HEXAGON_RESERVED_REG_2)
- .addReg(HEXAGON_RESERVED_REG_1)
- .addImm(0);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
- DstReg).addReg(HEXAGON_RESERVED_REG_2);
- } else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::A2_addi),
- HEXAGON_RESERVED_REG_1).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
- HEXAGON_RESERVED_REG_2)
- .addReg(HEXAGON_RESERVED_REG_1)
- .addImm(0);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
- DstReg).addReg(HEXAGON_RESERVED_REG_2);
- }
- } else {
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::L2_loadri_io),
- HEXAGON_RESERVED_REG_2).addReg(FP).addImm(Offset);
- BuildMI(*MBB, MII, MI->getDebugLoc(), TII->get(Hexagon::C2_tfrrp),
- DstReg).addReg(HEXAGON_RESERVED_REG_2);
- }
- MII = MBB->erase(MI);
- --MII;
- }
- }
- }
-
- return true;
-}
-
-}
-
-//===----------------------------------------------------------------------===//
-// Public Constructor Functions
-//===----------------------------------------------------------------------===//
-
-static void initializePassOnce(PassRegistry &Registry) {
- const char *Name = "Hexagon Expand Predicate Spill Code";
- PassInfo *PI = new PassInfo(Name, "hexagon-spill-pred",
- &HexagonExpandPredSpillCode::ID,
- nullptr, false, false);
- Registry.registerPass(*PI, true);
-}
-
-void llvm::initializeHexagonExpandPredSpillCodePass(PassRegistry &Registry) {
- CALL_ONCE_INITIALIZATION(initializePassOnce)
-}
-
-FunctionPass*
-llvm::createHexagonExpandPredSpillCode() {
- return new HexagonExpandPredSpillCode();
-}
diff --git a/gnu/llvm/lib/Target/Hexagon/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/Hexagon/MCTargetDesc/Makefile
deleted file mode 100644
index 885be2ddbd8..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Hexagon/TargetDesc/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMHexagonDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Hexagon/Makefile b/gnu/llvm/lib/Target/Hexagon/Makefile
deleted file mode 100644
index c53b8e56aaf..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-##===- lib/Target/Hexagon/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../..
-LIBRARYNAME = LLVMHexagonCodeGen
-TARGET = Hexagon
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = HexagonGenRegisterInfo.inc \
- HexagonGenInstrInfo.inc \
- HexagonGenAsmMatcher.inc \
- HexagonGenAsmWriter.inc \
- HexagonGenDAGISel.inc HexagonGenSubtargetInfo.inc \
- HexagonGenCallingConv.inc \
- HexagonGenDFAPacketizer.inc \
- HexagonGenMCCodeEmitter.inc \
- HexagonGenDisassemblerTables.inc
-
-DIRS = TargetInfo MCTargetDesc Disassembler AsmParser
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Hexagon/TargetInfo/Makefile b/gnu/llvm/lib/Target/Hexagon/TargetInfo/Makefile
deleted file mode 100644
index 494cca11224..00000000000
--- a/gnu/llvm/lib/Target/Hexagon/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Hexagon/TargetInfo/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMHexagonInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/MSP430/InstPrinter/Makefile b/gnu/llvm/lib/Target/MSP430/InstPrinter/Makefile
deleted file mode 100644
index a5293ab8a23..00000000000
--- a/gnu/llvm/lib/Target/MSP430/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/MSP430/AsmPrinter/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMSP430AsmPrinter
-
-# Hack: we need to include 'main' MSP430 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/MSP430/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/MSP430/MCTargetDesc/Makefile
deleted file mode 100644
index bb857998eef..00000000000
--- a/gnu/llvm/lib/Target/MSP430/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/MSP430/TargetDesc/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMSP430Desc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/MSP430/Makefile b/gnu/llvm/lib/Target/MSP430/Makefile
deleted file mode 100644
index 82216edd81e..00000000000
--- a/gnu/llvm/lib/Target/MSP430/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Target/MSP430/Makefile --------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMSP430CodeGen
-TARGET = MSP430
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = MSP430GenRegisterInfo.inc MSP430GenInstrInfo.inc \
- MSP430GenAsmWriter.inc \
- MSP430GenDAGISel.inc MSP430GenCallingConv.inc \
- MSP430GenSubtargetInfo.inc
-
-DIRS = InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/MSP430/TargetInfo/Makefile b/gnu/llvm/lib/Target/MSP430/TargetInfo/Makefile
deleted file mode 100644
index abb08f2548e..00000000000
--- a/gnu/llvm/lib/Target/MSP430/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/MSP430/TargetInfo/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMSP430Info
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Makefile b/gnu/llvm/lib/Target/Makefile
deleted file mode 100644
index 50a360f1f86..00000000000
--- a/gnu/llvm/lib/Target/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-#===- lib/Target/Makefile ----------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-LIBRARYNAME = LLVMTarget
-BUILD_ARCHIVE = 1
-
-# We include this early so we can access the value of TARGETS_TO_BUILD as the
-# value for PARALLEL_DIRS which must be set before Makefile.rules is included
-include $(LEVEL)/Makefile.config
-
-PARALLEL_DIRS := $(TARGETS_TO_BUILD)
-
-include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/gnu/llvm/lib/Target/Mips/AsmParser/Makefile b/gnu/llvm/lib/Target/Mips/AsmParser/Makefile
deleted file mode 100644
index 679acee9fe7..00000000000
--- a/gnu/llvm/lib/Target/Mips/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Mips/AsmParser/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMipsAsmParser
-
-# Hack: we need to include 'main' mips target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Mips/Disassembler/Makefile b/gnu/llvm/lib/Target/Mips/Disassembler/Makefile
deleted file mode 100644
index 7900373dd2b..00000000000
--- a/gnu/llvm/lib/Target/Mips/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Mips/Disassembler/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMipsDisassembler
-
-# Hack: we need to include 'main' Mips target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Mips/InstPrinter/Makefile b/gnu/llvm/lib/Target/Mips/InstPrinter/Makefile
deleted file mode 100644
index f07f3ed381e..00000000000
--- a/gnu/llvm/lib/Target/Mips/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Mips/AsmPrinter/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMipsAsmPrinter
-
-# Hack: we need to include 'main' mips target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Mips/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/Mips/MCTargetDesc/Makefile
deleted file mode 100644
index 22a27218f28..00000000000
--- a/gnu/llvm/lib/Target/Mips/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-##===- lib/Target/Mips/TargetDesc/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMipsDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/Mips/Makefile b/gnu/llvm/lib/Target/Mips/Makefile
deleted file mode 100644
index 56db450f696..00000000000
--- a/gnu/llvm/lib/Target/Mips/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===- lib/Target/Mips/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMMipsCodeGen
-TARGET = Mips
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
- MipsGenAsmWriter.inc MipsGenFastISel.inc \
- MipsGenDAGISel.inc MipsGenCallingConv.inc \
- MipsGenSubtargetInfo.inc MipsGenMCCodeEmitter.inc \
- MipsGenDisassemblerTables.inc \
- MipsGenMCPseudoLowering.inc MipsGenAsmMatcher.inc
-
-DIRS = InstPrinter Disassembler AsmParser TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/Mips/TargetInfo/Makefile b/gnu/llvm/lib/Target/Mips/TargetInfo/Makefile
deleted file mode 100644
index 32f4e1695b1..00000000000
--- a/gnu/llvm/lib/Target/Mips/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Mips/TargetInfo/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMMipsInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/NVPTX/InstPrinter/Makefile b/gnu/llvm/lib/Target/NVPTX/InstPrinter/Makefile
deleted file mode 100644
index 7b7865436bf..00000000000
--- a/gnu/llvm/lib/Target/NVPTX/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/NVPTX/AsmPrinter/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMNVPTXAsmPrinter
-
-# Hack: we need to include 'main' ptx target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/NVPTX/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/NVPTX/MCTargetDesc/Makefile
deleted file mode 100644
index 31d06cb5948..00000000000
--- a/gnu/llvm/lib/Target/NVPTX/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/NVPTX/TargetDesc/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMNVPTXDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/NVPTX/Makefile b/gnu/llvm/lib/Target/NVPTX/Makefile
deleted file mode 100644
index 8db20ebed2c..00000000000
--- a/gnu/llvm/lib/Target/NVPTX/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Target/NVPTX/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMNVPTXCodeGen
-TARGET = NVPTX
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = NVPTXGenAsmWriter.inc \
- NVPTXGenDAGISel.inc \
- NVPTXGenInstrInfo.inc \
- NVPTXGenRegisterInfo.inc \
- NVPTXGenSubtargetInfo.inc
-
-DIRS = InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/NVPTX/TargetInfo/Makefile b/gnu/llvm/lib/Target/NVPTX/TargetInfo/Makefile
deleted file mode 100644
index 8622315b47b..00000000000
--- a/gnu/llvm/lib/Target/NVPTX/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/NVPTX/TargetInfo/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMNVPTXInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/AsmParser/Makefile b/gnu/llvm/lib/Target/PowerPC/AsmParser/Makefile
deleted file mode 100644
index c8a8915685e..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/PowerPC/AsmParser/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMPowerPCAsmParser
-
-# Hack: we need to include 'main' PowerPC target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/Disassembler/Makefile b/gnu/llvm/lib/Target/PowerPC/Disassembler/Makefile
deleted file mode 100644
index 86e3b475220..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===-- lib/Target/PowerPC/Disassembler/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMPowerPCDisassembler
-
-# Hack: we need to include 'main' PPC target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/InstPrinter/Makefile b/gnu/llvm/lib/Target/PowerPC/InstPrinter/Makefile
deleted file mode 100644
index f097e84248f..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/PowerPC/AsmPrinter/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMPowerPCAsmPrinter
-
-# Hack: we need to include 'main' powerpc target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/PowerPC/MCTargetDesc/Makefile
deleted file mode 100644
index 9db66622cce..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/PowerPC/TargetDesc/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMPowerPCDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/Makefile b/gnu/llvm/lib/Target/PowerPC/Makefile
deleted file mode 100644
index cf516f4e5ec..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- lib/Target/PowerPC/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMPowerPCCodeGen
-TARGET = PPC
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = PPCGenRegisterInfo.inc PPCGenAsmMatcher.inc \
- PPCGenAsmWriter.inc \
- PPCGenInstrInfo.inc PPCGenDAGISel.inc \
- PPCGenSubtargetInfo.inc PPCGenCallingConv.inc \
- PPCGenMCCodeEmitter.inc PPCGenFastISel.inc \
- PPCGenDisassemblerTables.inc
-
-DIRS = AsmParser Disassembler InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/PowerPC/PPCLoopDataPrefetch.cpp b/gnu/llvm/lib/Target/PowerPC/PPCLoopDataPrefetch.cpp
deleted file mode 100644
index e3a35d5df35..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/PPCLoopDataPrefetch.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-//===-------- PPCLoopDataPrefetch.cpp - Loop Data Prefetching Pass --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a Loop Data Prefetching Pass.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "ppc-loop-data-prefetch"
-#include "PPC.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/ADT/DepthFirstIterator.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/CodeMetrics.h"
-#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
-#include "llvm/Analysis/ScalarEvolutionExpander.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/CFG.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
-using namespace llvm;
-
-// By default, we limit this to creating 16 PHIs (which is a little over half
-// of the allocatable register set).
-static cl::opt<bool>
-PrefetchWrites("ppc-loop-prefetch-writes", cl::Hidden, cl::init(false),
- cl::desc("Prefetch write addresses"));
-
-// This seems like a reasonable default for the BG/Q (this pass is enabled, by
-// default, only on the BG/Q).
-static cl::opt<unsigned>
-PrefDist("ppc-loop-prefetch-distance", cl::Hidden, cl::init(300),
- cl::desc("The loop prefetch distance"));
-
-static cl::opt<unsigned>
-CacheLineSize("ppc-loop-prefetch-cache-line", cl::Hidden, cl::init(64),
- cl::desc("The loop prefetch cache line size"));
-
-namespace llvm {
- void initializePPCLoopDataPrefetchPass(PassRegistry&);
-}
-
-namespace {
-
- class PPCLoopDataPrefetch : public FunctionPass {
- public:
- static char ID; // Pass ID, replacement for typeid
- PPCLoopDataPrefetch() : FunctionPass(ID) {
- initializePPCLoopDataPrefetchPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<AssumptionCacheTracker>();
- AU.addPreserved<DominatorTreeWrapperPass>();
- AU.addRequired<LoopInfoWrapperPass>();
- AU.addPreserved<LoopInfoWrapperPass>();
- AU.addRequired<ScalarEvolutionWrapperPass>();
- // FIXME: For some reason, preserving SE here breaks LSR (even if
- // this pass changes nothing).
- // AU.addPreserved<ScalarEvolutionWrapperPass>();
- AU.addRequired<TargetTransformInfoWrapperPass>();
- }
-
- bool runOnFunction(Function &F) override;
- bool runOnLoop(Loop *L);
-
- private:
- AssumptionCache *AC;
- LoopInfo *LI;
- ScalarEvolution *SE;
- const TargetTransformInfo *TTI;
- const DataLayout *DL;
- };
-}
-
-char PPCLoopDataPrefetch::ID = 0;
-INITIALIZE_PASS_BEGIN(PPCLoopDataPrefetch, "ppc-loop-data-prefetch",
- "PPC Loop Data Prefetch", false, false)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
-INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
-INITIALIZE_PASS_END(PPCLoopDataPrefetch, "ppc-loop-data-prefetch",
- "PPC Loop Data Prefetch", false, false)
-
-FunctionPass *llvm::createPPCLoopDataPrefetchPass() { return new PPCLoopDataPrefetch(); }
-
-bool PPCLoopDataPrefetch::runOnFunction(Function &F) {
- LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
- DL = &F.getParent()->getDataLayout();
- AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
- TTI = &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
-
- bool MadeChange = false;
-
- for (auto I = LI->begin(), IE = LI->end(); I != IE; ++I)
- for (auto L = df_begin(*I), LE = df_end(*I); L != LE; ++L)
- MadeChange |= runOnLoop(*L);
-
- return MadeChange;
-}
-
-bool PPCLoopDataPrefetch::runOnLoop(Loop *L) {
- bool MadeChange = false;
-
- // Only prefetch in the inner-most loop
- if (!L->empty())
- return MadeChange;
-
- SmallPtrSet<const Value *, 32> EphValues;
- CodeMetrics::collectEphemeralValues(L, AC, EphValues);
-
- // Calculate the number of iterations ahead to prefetch
- CodeMetrics Metrics;
- for (Loop::block_iterator I = L->block_begin(), IE = L->block_end();
- I != IE; ++I) {
-
- // If the loop already has prefetches, then assume that the user knows
- // what he or she is doing and don't add any more.
- for (BasicBlock::iterator J = (*I)->begin(), JE = (*I)->end();
- J != JE; ++J)
- if (CallInst *CI = dyn_cast<CallInst>(J))
- if (Function *F = CI->getCalledFunction())
- if (F->getIntrinsicID() == Intrinsic::prefetch)
- return MadeChange;
-
- Metrics.analyzeBasicBlock(*I, *TTI, EphValues);
- }
- unsigned LoopSize = Metrics.NumInsts;
- if (!LoopSize)
- LoopSize = 1;
-
- unsigned ItersAhead = PrefDist/LoopSize;
- if (!ItersAhead)
- ItersAhead = 1;
-
- SmallVector<std::pair<Instruction *, const SCEVAddRecExpr *>, 16> PrefLoads;
- for (Loop::block_iterator I = L->block_begin(), IE = L->block_end();
- I != IE; ++I) {
- for (BasicBlock::iterator J = (*I)->begin(), JE = (*I)->end();
- J != JE; ++J) {
- Value *PtrValue;
- Instruction *MemI;
-
- if (LoadInst *LMemI = dyn_cast<LoadInst>(J)) {
- MemI = LMemI;
- PtrValue = LMemI->getPointerOperand();
- } else if (StoreInst *SMemI = dyn_cast<StoreInst>(J)) {
- if (!PrefetchWrites) continue;
- MemI = SMemI;
- PtrValue = SMemI->getPointerOperand();
- } else continue;
-
- unsigned PtrAddrSpace = PtrValue->getType()->getPointerAddressSpace();
- if (PtrAddrSpace)
- continue;
-
- if (L->isLoopInvariant(PtrValue))
- continue;
-
- const SCEV *LSCEV = SE->getSCEV(PtrValue);
- const SCEVAddRecExpr *LSCEVAddRec = dyn_cast<SCEVAddRecExpr>(LSCEV);
- if (!LSCEVAddRec)
- continue;
-
- // We don't want to double prefetch individual cache lines. If this load
- // is known to be within one cache line of some other load that has
- // already been prefetched, then don't prefetch this one as well.
- bool DupPref = false;
- for (SmallVector<std::pair<Instruction *, const SCEVAddRecExpr *>,
- 16>::iterator K = PrefLoads.begin(), KE = PrefLoads.end();
- K != KE; ++K) {
- const SCEV *PtrDiff = SE->getMinusSCEV(LSCEVAddRec, K->second);
- if (const SCEVConstant *ConstPtrDiff =
- dyn_cast<SCEVConstant>(PtrDiff)) {
- int64_t PD = std::abs(ConstPtrDiff->getValue()->getSExtValue());
- if (PD < (int64_t) CacheLineSize) {
- DupPref = true;
- break;
- }
- }
- }
- if (DupPref)
- continue;
-
- const SCEV *NextLSCEV = SE->getAddExpr(LSCEVAddRec, SE->getMulExpr(
- SE->getConstant(LSCEVAddRec->getType(), ItersAhead),
- LSCEVAddRec->getStepRecurrence(*SE)));
- if (!isSafeToExpand(NextLSCEV, *SE))
- continue;
-
- PrefLoads.push_back(std::make_pair(MemI, LSCEVAddRec));
-
- Type *I8Ptr = Type::getInt8PtrTy((*I)->getContext(), PtrAddrSpace);
- SCEVExpander SCEVE(*SE, J->getModule()->getDataLayout(), "prefaddr");
- Value *PrefPtrValue = SCEVE.expandCodeFor(NextLSCEV, I8Ptr, MemI);
-
- IRBuilder<> Builder(MemI);
- Module *M = (*I)->getParent()->getParent();
- Type *I32 = Type::getInt32Ty((*I)->getContext());
- Value *PrefetchFunc = Intrinsic::getDeclaration(M, Intrinsic::prefetch);
- Builder.CreateCall(
- PrefetchFunc,
- {PrefPtrValue,
- ConstantInt::get(I32, MemI->mayReadFromMemory() ? 0 : 1),
- ConstantInt::get(I32, 3), ConstantInt::get(I32, 1)});
-
- MadeChange = true;
- }
- }
-
- return MadeChange;
-}
-
diff --git a/gnu/llvm/lib/Target/PowerPC/TargetInfo/Makefile b/gnu/llvm/lib/Target/PowerPC/TargetInfo/Makefile
deleted file mode 100644
index 2d0560d275f..00000000000
--- a/gnu/llvm/lib/Target/PowerPC/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/PowerPC/TargetInfo/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMPowerPCInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-override CPPFLAGS += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Sparc/AsmParser/Makefile b/gnu/llvm/lib/Target/Sparc/AsmParser/Makefile
deleted file mode 100644
index 46b3e45f2be..00000000000
--- a/gnu/llvm/lib/Target/Sparc/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Sparc/AsmParser/Makefile ------------------*- Makefile-*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcAsmParser
-
-# Hack: we need to include 'main' Sparc target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Sparc/Disassembler/Makefile b/gnu/llvm/lib/Target/Sparc/Disassembler/Makefile
deleted file mode 100644
index bc17ddc48c7..00000000000
--- a/gnu/llvm/lib/Target/Sparc/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Sparc/Disassembler/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcDisassembler
-
-# Hack: we need to include 'main' Sparc target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Sparc/InstPrinter/Makefile b/gnu/llvm/lib/Target/Sparc/InstPrinter/Makefile
deleted file mode 100644
index 2dabd82965f..00000000000
--- a/gnu/llvm/lib/Target/Sparc/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Sparc/InstPrinter/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcAsmPrinter
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Sparc/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/Sparc/MCTargetDesc/Makefile
deleted file mode 100644
index abcbe2da18e..00000000000
--- a/gnu/llvm/lib/Target/Sparc/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/Sparc/TargetDesc/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/Sparc/Makefile b/gnu/llvm/lib/Target/Sparc/Makefile
deleted file mode 100644
index c2a95b47151..00000000000
--- a/gnu/llvm/lib/Target/Sparc/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- lib/Target/Sparc/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMSparcCodeGen
-TARGET = Sparc
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = SparcGenRegisterInfo.inc SparcGenInstrInfo.inc \
- SparcGenAsmWriter.inc SparcGenAsmMatcher.inc \
- SparcGenDAGISel.inc SparcGenDisassemblerTables.inc \
- SparcGenSubtargetInfo.inc SparcGenCallingConv.inc \
- SparcGenMCCodeEmitter.inc
-
-DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/Sparc/TargetInfo/Makefile b/gnu/llvm/lib/Target/Sparc/TargetInfo/Makefile
deleted file mode 100644
index 641ed87160c..00000000000
--- a/gnu/llvm/lib/Target/Sparc/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/Sparc/TargetInfo/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSparcInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/SystemZ/AsmParser/Makefile b/gnu/llvm/lib/Target/SystemZ/AsmParser/Makefile
deleted file mode 100644
index 623ae2c4e3e..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/AsmParser/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/SystemZ/AsmParser/Makefile ---------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSystemZAsmParser
-
-# Hack: we need to include 'main' SystemZ target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/SystemZ/Disassembler/Makefile b/gnu/llvm/lib/Target/SystemZ/Disassembler/Makefile
deleted file mode 100644
index efc4cc8e9cb..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===-- lib/Target/SystemZ/Disassembler/Makefile -----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSystemZDisassembler
-
-# Hack: we need to include 'main' x86 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/SystemZ/InstPrinter/Makefile b/gnu/llvm/lib/Target/SystemZ/InstPrinter/Makefile
deleted file mode 100644
index 3ba8126735a..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/SystemZ/AsmPrinter/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSystemZAsmPrinter
-
-# Hack: we need to include 'main' mips target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/SystemZ/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/SystemZ/MCTargetDesc/Makefile
deleted file mode 100644
index 08f1a9d51fb..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/SystemZ/TargetDesc/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSystemZDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/SystemZ/Makefile b/gnu/llvm/lib/Target/SystemZ/Makefile
deleted file mode 100644
index 732c3172553..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/Makefile
+++ /dev/null
@@ -1,28 +0,0 @@
-##===- lib/Target/SystemZ/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMSystemZCodeGen
-TARGET = SystemZ
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = SystemZGenRegisterInfo.inc \
- SystemZGenAsmWriter.inc \
- SystemZGenAsmMatcher.inc \
- SystemZGenDisassemblerTables.inc \
- SystemZGenInstrInfo.inc \
- SystemZGenDAGISel.inc \
- SystemZGenSubtargetInfo.inc \
- SystemZGenCallingConv.inc \
- SystemZGenMCCodeEmitter.inc
-
-DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/SystemZ/TargetInfo/Makefile b/gnu/llvm/lib/Target/SystemZ/TargetInfo/Makefile
deleted file mode 100644
index 0be80eb4e6a..00000000000
--- a/gnu/llvm/lib/Target/SystemZ/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/SystemZ/TargetInfo/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMSystemZInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/Disassembler/Makefile b/gnu/llvm/lib/Target/WebAssembly/Disassembler/Makefile
deleted file mode 100644
index bcd36ba6f01..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===-- lib/Target/WebAssembly/Disassembler/Makefile -------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMWebAssemblyDisassembler
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/InstPrinter/Makefile b/gnu/llvm/lib/Target/WebAssembly/InstPrinter/Makefile
deleted file mode 100644
index 87534379f79..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/WebAssembly/AsmPrinter/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMWebAssemblyAsmPrinter
-
-# Hack: we need to include 'main' wasm target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/WebAssembly/MCTargetDesc/Makefile
deleted file mode 100644
index 11dcb4ff607..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/WebAssembly/TargetDesc/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMWebAssemblyDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/Makefile b/gnu/llvm/lib/Target/WebAssembly/Makefile
deleted file mode 100644
index c501a2b1ab1..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-##===- lib/Target/WebAssembly/Makefile ---------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMWebAssemblyCodeGen
-TARGET = WebAssembly
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = \
- WebAssemblyGenAsmWriter.inc \
- WebAssemblyGenDAGISel.inc \
- WebAssemblyGenFastISel.inc \
- WebAssemblyGenInstrInfo.inc \
- WebAssemblyGenMCCodeEmitter.inc \
- WebAssemblyGenRegisterInfo.inc \
- WebAssemblyGenSubtargetInfo.inc
-
-DIRS = InstPrinter TargetInfo MCTargetDesc Disassembler
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/Relooper.cpp b/gnu/llvm/lib/Target/WebAssembly/Relooper.cpp
deleted file mode 100644
index 9b718ef094a..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/Relooper.cpp
+++ /dev/null
@@ -1,984 +0,0 @@
-//===-- Relooper.cpp - Top-level interface for WebAssembly ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===---------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This implements the Relooper algorithm. This implementation includes
-/// optimizations added since the original academic paper [1] was published.
-///
-/// [1] Alon Zakai. 2011. Emscripten: an LLVM-to-JavaScript compiler. In
-/// Proceedings of the ACM international conference companion on Object
-/// oriented programming systems languages and applications companion
-/// (SPLASH '11). ACM, New York, NY, USA, 301-312. DOI=10.1145/2048147.2048224
-/// http://doi.acm.org/10.1145/2048147.2048224
-///
-//===-------------------------------------------------------------------===//
-
-#include "Relooper.h"
-#include "WebAssembly.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/CFG.h"
-#include "llvm/IR/Function.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <cstring>
-#include <cstdlib>
-#include <functional>
-#include <list>
-#include <stack>
-#include <string>
-
-#define DEBUG_TYPE "relooper"
-
-using namespace llvm;
-using namespace Relooper;
-
-static cl::opt<int> RelooperSplittingFactor(
- "relooper-splitting-factor",
- cl::desc(
- "How much to discount code size when deciding whether to split a node"),
- cl::init(5));
-
-static cl::opt<unsigned> RelooperMultipleSwitchThreshold(
- "relooper-multiple-switch-threshold",
- cl::desc(
- "How many entries to allow in a multiple before we use a switch"),
- cl::init(10));
-
-static cl::opt<unsigned> RelooperNestingLimit(
- "relooper-nesting-limit",
- cl::desc(
- "How much nesting is acceptable"),
- cl::init(20));
-
-
-namespace {
-///
-/// Implements the relooper algorithm for a function's blocks.
-///
-/// Implementation details: The Relooper instance has
-/// ownership of the blocks and shapes, and frees them when done.
-///
-struct RelooperAlgorithm {
- std::deque<Block *> Blocks;
- std::deque<Shape *> Shapes;
- Shape *Root;
- bool MinSize;
- int BlockIdCounter;
- int ShapeIdCounter;
-
- RelooperAlgorithm();
- ~RelooperAlgorithm();
-
- void AddBlock(Block *New, int Id = -1);
-
- // Calculates the shapes
- void Calculate(Block *Entry);
-
- // Sets us to try to minimize size
- void SetMinSize(bool MinSize_) { MinSize = MinSize_; }
-};
-
-struct RelooperAnalysis final : public FunctionPass {
- static char ID;
- RelooperAnalysis() : FunctionPass(ID) {}
- const char *getPassName() const override { return "relooper"; }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
- bool runOnFunction(Function &F) override;
-};
-}
-
-// RelooperAnalysis
-
-char RelooperAnalysis::ID = 0;
-FunctionPass *llvm::createWebAssemblyRelooper() {
- return new RelooperAnalysis();
-}
-
-bool RelooperAnalysis::runOnFunction(Function &F) {
- DEBUG(dbgs() << "Relooping function '" << F.getName() << "'\n");
- RelooperAlgorithm R;
- // FIXME: remove duplication between relooper's and LLVM's BBs.
- std::map<const BasicBlock *, Block *> BB2B;
- std::map<const Block *, const BasicBlock *> B2BB;
- for (const BasicBlock &BB : F) {
- // FIXME: getName is wrong here, Code is meant to represent amount of code.
- // FIXME: use BranchVarInit for switch.
- Block *B = new Block(BB.getName().str().data(), /*BranchVarInit=*/nullptr);
- R.AddBlock(B);
- assert(BB2B.find(&BB) == BB2B.end() && "Inserting the same block twice");
- assert(B2BB.find(B) == B2BB.end() && "Inserting the same block twice");
- BB2B[&BB] = B;
- B2BB[B] = &BB;
- }
- for (Block *B : R.Blocks) {
- const BasicBlock *BB = B2BB[B];
- for (const BasicBlock *Successor : successors(BB))
- // FIXME: add branch's Condition and Code below.
- B->AddBranchTo(BB2B[Successor], /*Condition=*/nullptr, /*Code=*/nullptr);
- }
- R.Calculate(BB2B[&F.getEntryBlock()]);
- return false; // Analysis passes don't modify anything.
-}
-
-// Helpers
-
-typedef MapVector<Block *, BlockSet> BlockBlockSetMap;
-typedef std::list<Block *> BlockList;
-
-template <class T, class U>
-static bool contains(const T &container, const U &contained) {
- return container.count(contained);
-}
-
-
-// Branch
-
-Branch::Branch(const char *ConditionInit, const char *CodeInit)
- : Ancestor(nullptr), Labeled(true) {
- // FIXME: move from char* to LLVM data structures
- Condition = ConditionInit ? strdup(ConditionInit) : nullptr;
- Code = CodeInit ? strdup(CodeInit) : nullptr;
-}
-
-Branch::~Branch() {
- // FIXME: move from char* to LLVM data structures
- free(static_cast<void *>(const_cast<char *>(Condition)));
- free(static_cast<void *>(const_cast<char *>(Code)));
-}
-
-// Block
-
-Block::Block(const char *CodeInit, const char *BranchVarInit)
- : Parent(nullptr), Id(-1), IsCheckedMultipleEntry(false) {
- // FIXME: move from char* to LLVM data structures
- Code = strdup(CodeInit);
- BranchVar = BranchVarInit ? strdup(BranchVarInit) : nullptr;
-}
-
-Block::~Block() {
- // FIXME: move from char* to LLVM data structures
- free(static_cast<void *>(const_cast<char *>(Code)));
- free(static_cast<void *>(const_cast<char *>(BranchVar)));
-}
-
-void Block::AddBranchTo(Block *Target, const char *Condition,
- const char *Code) {
- assert(!contains(BranchesOut, Target) &&
- "cannot add more than one branch to the same target");
- BranchesOut[Target] = make_unique<Branch>(Condition, Code);
-}
-
-// Relooper
-
-RelooperAlgorithm::RelooperAlgorithm()
- : Root(nullptr), MinSize(false), BlockIdCounter(1),
- ShapeIdCounter(0) { // block ID 0 is reserved for clearings
-}
-
-RelooperAlgorithm::~RelooperAlgorithm() {
- for (auto Curr : Blocks)
- delete Curr;
- for (auto Curr : Shapes)
- delete Curr;
-}
-
-void RelooperAlgorithm::AddBlock(Block *New, int Id) {
- New->Id = Id == -1 ? BlockIdCounter++ : Id;
- Blocks.push_back(New);
-}
-
-struct RelooperRecursor {
- RelooperAlgorithm *Parent;
- RelooperRecursor(RelooperAlgorithm *ParentInit) : Parent(ParentInit) {}
-};
-
-void RelooperAlgorithm::Calculate(Block *Entry) {
- // Scan and optimize the input
- struct PreOptimizer : public RelooperRecursor {
- PreOptimizer(RelooperAlgorithm *Parent) : RelooperRecursor(Parent) {}
- BlockSet Live;
-
- void FindLive(Block *Root) {
- BlockList ToInvestigate;
- ToInvestigate.push_back(Root);
- while (!ToInvestigate.empty()) {
- Block *Curr = ToInvestigate.front();
- ToInvestigate.pop_front();
- if (contains(Live, Curr))
- continue;
- Live.insert(Curr);
- for (const auto &iter : Curr->BranchesOut)
- ToInvestigate.push_back(iter.first);
- }
- }
-
- // If a block has multiple entries but no exits, and it is small enough, it
- // is useful to split it. A common example is a C++ function where
- // everything ends up at a final exit block and does some RAII cleanup.
- // Without splitting, we will be forced to introduce labelled loops to
- // allow reaching the final block
- void SplitDeadEnds() {
- unsigned TotalCodeSize = 0;
- for (const auto &Curr : Live) {
- TotalCodeSize += strlen(Curr->Code);
- }
- BlockSet Splits;
- BlockSet Removed;
- for (const auto &Original : Live) {
- if (Original->BranchesIn.size() <= 1 ||
- !Original->BranchesOut.empty())
- continue; // only dead ends, for now
- if (contains(Original->BranchesOut, Original))
- continue; // cannot split a looping node
- if (strlen(Original->Code) * (Original->BranchesIn.size() - 1) >
- TotalCodeSize / RelooperSplittingFactor)
- continue; // if splitting increases raw code size by a significant
- // amount, abort
- // Split the node (for simplicity, we replace all the blocks, even
- // though we could have reused the original)
- DEBUG(dbgs() << " Splitting '" << Original->Code << "'\n");
- for (const auto &Prior : Original->BranchesIn) {
- Block *Split = new Block(Original->Code, Original->BranchVar);
- Parent->AddBlock(Split, Original->Id);
- Split->BranchesIn.insert(Prior);
- std::unique_ptr<Branch> Details;
- Details.swap(Prior->BranchesOut[Original]);
- Prior->BranchesOut[Split] = make_unique<Branch>(Details->Condition,
- Details->Code);
- for (const auto &iter : Original->BranchesOut) {
- Block *Post = iter.first;
- Branch *Details = iter.second.get();
- Split->BranchesOut[Post] = make_unique<Branch>(Details->Condition,
- Details->Code);
- Post->BranchesIn.insert(Split);
- }
- Splits.insert(Split);
- Removed.insert(Original);
- }
- for (const auto &iter : Original->BranchesOut) {
- Block *Post = iter.first;
- Post->BranchesIn.remove(Original);
- }
- }
- for (const auto &iter : Splits)
- Live.insert(iter);
- for (const auto &iter : Removed)
- Live.remove(iter);
- }
- };
- PreOptimizer Pre(this);
- Pre.FindLive(Entry);
-
- // Add incoming branches from live blocks, ignoring dead code
- for (unsigned i = 0; i < Blocks.size(); i++) {
- Block *Curr = Blocks[i];
- if (!contains(Pre.Live, Curr))
- continue;
- for (const auto &iter : Curr->BranchesOut)
- iter.first->BranchesIn.insert(Curr);
- }
-
- if (!MinSize)
- Pre.SplitDeadEnds();
-
- // Recursively process the graph
-
- struct Analyzer : public RelooperRecursor {
- Analyzer(RelooperAlgorithm *Parent) : RelooperRecursor(Parent) {}
-
- // Add a shape to the list of shapes in this Relooper calculation
- void Notice(Shape *New) {
- New->Id = Parent->ShapeIdCounter++;
- Parent->Shapes.push_back(New);
- }
-
- // Create a list of entries from a block. If LimitTo is provided, only
- // results in that set will appear
- void GetBlocksOut(Block *Source, BlockSet &Entries,
- BlockSet *LimitTo = nullptr) {
- for (const auto &iter : Source->BranchesOut)
- if (!LimitTo || contains(*LimitTo, iter.first))
- Entries.insert(iter.first);
- }
-
- // Converts/processes all branchings to a specific target
- void Solipsize(Block *Target, Branch::FlowType Type, Shape *Ancestor,
- BlockSet &From) {
- DEBUG(dbgs() << " Solipsize '" << Target->Code << "' type " << Type
- << "\n");
- for (auto iter = Target->BranchesIn.begin();
- iter != Target->BranchesIn.end();) {
- Block *Prior = *iter;
- if (!contains(From, Prior)) {
- iter++;
- continue;
- }
- std::unique_ptr<Branch> PriorOut;
- PriorOut.swap(Prior->BranchesOut[Target]);
- PriorOut->Ancestor = Ancestor;
- PriorOut->Type = Type;
- if (MultipleShape *Multiple = dyn_cast<MultipleShape>(Ancestor))
- Multiple->Breaks++; // We are breaking out of this Multiple, so need a
- // loop
- iter++; // carefully increment iter before erasing
- Target->BranchesIn.remove(Prior);
- Target->ProcessedBranchesIn.insert(Prior);
- Prior->ProcessedBranchesOut[Target].swap(PriorOut);
- }
- }
-
- Shape *MakeSimple(BlockSet &Blocks, Block *Inner, BlockSet &NextEntries) {
- DEBUG(dbgs() << " MakeSimple inner block '" << Inner->Code << "'\n");
- SimpleShape *Simple = new SimpleShape;
- Notice(Simple);
- Simple->Inner = Inner;
- Inner->Parent = Simple;
- if (Blocks.size() > 1) {
- Blocks.remove(Inner);
- GetBlocksOut(Inner, NextEntries, &Blocks);
- BlockSet JustInner;
- JustInner.insert(Inner);
- for (const auto &iter : NextEntries)
- Solipsize(iter, Branch::Direct, Simple, JustInner);
- }
- return Simple;
- }
-
- Shape *MakeLoop(BlockSet &Blocks, BlockSet &Entries,
- BlockSet &NextEntries) {
- // Find the inner blocks in this loop. Proceed backwards from the entries
- // until
- // you reach a seen block, collecting as you go.
- BlockSet InnerBlocks;
- BlockSet Queue = Entries;
- while (!Queue.empty()) {
- Block *Curr = *(Queue.begin());
- Queue.remove(*Queue.begin());
- if (!contains(InnerBlocks, Curr)) {
- // This element is new, mark it as inner and remove from outer
- InnerBlocks.insert(Curr);
- Blocks.remove(Curr);
- // Add the elements prior to it
- for (const auto &iter : Curr->BranchesIn)
- Queue.insert(iter);
- }
- }
- assert(!InnerBlocks.empty());
-
- for (const auto &Curr : InnerBlocks) {
- for (const auto &iter : Curr->BranchesOut) {
- Block *Possible = iter.first;
- if (!contains(InnerBlocks, Possible))
- NextEntries.insert(Possible);
- }
- }
-
- LoopShape *Loop = new LoopShape();
- Notice(Loop);
-
- // Solipsize the loop, replacing with break/continue and marking branches
- // as Processed (will not affect later calculations)
- // A. Branches to the loop entries become a continue to this shape
- for (const auto &iter : Entries)
- Solipsize(iter, Branch::Continue, Loop, InnerBlocks);
- // B. Branches to outside the loop (a next entry) become breaks on this
- // shape
- for (const auto &iter : NextEntries)
- Solipsize(iter, Branch::Break, Loop, InnerBlocks);
- // Finish up
- Shape *Inner = Process(InnerBlocks, Entries, nullptr);
- Loop->Inner = Inner;
- return Loop;
- }
-
- // For each entry, find the independent group reachable by it. The
- // independent group is the entry itself, plus all the blocks it can
- // reach that cannot be directly reached by another entry. Note that we
- // ignore directly reaching the entry itself by another entry.
- // @param Ignore - previous blocks that are irrelevant
- void FindIndependentGroups(BlockSet &Entries,
- BlockBlockSetMap &IndependentGroups,
- BlockSet *Ignore = nullptr) {
- typedef std::map<Block *, Block *> BlockBlockMap;
-
- struct HelperClass {
- BlockBlockSetMap &IndependentGroups;
- BlockBlockMap Ownership; // For each block, which entry it belongs to.
- // We have reached it from there.
-
- HelperClass(BlockBlockSetMap &IndependentGroupsInit)
- : IndependentGroups(IndependentGroupsInit) {}
- void InvalidateWithChildren(Block *New) {
- // Being in the list means you need to be invalidated
- BlockList ToInvalidate;
- ToInvalidate.push_back(New);
- while (!ToInvalidate.empty()) {
- Block *Invalidatee = ToInvalidate.front();
- ToInvalidate.pop_front();
- Block *Owner = Ownership[Invalidatee];
- // Owner may have been invalidated, do not add to
- // IndependentGroups!
- if (contains(IndependentGroups, Owner))
- IndependentGroups[Owner].remove(Invalidatee);
- if (Ownership[Invalidatee]) { // may have been seen before and
- // invalidated already
- Ownership[Invalidatee] = nullptr;
- for (const auto &iter : Invalidatee->BranchesOut) {
- Block *Target = iter.first;
- BlockBlockMap::iterator Known = Ownership.find(Target);
- if (Known != Ownership.end()) {
- Block *TargetOwner = Known->second;
- if (TargetOwner)
- ToInvalidate.push_back(Target);
- }
- }
- }
- }
- }
- };
- HelperClass Helper(IndependentGroups);
-
- // We flow out from each of the entries, simultaneously.
- // When we reach a new block, we add it as belonging to the one we got to
- // it from.
- // If we reach a new block that is already marked as belonging to someone,
- // it is reachable by two entries and is not valid for any of them.
- // Remove it and all it can reach that have been visited.
-
- // Being in the queue means we just added this item, and
- // we need to add its children
- BlockList Queue;
- for (const auto &Entry : Entries) {
- Helper.Ownership[Entry] = Entry;
- IndependentGroups[Entry].insert(Entry);
- Queue.push_back(Entry);
- }
- while (!Queue.empty()) {
- Block *Curr = Queue.front();
- Queue.pop_front();
- Block *Owner = Helper.Ownership[Curr]; // Curr must be in the ownership
- // map if we are in the queue
- if (!Owner)
- continue; // we have been invalidated meanwhile after being reached
- // from two entries
- // Add all children
- for (const auto &iter : Curr->BranchesOut) {
- Block *New = iter.first;
- BlockBlockMap::iterator Known = Helper.Ownership.find(New);
- if (Known == Helper.Ownership.end()) {
- // New node. Add it, and put it in the queue
- Helper.Ownership[New] = Owner;
- IndependentGroups[Owner].insert(New);
- Queue.push_back(New);
- continue;
- }
- Block *NewOwner = Known->second;
- if (!NewOwner)
- continue; // We reached an invalidated node
- if (NewOwner != Owner)
- // Invalidate this and all reachable that we have seen - we reached
- // this from two locations
- Helper.InvalidateWithChildren(New);
- // otherwise, we have the same owner, so do nothing
- }
- }
-
- // Having processed all the interesting blocks, we remain with just one
- // potential issue:
- // If a->b, and a was invalidated, but then b was later reached by
- // someone else, we must invalidate b. To check for this, we go over all
- // elements in the independent groups, if an element has a parent which
- // does *not* have the same owner, we/ must remove it and all its
- // children.
-
- for (const auto &iter : Entries) {
- BlockSet &CurrGroup = IndependentGroups[iter];
- BlockList ToInvalidate;
- for (const auto &iter : CurrGroup) {
- Block *Child = iter;
- for (const auto &iter : Child->BranchesIn) {
- Block *Parent = iter;
- if (Ignore && contains(*Ignore, Parent))
- continue;
- if (Helper.Ownership[Parent] != Helper.Ownership[Child])
- ToInvalidate.push_back(Child);
- }
- }
- while (!ToInvalidate.empty()) {
- Block *Invalidatee = ToInvalidate.front();
- ToInvalidate.pop_front();
- Helper.InvalidateWithChildren(Invalidatee);
- }
- }
-
- // Remove empty groups
- for (const auto &iter : Entries)
- if (IndependentGroups[iter].empty())
- IndependentGroups.erase(iter);
- }
-
- Shape *MakeMultiple(BlockSet &Blocks, BlockSet &Entries,
- BlockBlockSetMap &IndependentGroups, Shape *Prev,
- BlockSet &NextEntries) {
- bool Fused = isa<SimpleShape>(Prev);
- MultipleShape *Multiple = new MultipleShape();
- Notice(Multiple);
- BlockSet CurrEntries;
- for (auto &iter : IndependentGroups) {
- Block *CurrEntry = iter.first;
- BlockSet &CurrBlocks = iter.second;
- // Create inner block
- CurrEntries.clear();
- CurrEntries.insert(CurrEntry);
- for (const auto &CurrInner : CurrBlocks) {
- // Remove the block from the remaining blocks
- Blocks.remove(CurrInner);
- // Find new next entries and fix branches to them
- for (auto iter = CurrInner->BranchesOut.begin();
- iter != CurrInner->BranchesOut.end();) {
- Block *CurrTarget = iter->first;
- auto Next = iter;
- Next++;
- if (!contains(CurrBlocks, CurrTarget)) {
- NextEntries.insert(CurrTarget);
- Solipsize(CurrTarget, Branch::Break, Multiple, CurrBlocks);
- }
- iter = Next; // increment carefully because Solipsize can remove us
- }
- }
- Multiple->InnerMap[CurrEntry->Id] =
- Process(CurrBlocks, CurrEntries, nullptr);
- // If we are not fused, then our entries will actually be checked
- if (!Fused)
- CurrEntry->IsCheckedMultipleEntry = true;
- }
- // Add entries not handled as next entries, they are deferred
- for (const auto &Entry : Entries)
- if (!contains(IndependentGroups, Entry))
- NextEntries.insert(Entry);
- // The multiple has been created, we can decide how to implement it
- if (Multiple->InnerMap.size() >= RelooperMultipleSwitchThreshold) {
- Multiple->UseSwitch = true;
- Multiple->Breaks++; // switch captures breaks
- }
- return Multiple;
- }
-
- // Main function.
- // Process a set of blocks with specified entries, returns a shape
- // The Make* functions receive a NextEntries. If they fill it with data,
- // those are the entries for the ->Next block on them, and the blocks
- // are what remains in Blocks (which Make* modify). In this way
- // we avoid recursing on Next (imagine a long chain of Simples, if we
- // recursed we could blow the stack).
- Shape *Process(BlockSet &Blocks, BlockSet &InitialEntries, Shape *Prev) {
- BlockSet *Entries = &InitialEntries;
- BlockSet TempEntries[2];
- int CurrTempIndex = 0;
- BlockSet *NextEntries;
- Shape *Ret = nullptr;
-
- auto Make = [&](Shape *Temp) {
- if (Prev)
- Prev->Next = Temp;
- if (!Ret)
- Ret = Temp;
- Prev = Temp;
- Entries = NextEntries;
- };
-
- while (1) {
- CurrTempIndex = 1 - CurrTempIndex;
- NextEntries = &TempEntries[CurrTempIndex];
- NextEntries->clear();
-
- if (Entries->empty())
- return Ret;
- if (Entries->size() == 1) {
- Block *Curr = *(Entries->begin());
- if (Curr->BranchesIn.empty()) {
- // One entry, no looping ==> Simple
- Make(MakeSimple(Blocks, Curr, *NextEntries));
- if (NextEntries->empty())
- return Ret;
- continue;
- }
- // One entry, looping ==> Loop
- Make(MakeLoop(Blocks, *Entries, *NextEntries));
- if (NextEntries->empty())
- return Ret;
- continue;
- }
-
- // More than one entry, try to eliminate through a Multiple groups of
- // independent blocks from an entry/ies. It is important to remove
- // through multiples as opposed to looping since the former is more
- // performant.
- BlockBlockSetMap IndependentGroups;
- FindIndependentGroups(*Entries, IndependentGroups);
-
- if (!IndependentGroups.empty()) {
- // We can handle a group in a multiple if its entry cannot be reached
- // by another group.
- // Note that it might be reachable by itself - a loop. But that is
- // fine, we will create a loop inside the multiple block (which
- // is the performant order to do it).
- for (auto iter = IndependentGroups.begin();
- iter != IndependentGroups.end();) {
- Block *Entry = iter->first;
- BlockSet &Group = iter->second;
- auto curr = iter++; // iterate carefully, we may delete
- for (BlockSet::iterator iterBranch = Entry->BranchesIn.begin();
- iterBranch != Entry->BranchesIn.end(); iterBranch++) {
- Block *Origin = *iterBranch;
- if (!contains(Group, Origin)) {
- // Reached from outside the group, so we cannot handle this
- IndependentGroups.erase(curr);
- break;
- }
- }
- }
-
- // As an optimization, if we have 2 independent groups, and one is a
- // small dead end, we can handle only that dead end.
- // The other then becomes a Next - without nesting in the code and
- // recursion in the analysis.
- // TODO: if the larger is the only dead end, handle that too
- // TODO: handle >2 groups
- // TODO: handle not just dead ends, but also that do not branch to the
- // NextEntries. However, must be careful there since we create a
- // Next, and that Next can prevent eliminating a break (since we no
- // longer naturally reach the same place), which may necessitate a
- // one-time loop, which makes the unnesting pointless.
- if (IndependentGroups.size() == 2) {
- // Find the smaller one
- auto iter = IndependentGroups.begin();
- Block *SmallEntry = iter->first;
- auto SmallSize = iter->second.size();
- iter++;
- Block *LargeEntry = iter->first;
- auto LargeSize = iter->second.size();
- if (SmallSize != LargeSize) { // ignore the case where they are
- // identical - keep things symmetrical
- // there
- if (SmallSize > LargeSize) {
- Block *Temp = SmallEntry;
- SmallEntry = LargeEntry;
- LargeEntry = Temp; // Note: we did not flip the Sizes too, they
- // are now invalid. TODO: use the smaller
- // size as a limit?
- }
- // Check if dead end
- bool DeadEnd = true;
- BlockSet &SmallGroup = IndependentGroups[SmallEntry];
- for (const auto &Curr : SmallGroup) {
- for (const auto &iter : Curr->BranchesOut) {
- Block *Target = iter.first;
- if (!contains(SmallGroup, Target)) {
- DeadEnd = false;
- break;
- }
- }
- if (!DeadEnd)
- break;
- }
- if (DeadEnd)
- IndependentGroups.erase(LargeEntry);
- }
- }
-
- if (!IndependentGroups.empty())
- // Some groups removable ==> Multiple
- Make(MakeMultiple(Blocks, *Entries, IndependentGroups, Prev,
- *NextEntries));
- if (NextEntries->empty())
- return Ret;
- continue;
- }
- // No independent groups, must be loopable ==> Loop
- Make(MakeLoop(Blocks, *Entries, *NextEntries));
- if (NextEntries->empty())
- return Ret;
- continue;
- }
- }
- };
-
- // Main
-
- BlockSet AllBlocks;
- for (const auto &Curr : Pre.Live) {
- AllBlocks.insert(Curr);
- }
-
- BlockSet Entries;
- Entries.insert(Entry);
- Root = Analyzer(this).Process(AllBlocks, Entries, nullptr);
- assert(Root);
-
- ///
- /// Relooper post-optimizer
- ///
- struct PostOptimizer {
- RelooperAlgorithm *Parent;
- std::stack<Shape *> LoopStack;
-
- PostOptimizer(RelooperAlgorithm *ParentInit) : Parent(ParentInit) {}
-
- void ShapeSwitch(Shape* var,
- std::function<void (SimpleShape*)> simple,
- std::function<void (MultipleShape*)> multiple,
- std::function<void (LoopShape*)> loop) {
- switch (var->getKind()) {
- case Shape::SK_Simple: {
- simple(cast<SimpleShape>(var));
- break;
- }
- case Shape::SK_Multiple: {
- multiple(cast<MultipleShape>(var));
- break;
- }
- case Shape::SK_Loop: {
- loop(cast<LoopShape>(var));
- break;
- }
- }
- }
-
- // Find the blocks that natural control flow can get us directly to, or
- // through a multiple that we ignore
- void FollowNaturalFlow(Shape *S, BlockSet &Out) {
- ShapeSwitch(S, [&](SimpleShape* Simple) {
- Out.insert(Simple->Inner);
- }, [&](MultipleShape* Multiple) {
- for (const auto &iter : Multiple->InnerMap) {
- FollowNaturalFlow(iter.second, Out);
- }
- FollowNaturalFlow(Multiple->Next, Out);
- }, [&](LoopShape* Loop) {
- FollowNaturalFlow(Loop->Inner, Out);
- });
- }
-
- void FindNaturals(Shape *Root, Shape *Otherwise = nullptr) {
- if (Root->Next) {
- Root->Natural = Root->Next;
- FindNaturals(Root->Next, Otherwise);
- } else {
- Root->Natural = Otherwise;
- }
-
- ShapeSwitch(Root, [](SimpleShape* Simple) {
- }, [&](MultipleShape* Multiple) {
- for (const auto &iter : Multiple->InnerMap) {
- FindNaturals(iter.second, Root->Natural);
- }
- }, [&](LoopShape* Loop){
- FindNaturals(Loop->Inner, Loop->Inner);
- });
- }
-
- // Remove unneeded breaks and continues.
- // A flow operation is trivially unneeded if the shape we naturally get to
- // by normal code execution is the same as the flow forces us to.
- void RemoveUnneededFlows(Shape *Root, Shape *Natural = nullptr,
- LoopShape *LastLoop = nullptr,
- unsigned Depth = 0) {
- BlockSet NaturalBlocks;
- FollowNaturalFlow(Natural, NaturalBlocks);
- Shape *Next = Root;
- while (Next) {
- Root = Next;
- Next = nullptr;
- ShapeSwitch(
- Root,
- [&](SimpleShape* Simple) {
- if (Simple->Inner->BranchVar)
- LastLoop =
- nullptr; // a switch clears out the loop (TODO: only for
- // breaks, not continue)
-
- if (Simple->Next) {
- if (!Simple->Inner->BranchVar &&
- Simple->Inner->ProcessedBranchesOut.size() == 2 &&
- Depth < RelooperNestingLimit) {
- // If there is a next block, we already know at Simple
- // creation time to make direct branches, and we can do
- // nothing more in general. But, we try to optimize the
- // case of a break and a direct: This would normally be
- // if (break?) { break; } ..
- // but if we make sure to nest the else, we can save the
- // break,
- // if (!break?) { .. }
- // This is also better because the more canonical nested
- // form is easier to further optimize later. The
- // downside is more nesting, which adds to size in builds with
- // whitespace.
- // Note that we avoid switches, as it complicates control flow
- // and is not relevant for the common case we optimize here.
- bool Found = false;
- bool Abort = false;
- for (const auto &iter : Simple->Inner->ProcessedBranchesOut) {
- Block *Target = iter.first;
- Branch *Details = iter.second.get();
- if (Details->Type == Branch::Break) {
- Found = true;
- if (!contains(NaturalBlocks, Target))
- Abort = true;
- } else if (Details->Type != Branch::Direct)
- Abort = true;
- }
- if (Found && !Abort) {
- for (const auto &iter : Simple->Inner->ProcessedBranchesOut) {
- Branch *Details = iter.second.get();
- if (Details->Type == Branch::Break) {
- Details->Type = Branch::Direct;
- if (MultipleShape *Multiple =
- dyn_cast<MultipleShape>(Details->Ancestor))
- Multiple->Breaks--;
- } else {
- assert(Details->Type == Branch::Direct);
- Details->Type = Branch::Nested;
- }
- }
- }
- Depth++; // this optimization increases depth, for us and all
- // our next chain (i.e., until this call returns)
- }
- Next = Simple->Next;
- } else {
- // If there is no next then Natural is where we will
- // go to by doing nothing, so we can potentially optimize some
- // branches to direct.
- for (const auto &iter : Simple->Inner->ProcessedBranchesOut) {
- Block *Target = iter.first;
- Branch *Details = iter.second.get();
- if (Details->Type != Branch::Direct &&
- contains(NaturalBlocks,
- Target)) { // note: cannot handle split blocks
- Details->Type = Branch::Direct;
- if (MultipleShape *Multiple =
- dyn_cast<MultipleShape>(Details->Ancestor))
- Multiple->Breaks--;
- } else if (Details->Type == Branch::Break && LastLoop &&
- LastLoop->Natural == Details->Ancestor->Natural) {
- // it is important to simplify breaks, as simpler breaks
- // enable other optimizations
- Details->Labeled = false;
- if (MultipleShape *Multiple =
- dyn_cast<MultipleShape>(Details->Ancestor))
- Multiple->Breaks--;
- }
- }
- }
- }, [&](MultipleShape* Multiple)
- {
- for (const auto &iter : Multiple->InnerMap) {
- RemoveUnneededFlows(iter.second, Multiple->Next,
- Multiple->Breaks ? nullptr : LastLoop,
- Depth + 1);
- }
- Next = Multiple->Next;
- }, [&](LoopShape* Loop)
- {
- RemoveUnneededFlows(Loop->Inner, Loop->Inner, Loop, Depth + 1);
- Next = Loop->Next;
- });
- }
- }
-
- // After we know which loops exist, we can calculate which need to be
- // labeled
- void FindLabeledLoops(Shape *Root) {
- Shape *Next = Root;
- while (Next) {
- Root = Next;
- Next = nullptr;
-
- ShapeSwitch(
- Root,
- [&](SimpleShape *Simple) {
- MultipleShape *Fused = dyn_cast<MultipleShape>(Root->Next);
- // If we are fusing a Multiple with a loop into this Simple, then
- // visit it now
- if (Fused && Fused->Breaks)
- LoopStack.push(Fused);
- if (Simple->Inner->BranchVar)
- LoopStack.push(nullptr); // a switch means breaks are now useless,
- // push a dummy
- if (Fused) {
- if (Fused->UseSwitch)
- LoopStack.push(nullptr); // a switch means breaks are now
- // useless, push a dummy
- for (const auto &iter : Fused->InnerMap) {
- FindLabeledLoops(iter.second);
- }
- }
- for (const auto &iter : Simple->Inner->ProcessedBranchesOut) {
- Branch *Details = iter.second.get();
- if (Details->Type == Branch::Break ||
- Details->Type == Branch::Continue) {
- assert(!LoopStack.empty());
- if (Details->Ancestor != LoopStack.top() && Details->Labeled) {
- if (MultipleShape *Multiple =
- dyn_cast<MultipleShape>(Details->Ancestor)) {
- Multiple->Labeled = true;
- } else {
- LoopShape *Loop = cast<LoopShape>(Details->Ancestor);
- Loop->Labeled = true;
- }
- } else {
- Details->Labeled = false;
- }
- }
- if (Fused && Fused->UseSwitch)
- LoopStack.pop();
- if (Simple->Inner->BranchVar)
- LoopStack.pop();
- if (Fused && Fused->Breaks)
- LoopStack.pop();
- if (Fused)
- Next = Fused->Next;
- else
- Next = Root->Next;
- }
- }
- , [&](MultipleShape* Multiple) {
- if (Multiple->Breaks)
- LoopStack.push(Multiple);
- for (const auto &iter : Multiple->InnerMap)
- FindLabeledLoops(iter.second);
- if (Multiple->Breaks)
- LoopStack.pop();
- Next = Root->Next;
- }
- , [&](LoopShape* Loop) {
- LoopStack.push(Loop);
- FindLabeledLoops(Loop->Inner);
- LoopStack.pop();
- Next = Root->Next;
- });
- }
- }
-
- void Process(Shape * Root) {
- FindNaturals(Root);
- RemoveUnneededFlows(Root);
- FindLabeledLoops(Root);
- }
- };
-
- PostOptimizer(this).Process(Root);
-}
diff --git a/gnu/llvm/lib/Target/WebAssembly/Relooper.h b/gnu/llvm/lib/Target/WebAssembly/Relooper.h
deleted file mode 100644
index 7c564de82f3..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/Relooper.h
+++ /dev/null
@@ -1,186 +0,0 @@
-//===-- Relooper.h - Top-level interface for WebAssembly ----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===-------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This defines an optimized C++ implemention of the Relooper
-/// algorithm, originally developed as part of Emscripten, which
-/// generates a structured AST from arbitrary control flow.
-///
-//===-------------------------------------------------------------------===//
-
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/Support/Casting.h"
-
-#include <cassert>
-#include <cstdarg>
-#include <cstdio>
-#include <deque>
-#include <list>
-#include <map>
-#include <memory>
-#include <set>
-
-namespace llvm {
-
-namespace Relooper {
-
-struct Block;
-struct Shape;
-
-///
-/// Info about a branching from one block to another
-///
-struct Branch {
- enum FlowType {
- Direct = 0, // We will directly reach the right location through other
- // means, no need for continue or break
- Break = 1,
- Continue = 2,
- Nested = 3 // This code is directly reached, but we must be careful to
- // ensure it is nested in an if - it is not reached
- // unconditionally, other code paths exist alongside it that we need to make
- // sure do not intertwine
- };
- Shape
- *Ancestor; // If not nullptr, this shape is the relevant one for purposes
- // of getting to the target block. We break or continue on it
- Branch::FlowType
- Type; // If Ancestor is not nullptr, this says whether to break or
- // continue
- bool Labeled; // If a break or continue, whether we need to use a label
- const char *Condition; // The condition for which we branch. For example,
- // "my_var == 1". Conditions are checked one by one.
- // One of the conditions should have nullptr as the
- // condition, in which case it is the default
- // FIXME: move from char* to LLVM data structures
- const char *Code; // If provided, code that is run right before the branch is
- // taken. This is useful for phis
- // FIXME: move from char* to LLVM data structures
-
- Branch(const char *ConditionInit, const char *CodeInit = nullptr);
- ~Branch();
-};
-
-typedef SetVector<Block *> BlockSet;
-typedef MapVector<Block *, Branch *> BlockBranchMap;
-typedef MapVector<Block *, std::unique_ptr<Branch>> OwningBlockBranchMap;
-
-///
-/// Represents a basic block of code - some instructions that end with a
-/// control flow modifier (a branch, return or throw).
-///
-struct Block {
- // Branches become processed after we finish the shape relevant to them. For
- // example, when we recreate a loop, branches to the loop start become
- // continues and are now processed. When we calculate what shape to generate
- // from a set of blocks, we ignore processed branches. Blocks own the Branch
- // objects they use, and destroy them when done.
- OwningBlockBranchMap BranchesOut;
- BlockSet BranchesIn;
- OwningBlockBranchMap ProcessedBranchesOut;
- BlockSet ProcessedBranchesIn;
- Shape *Parent; // The shape we are directly inside
- int Id; // A unique identifier, defined when added to relooper. Note that this
- // uniquely identifies a *logical* block - if we split it, the two
- // instances have the same content *and* the same Id
- const char *Code; // The string representation of the code in this block.
- // Owning pointer (we copy the input)
- // FIXME: move from char* to LLVM data structures
- const char *BranchVar; // A variable whose value determines where we go; if
- // this is not nullptr, emit a switch on that variable
- // FIXME: move from char* to LLVM data structures
- bool IsCheckedMultipleEntry; // If true, we are a multiple entry, so reaching
- // us requires setting the label variable
-
- Block(const char *CodeInit, const char *BranchVarInit);
- ~Block();
-
- void AddBranchTo(Block *Target, const char *Condition,
- const char *Code = nullptr);
-};
-
-///
-/// Represents a structured control flow shape
-///
-struct Shape {
- int Id; // A unique identifier. Used to identify loops, labels are Lx where x
- // is the Id. Defined when added to relooper
- Shape *Next; // The shape that will appear in the code right after this one
- Shape *Natural; // The shape that control flow gets to naturally (if there is
- // Next, then this is Next)
-
- /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
- enum ShapeKind { SK_Simple, SK_Multiple, SK_Loop };
-
-private:
- ShapeKind Kind;
-
-public:
- ShapeKind getKind() const { return Kind; }
-
- Shape(ShapeKind KindInit) : Id(-1), Next(nullptr), Kind(KindInit) {}
-};
-
-///
-/// Simple: No control flow at all, just instructions.
-///
-struct SimpleShape : public Shape {
- Block *Inner;
-
- SimpleShape() : Shape(SK_Simple), Inner(nullptr) {}
-
- static bool classof(const Shape *S) { return S->getKind() == SK_Simple; }
-};
-
-///
-/// A shape that may be implemented with a labeled loop.
-///
-struct LabeledShape : public Shape {
- bool Labeled; // If we have a loop, whether it needs to be labeled
-
- LabeledShape(ShapeKind KindInit) : Shape(KindInit), Labeled(false) {}
-};
-
-// Blocks with the same id were split and are identical, so we just care about
-// ids in Multiple entries
-typedef std::map<int, Shape *> IdShapeMap;
-
-///
-/// Multiple: A shape with more than one entry. If the next block to
-/// be entered is among them, we run it and continue to
-/// the next shape, otherwise we continue immediately to the
-/// next shape.
-///
-struct MultipleShape : public LabeledShape {
- IdShapeMap InnerMap; // entry block ID -> shape
- int Breaks; // If we have branches on us, we need a loop (or a switch). This
- // is a counter of requirements,
- // if we optimize it to 0, the loop is unneeded
- bool UseSwitch; // Whether to switch on label as opposed to an if-else chain
-
- MultipleShape() : LabeledShape(SK_Multiple), Breaks(0), UseSwitch(false) {}
-
- static bool classof(const Shape *S) { return S->getKind() == SK_Multiple; }
-};
-
-///
-/// Loop: An infinite loop.
-///
-struct LoopShape : public LabeledShape {
- Shape *Inner;
-
- LoopShape() : LabeledShape(SK_Loop), Inner(nullptr) {}
-
- static bool classof(const Shape *S) { return S->getKind() == SK_Loop; }
-};
-
-} // namespace Relooper
-
-} // namespace llvm
diff --git a/gnu/llvm/lib/Target/WebAssembly/TargetInfo/Makefile b/gnu/llvm/lib/Target/WebAssembly/TargetInfo/Makefile
deleted file mode 100644
index b021eb6d945..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/TargetInfo/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/WebAssembly/TargetInfo/Makefile ----------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMWebAssemblyInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/WebAssembly/WebAssemblyPEI.cpp b/gnu/llvm/lib/Target/WebAssembly/WebAssemblyPEI.cpp
deleted file mode 100644
index d570d426611..00000000000
--- a/gnu/llvm/lib/Target/WebAssembly/WebAssemblyPEI.cpp
+++ /dev/null
@@ -1,1066 +0,0 @@
-//===-- WebAssemblyPEI.cpp - Insert Prolog/Epilog code in function --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass is responsible for finalizing the functions frame layout, saving
-// callee saved registers, and for emitting prolog & epilog code for the
-// function.
-//
-// This pass must be run after register allocation. After this pass is
-// executed, it is illegal to construct MO_FrameIndex operands.
-//
-// This is a copy of lib/CodeGen/PrologEpilogInserter.cpp except that it does
-// not assert that all virtual registers are gone (because WebAssembly currently
-// uses virtual rather than physical registers), and only runs
-// MRI.clearVirtRegs() if scavenging happened (which it never does). It also
-// uses a different class name so it can be registered via INITIALIZE_PASS.
-// It is otherwise unmodified, so any changes to the target-independent PEI
-// can be easily applied.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/IndexedMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineDominators.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/CodeGen/StackProtector.h"
-#include "llvm/CodeGen/WinEHFuncInfo.h"
-#include "llvm/IR/DiagnosticInfo.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-#include <climits>
-
-using namespace llvm;
-
-#define DEBUG_TYPE "pei"
-namespace llvm {
-void initializeWasmPEIPass(PassRegistry&);
-}
-namespace {
-class WasmPEI : public MachineFunctionPass {
-public:
- static char ID;
- WasmPEI() : MachineFunctionPass(ID) {
- initializeWasmPEIPass(*PassRegistry::getPassRegistry());
- }
-
- void getAnalysisUsage(AnalysisUsage &AU) const override;
-
- /// runOnMachineFunction - Insert prolog/epilog code and replace abstract
- /// frame indexes with appropriate references.
- ///
- bool runOnMachineFunction(MachineFunction &Fn) override;
-
-private:
- RegScavenger *RS;
-
- // MinCSFrameIndex, MaxCSFrameIndex - Keeps the range of callee saved
- // stack frame indexes.
- unsigned MinCSFrameIndex, MaxCSFrameIndex;
-
- // Save and Restore blocks of the current function. Typically there is a
- // single save block, unless Windows EH funclets are involved.
- SmallVector<MachineBasicBlock *, 1> SaveBlocks;
- SmallVector<MachineBasicBlock *, 4> RestoreBlocks;
-
- // Flag to control whether to use the register scavenger to resolve
- // frame index materialization registers. Set according to
- // TRI->requiresFrameIndexScavenging() for the current function.
- bool FrameIndexVirtualScavenging;
-
- void calculateSets(MachineFunction &Fn);
- void calculateCallsInformation(MachineFunction &Fn);
- void assignCalleeSavedSpillSlots(MachineFunction &Fn,
- const BitVector &SavedRegs);
- void insertCSRSpillsAndRestores(MachineFunction &Fn);
- void calculateFrameObjectOffsets(MachineFunction &Fn);
- void replaceFrameIndices(MachineFunction &Fn);
- void replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
- int &SPAdj);
- void scavengeFrameVirtualRegs(MachineFunction &Fn);
- void insertPrologEpilogCode(MachineFunction &Fn);
-};
-} // namespace
-
-char WasmPEI::ID = 0;
-
-namespace llvm {
-FunctionPass *createWebAssemblyPEI() {
- return new WasmPEI();
-}
-}
-
-static cl::opt<unsigned>
-WarnStackSize("wasm-warn-stack-size", cl::Hidden, cl::init((unsigned)-1),
- cl::desc("Warn for stack size bigger than the given"
- " number"));
-
-INITIALIZE_PASS_BEGIN(WasmPEI, "wasmprologepilog",
- "Wasm Prologue/Epilogue Insertion", false, false)
-INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
-INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
-INITIALIZE_PASS_DEPENDENCY(StackProtector)
-INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
-INITIALIZE_PASS_END(WasmPEI, "wasmprologepilog",
- "Wasm Prologue/Epilogue Insertion & Frame Finalization",
- false, false)
-
-STATISTIC(NumScavengedRegs, "Number of frame index regs scavenged");
-STATISTIC(NumBytesStackSpace,
- "Number of bytes used for stack in all functions");
-
-void WasmPEI::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesCFG();
- AU.addPreserved<MachineLoopInfo>();
- AU.addPreserved<MachineDominatorTree>();
- AU.addRequired<StackProtector>();
- AU.addRequired<TargetPassConfig>();
- MachineFunctionPass::getAnalysisUsage(AU);
-}
-
-/// Compute the set of return blocks
-void WasmPEI::calculateSets(MachineFunction &Fn) {
- const MachineFrameInfo *MFI = Fn.getFrameInfo();
-
- // Even when we do not change any CSR, we still want to insert the
- // prologue and epilogue of the function.
- // So set the save points for those.
-
- // Use the points found by shrink-wrapping, if any.
- if (MFI->getSavePoint()) {
- SaveBlocks.push_back(MFI->getSavePoint());
- assert(MFI->getRestorePoint() && "Both restore and save must be set");
- MachineBasicBlock *RestoreBlock = MFI->getRestorePoint();
- // If RestoreBlock does not have any successor and is not a return block
- // then the end point is unreachable and we do not need to insert any
- // epilogue.
- if (!RestoreBlock->succ_empty() || RestoreBlock->isReturnBlock())
- RestoreBlocks.push_back(RestoreBlock);
- return;
- }
-
- // Save refs to entry and return blocks.
- SaveBlocks.push_back(&Fn.front());
- for (MachineBasicBlock &MBB : Fn) {
- if (MBB.isEHFuncletEntry())
- SaveBlocks.push_back(&MBB);
- if (MBB.isReturnBlock())
- RestoreBlocks.push_back(&MBB);
- }
-}
-
-/// StackObjSet - A set of stack object indexes
-typedef SmallSetVector<int, 8> StackObjSet;
-
-/// runOnMachineFunction - Insert prolog/epilog code and replace abstract
-/// frame indexes with appropriate references.
-///
-bool WasmPEI::runOnMachineFunction(MachineFunction &Fn) {
- const Function* F = Fn.getFunction();
- const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
- const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
-
- // LOCALMOD: assert removed from target-independent PEI
- //assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs");
-
- RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr;
- FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
-
- // Calculate the MaxCallFrameSize and AdjustsStack variables for the
- // function's frame information. Also eliminates call frame pseudo
- // instructions.
- calculateCallsInformation(Fn);
-
- // Determine which of the registers in the callee save list should be saved.
- BitVector SavedRegs;
- TFI->determineCalleeSaves(Fn, SavedRegs, RS);
-
- // Insert spill code for any callee saved registers that are modified.
- assignCalleeSavedSpillSlots(Fn, SavedRegs);
-
- // Determine placement of CSR spill/restore code:
- // place all spills in the entry block, all restores in return blocks.
- calculateSets(Fn);
-
- // Add the code to save and restore the callee saved registers.
- if (!F->hasFnAttribute(Attribute::Naked))
- insertCSRSpillsAndRestores(Fn);
-
- // Allow the target machine to make final modifications to the function
- // before the frame layout is finalized.
- TFI->processFunctionBeforeFrameFinalized(Fn, RS);
-
- // Calculate actual frame offsets for all abstract stack objects...
- calculateFrameObjectOffsets(Fn);
-
- // Add prolog and epilog code to the function. This function is required
- // to align the stack frame as necessary for any stack variables or
- // called functions. Because of this, calculateCalleeSavedRegisters()
- // must be called before this function in order to set the AdjustsStack
- // and MaxCallFrameSize variables.
- if (!F->hasFnAttribute(Attribute::Naked))
- insertPrologEpilogCode(Fn);
-
- // Replace all MO_FrameIndex operands with physical register references
- // and actual offsets.
- //
- replaceFrameIndices(Fn);
-
- // If register scavenging is needed, as we've enabled doing it as a
- // post-pass, scavenge the virtual registers that frame index elimination
- // inserted.
- if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) {
- scavengeFrameVirtualRegs(Fn);
- // Clear any vregs created by virtual scavenging.
- // LOCALMOD: made this call conditional with scavengeFrameVirtualregs()
- Fn.getRegInfo().clearVirtRegs();
- }
-
- // Warn on stack size when we exceeds the given limit.
- MachineFrameInfo *MFI = Fn.getFrameInfo();
- uint64_t StackSize = MFI->getStackSize();
- if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) {
- DiagnosticInfoStackSize DiagStackSize(*F, StackSize);
- F->getContext().diagnose(DiagStackSize);
- }
-
- delete RS;
- SaveBlocks.clear();
- RestoreBlocks.clear();
- return true;
-}
-
-/// calculateCallsInformation - Calculate the MaxCallFrameSize and AdjustsStack
-/// variables for the function's frame information and eliminate call frame
-/// pseudo instructions.
-void WasmPEI::calculateCallsInformation(MachineFunction &Fn) {
- const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo();
- const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
- MachineFrameInfo *MFI = Fn.getFrameInfo();
-
- unsigned MaxCallFrameSize = 0;
- bool AdjustsStack = MFI->adjustsStack();
-
- // Get the function call frame set-up and tear-down instruction opcode
- unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
- unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
-
- // Early exit for targets which have no call frame setup/destroy pseudo
- // instructions.
- if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
- return;
-
- std::vector<MachineBasicBlock::iterator> FrameSDOps;
- for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
- for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
- if (I->getOpcode() == FrameSetupOpcode ||
- I->getOpcode() == FrameDestroyOpcode) {
- assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
- " instructions should have a single immediate argument!");
- unsigned Size = I->getOperand(0).getImm();
- if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
- AdjustsStack = true;
- FrameSDOps.push_back(I);
- } else if (I->isInlineAsm()) {
- // Some inline asm's need a stack frame, as indicated by operand 1.
- unsigned ExtraInfo = I->getOperand(InlineAsm::MIOp_ExtraInfo).getImm();
- if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
- AdjustsStack = true;
- }
-
- MFI->setAdjustsStack(AdjustsStack);
- MFI->setMaxCallFrameSize(MaxCallFrameSize);
-
- for (std::vector<MachineBasicBlock::iterator>::iterator
- i = FrameSDOps.begin(), e = FrameSDOps.end(); i != e; ++i) {
- MachineBasicBlock::iterator I = *i;
-
- // If call frames are not being included as part of the stack frame, and
- // the target doesn't indicate otherwise, remove the call frame pseudos
- // here. The sub/add sp instruction pairs are still inserted, but we don't
- // need to track the SP adjustment for frame index elimination.
- if (TFI->canSimplifyCallFramePseudos(Fn))
- TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
- }
-}
-
-void WasmPEI::assignCalleeSavedSpillSlots(MachineFunction &F,
- const BitVector &SavedRegs) {
- // These are used to keep track the callee-save area. Initialize them.
- MinCSFrameIndex = INT_MAX;
- MaxCSFrameIndex = 0;
-
- if (SavedRegs.empty())
- return;
-
- const TargetRegisterInfo *RegInfo = F.getSubtarget().getRegisterInfo();
- const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&F);
-
- std::vector<CalleeSavedInfo> CSI;
- for (unsigned i = 0; CSRegs[i]; ++i) {
- unsigned Reg = CSRegs[i];
- if (SavedRegs.test(Reg))
- CSI.push_back(CalleeSavedInfo(Reg));
- }
-
- const TargetFrameLowering *TFI = F.getSubtarget().getFrameLowering();
- MachineFrameInfo *MFI = F.getFrameInfo();
- if (!TFI->assignCalleeSavedSpillSlots(F, RegInfo, CSI)) {
- // If target doesn't implement this, use generic code.
-
- if (CSI.empty())
- return; // Early exit if no callee saved registers are modified!
-
- unsigned NumFixedSpillSlots;
- const TargetFrameLowering::SpillSlot *FixedSpillSlots =
- TFI->getCalleeSavedSpillSlots(NumFixedSpillSlots);
-
- // Now that we know which registers need to be saved and restored, allocate
- // stack slots for them.
- for (std::vector<CalleeSavedInfo>::iterator I = CSI.begin(), E = CSI.end();
- I != E; ++I) {
- unsigned Reg = I->getReg();
- const TargetRegisterClass *RC = RegInfo->getMinimalPhysRegClass(Reg);
-
- int FrameIdx;
- if (RegInfo->hasReservedSpillSlot(F, Reg, FrameIdx)) {
- I->setFrameIdx(FrameIdx);
- continue;
- }
-
- // Check to see if this physreg must be spilled to a particular stack slot
- // on this target.
- const TargetFrameLowering::SpillSlot *FixedSlot = FixedSpillSlots;
- while (FixedSlot != FixedSpillSlots + NumFixedSpillSlots &&
- FixedSlot->Reg != Reg)
- ++FixedSlot;
-
- if (FixedSlot == FixedSpillSlots + NumFixedSpillSlots) {
- // Nope, just spill it anywhere convenient.
- unsigned Align = RC->getAlignment();
- unsigned StackAlign = TFI->getStackAlignment();
-
- // We may not be able to satisfy the desired alignment specification of
- // the TargetRegisterClass if the stack alignment is smaller. Use the
- // min.
- Align = std::min(Align, StackAlign);
- FrameIdx = MFI->CreateStackObject(RC->getSize(), Align, true);
- if ((unsigned)FrameIdx < MinCSFrameIndex) MinCSFrameIndex = FrameIdx;
- if ((unsigned)FrameIdx > MaxCSFrameIndex) MaxCSFrameIndex = FrameIdx;
- } else {
- // Spill it to the stack where we must.
- FrameIdx =
- MFI->CreateFixedSpillStackObject(RC->getSize(), FixedSlot->Offset);
- }
-
- I->setFrameIdx(FrameIdx);
- }
- }
-
- MFI->setCalleeSavedInfo(CSI);
-}
-
-/// Helper function to update the liveness information for the callee-saved
-/// registers.
-static void updateLiveness(MachineFunction &MF) {
- MachineFrameInfo *MFI = MF.getFrameInfo();
- // Visited will contain all the basic blocks that are in the region
- // where the callee saved registers are alive:
- // - Anything that is not Save or Restore -> LiveThrough.
- // - Save -> LiveIn.
- // - Restore -> LiveOut.
- // The live-out is not attached to the block, so no need to keep
- // Restore in this set.
- SmallPtrSet<MachineBasicBlock *, 8> Visited;
- SmallVector<MachineBasicBlock *, 8> WorkList;
- MachineBasicBlock *Entry = &MF.front();
- MachineBasicBlock *Save = MFI->getSavePoint();
-
- if (!Save)
- Save = Entry;
-
- if (Entry != Save) {
- WorkList.push_back(Entry);
- Visited.insert(Entry);
- }
- Visited.insert(Save);
-
- MachineBasicBlock *Restore = MFI->getRestorePoint();
- if (Restore)
- // By construction Restore cannot be visited, otherwise it
- // means there exists a path to Restore that does not go
- // through Save.
- WorkList.push_back(Restore);
-
- while (!WorkList.empty()) {
- const MachineBasicBlock *CurBB = WorkList.pop_back_val();
- // By construction, the region that is after the save point is
- // dominated by the Save and post-dominated by the Restore.
- if (CurBB == Save && Save != Restore)
- continue;
- // Enqueue all the successors not already visited.
- // Those are by construction either before Save or after Restore.
- for (MachineBasicBlock *SuccBB : CurBB->successors())
- if (Visited.insert(SuccBB).second)
- WorkList.push_back(SuccBB);
- }
-
- const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
-
- for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
- for (MachineBasicBlock *MBB : Visited) {
- MCPhysReg Reg = CSI[i].getReg();
- // Add the callee-saved register as live-in.
- // It's killed at the spill.
- if (!MBB->isLiveIn(Reg))
- MBB->addLiveIn(Reg);
- }
- }
-}
-
-/// insertCSRSpillsAndRestores - Insert spill and restore code for
-/// callee saved registers used in the function.
-///
-void WasmPEI::insertCSRSpillsAndRestores(MachineFunction &Fn) {
- // Get callee saved register information.
- MachineFrameInfo *MFI = Fn.getFrameInfo();
- const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
-
- MFI->setCalleeSavedInfoValid(true);
-
- // Early exit if no callee saved registers are modified!
- if (CSI.empty())
- return;
-
- const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo();
- const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
- const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();
- MachineBasicBlock::iterator I;
-
- // Spill using target interface.
- for (MachineBasicBlock *SaveBlock : SaveBlocks) {
- I = SaveBlock->begin();
- if (!TFI->spillCalleeSavedRegisters(*SaveBlock, I, CSI, TRI)) {
- for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
- // Insert the spill to the stack frame.
- unsigned Reg = CSI[i].getReg();
- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
- TII.storeRegToStackSlot(*SaveBlock, I, Reg, true, CSI[i].getFrameIdx(),
- RC, TRI);
- }
- }
- // Update the live-in information of all the blocks up to the save point.
- updateLiveness(Fn);
- }
-
- // Restore using target interface.
- for (MachineBasicBlock *MBB : RestoreBlocks) {
- I = MBB->end();
-
- // Skip over all terminator instructions, which are part of the return
- // sequence.
- MachineBasicBlock::iterator I2 = I;
- while (I2 != MBB->begin() && (--I2)->isTerminator())
- I = I2;
-
- bool AtStart = I == MBB->begin();
- MachineBasicBlock::iterator BeforeI = I;
- if (!AtStart)
- --BeforeI;
-
- // Restore all registers immediately before the return and any
- // terminators that precede it.
- if (!TFI->restoreCalleeSavedRegisters(*MBB, I, CSI, TRI)) {
- for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
- unsigned Reg = CSI[i].getReg();
- const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
- TII.loadRegFromStackSlot(*MBB, I, Reg, CSI[i].getFrameIdx(), RC, TRI);
- assert(I != MBB->begin() &&
- "loadRegFromStackSlot didn't insert any code!");
- // Insert in reverse order. loadRegFromStackSlot can insert
- // multiple instructions.
- if (AtStart)
- I = MBB->begin();
- else {
- I = BeforeI;
- ++I;
- }
- }
- }
- }
-}
-
-/// AdjustStackOffset - Helper function used to adjust the stack frame offset.
-static inline void
-AdjustStackOffset(MachineFrameInfo *MFI, int FrameIdx,
- bool StackGrowsDown, int64_t &Offset,
- unsigned &MaxAlign, unsigned Skew) {
- // If the stack grows down, add the object size to find the lowest address.
- if (StackGrowsDown)
- Offset += MFI->getObjectSize(FrameIdx);
-
- unsigned Align = MFI->getObjectAlignment(FrameIdx);
-
- // If the alignment of this object is greater than that of the stack, then
- // increase the stack alignment to match.
- MaxAlign = std::max(MaxAlign, Align);
-
- // Adjust to alignment boundary.
- Offset = RoundUpToAlignment(Offset, Align, Skew);
-
- if (StackGrowsDown) {
- DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << -Offset << "]\n");
- MFI->setObjectOffset(FrameIdx, -Offset); // Set the computed offset
- } else {
- DEBUG(dbgs() << "alloc FI(" << FrameIdx << ") at SP[" << Offset << "]\n");
- MFI->setObjectOffset(FrameIdx, Offset);
- Offset += MFI->getObjectSize(FrameIdx);
- }
-}
-
-/// AssignProtectedObjSet - Helper function to assign large stack objects (i.e.,
-/// those required to be close to the Stack Protector) to stack offsets.
-static void
-AssignProtectedObjSet(const StackObjSet &UnassignedObjs,
- SmallSet<int, 16> &ProtectedObjs,
- MachineFrameInfo *MFI, bool StackGrowsDown,
- int64_t &Offset, unsigned &MaxAlign, unsigned Skew) {
-
- for (StackObjSet::const_iterator I = UnassignedObjs.begin(),
- E = UnassignedObjs.end(); I != E; ++I) {
- int i = *I;
- AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign, Skew);
- ProtectedObjs.insert(i);
- }
-}
-
-/// calculateFrameObjectOffsets - Calculate actual frame offsets for all of the
-/// abstract stack objects.
-///
-void WasmPEI::calculateFrameObjectOffsets(MachineFunction &Fn) {
- const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
- StackProtector *SP = &getAnalysis<StackProtector>();
-
- bool StackGrowsDown =
- TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown;
-
- // Loop over all of the stack objects, assigning sequential addresses...
- MachineFrameInfo *MFI = Fn.getFrameInfo();
-
- // Start at the beginning of the local area.
- // The Offset is the distance from the stack top in the direction
- // of stack growth -- so it's always nonnegative.
- int LocalAreaOffset = TFI.getOffsetOfLocalArea();
- if (StackGrowsDown)
- LocalAreaOffset = -LocalAreaOffset;
- assert(LocalAreaOffset >= 0
- && "Local area offset should be in direction of stack growth");
- int64_t Offset = LocalAreaOffset;
-
- // Skew to be applied to alignment.
- unsigned Skew = TFI.getStackAlignmentSkew(Fn);
-
- // If there are fixed sized objects that are preallocated in the local area,
- // non-fixed objects can't be allocated right at the start of local area.
- // We currently don't support filling in holes in between fixed sized
- // objects, so we adjust 'Offset' to point to the end of last fixed sized
- // preallocated object.
- for (int i = MFI->getObjectIndexBegin(); i != 0; ++i) {
- int64_t FixedOff;
- if (StackGrowsDown) {
- // The maximum distance from the stack pointer is at lower address of
- // the object -- which is given by offset. For down growing stack
- // the offset is negative, so we negate the offset to get the distance.
- FixedOff = -MFI->getObjectOffset(i);
- } else {
- // The maximum distance from the start pointer is at the upper
- // address of the object.
- FixedOff = MFI->getObjectOffset(i) + MFI->getObjectSize(i);
- }
- if (FixedOff > Offset) Offset = FixedOff;
- }
-
- // First assign frame offsets to stack objects that are used to spill
- // callee saved registers.
- if (StackGrowsDown) {
- for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
- // If the stack grows down, we need to add the size to find the lowest
- // address of the object.
- Offset += MFI->getObjectSize(i);
-
- unsigned Align = MFI->getObjectAlignment(i);
- // Adjust to alignment boundary
- Offset = RoundUpToAlignment(Offset, Align, Skew);
-
- MFI->setObjectOffset(i, -Offset); // Set the computed offset
- }
- } else {
- int MaxCSFI = MaxCSFrameIndex, MinCSFI = MinCSFrameIndex;
- for (int i = MaxCSFI; i >= MinCSFI ; --i) {
- unsigned Align = MFI->getObjectAlignment(i);
- // Adjust to alignment boundary
- Offset = RoundUpToAlignment(Offset, Align, Skew);
-
- MFI->setObjectOffset(i, Offset);
- Offset += MFI->getObjectSize(i);
- }
- }
-
- unsigned MaxAlign = MFI->getMaxAlignment();
-
- // Make sure the special register scavenging spill slot is closest to the
- // incoming stack pointer if a frame pointer is required and is closer
- // to the incoming rather than the final stack pointer.
- const TargetRegisterInfo *RegInfo = Fn.getSubtarget().getRegisterInfo();
- bool EarlyScavengingSlots = (TFI.hasFP(Fn) &&
- TFI.isFPCloseToIncomingSP() &&
- RegInfo->useFPForScavengingIndex(Fn) &&
- !RegInfo->needsStackRealignment(Fn));
- if (RS && EarlyScavengingSlots) {
- SmallVector<int, 2> SFIs;
- RS->getScavengingFrameIndices(SFIs);
- for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
- IE = SFIs.end(); I != IE; ++I)
- AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
- }
-
- // FIXME: Once this is working, then enable flag will change to a target
- // check for whether the frame is large enough to want to use virtual
- // frame index registers. Functions which don't want/need this optimization
- // will continue to use the existing code path.
- if (MFI->getUseLocalStackAllocationBlock()) {
- unsigned Align = MFI->getLocalFrameMaxAlign();
-
- // Adjust to alignment boundary.
- Offset = RoundUpToAlignment(Offset, Align, Skew);
-
- DEBUG(dbgs() << "Local frame base offset: " << Offset << "\n");
-
- // Resolve offsets for objects in the local block.
- for (unsigned i = 0, e = MFI->getLocalFrameObjectCount(); i != e; ++i) {
- std::pair<int, int64_t> Entry = MFI->getLocalFrameObjectMap(i);
- int64_t FIOffset = (StackGrowsDown ? -Offset : Offset) + Entry.second;
- DEBUG(dbgs() << "alloc FI(" << Entry.first << ") at SP[" <<
- FIOffset << "]\n");
- MFI->setObjectOffset(Entry.first, FIOffset);
- }
- // Allocate the local block
- Offset += MFI->getLocalFrameSize();
-
- MaxAlign = std::max(Align, MaxAlign);
- }
-
- // Make sure that the stack protector comes before the local variables on the
- // stack.
- SmallSet<int, 16> ProtectedObjs;
- if (MFI->getStackProtectorIndex() >= 0) {
- StackObjSet LargeArrayObjs;
- StackObjSet SmallArrayObjs;
- StackObjSet AddrOfObjs;
-
- AdjustStackOffset(MFI, MFI->getStackProtectorIndex(), StackGrowsDown,
- Offset, MaxAlign, Skew);
-
- // Assign large stack objects first.
- for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
- if (MFI->isObjectPreAllocated(i) &&
- MFI->getUseLocalStackAllocationBlock())
- continue;
- if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
- continue;
- if (RS && RS->isScavengingFrameIndex((int)i))
- continue;
- if (MFI->isDeadObjectIndex(i))
- continue;
- if (MFI->getStackProtectorIndex() == (int)i)
- continue;
-
- switch (SP->getSSPLayout(MFI->getObjectAllocation(i))) {
- case StackProtector::SSPLK_None:
- continue;
- case StackProtector::SSPLK_SmallArray:
- SmallArrayObjs.insert(i);
- continue;
- case StackProtector::SSPLK_AddrOf:
- AddrOfObjs.insert(i);
- continue;
- case StackProtector::SSPLK_LargeArray:
- LargeArrayObjs.insert(i);
- continue;
- }
- llvm_unreachable("Unexpected SSPLayoutKind.");
- }
-
- AssignProtectedObjSet(LargeArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign, Skew);
- AssignProtectedObjSet(SmallArrayObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign, Skew);
- AssignProtectedObjSet(AddrOfObjs, ProtectedObjs, MFI, StackGrowsDown,
- Offset, MaxAlign, Skew);
- }
-
- // Then assign frame offsets to stack objects that are not used to spill
- // callee saved registers.
- for (unsigned i = 0, e = MFI->getObjectIndexEnd(); i != e; ++i) {
- if (MFI->isObjectPreAllocated(i) &&
- MFI->getUseLocalStackAllocationBlock())
- continue;
- if (i >= MinCSFrameIndex && i <= MaxCSFrameIndex)
- continue;
- if (RS && RS->isScavengingFrameIndex((int)i))
- continue;
- if (MFI->isDeadObjectIndex(i))
- continue;
- if (MFI->getStackProtectorIndex() == (int)i)
- continue;
- if (ProtectedObjs.count(i))
- continue;
-
- AdjustStackOffset(MFI, i, StackGrowsDown, Offset, MaxAlign, Skew);
- }
-
- // Make sure the special register scavenging spill slot is closest to the
- // stack pointer.
- if (RS && !EarlyScavengingSlots) {
- SmallVector<int, 2> SFIs;
- RS->getScavengingFrameIndices(SFIs);
- for (SmallVectorImpl<int>::iterator I = SFIs.begin(),
- IE = SFIs.end(); I != IE; ++I)
- AdjustStackOffset(MFI, *I, StackGrowsDown, Offset, MaxAlign, Skew);
- }
-
- if (!TFI.targetHandlesStackFrameRounding()) {
- // If we have reserved argument space for call sites in the function
- // immediately on entry to the current function, count it as part of the
- // overall stack size.
- if (MFI->adjustsStack() && TFI.hasReservedCallFrame(Fn))
- Offset += MFI->getMaxCallFrameSize();
-
- // Round up the size to a multiple of the alignment. If the function has
- // any calls or alloca's, align to the target's StackAlignment value to
- // ensure that the callee's frame or the alloca data is suitably aligned;
- // otherwise, for leaf functions, align to the TransientStackAlignment
- // value.
- unsigned StackAlign;
- if (MFI->adjustsStack() || MFI->hasVarSizedObjects() ||
- (RegInfo->needsStackRealignment(Fn) && MFI->getObjectIndexEnd() != 0))
- StackAlign = TFI.getStackAlignment();
- else
- StackAlign = TFI.getTransientStackAlignment();
-
- // If the frame pointer is eliminated, all frame offsets will be relative to
- // SP not FP. Align to MaxAlign so this works.
- StackAlign = std::max(StackAlign, MaxAlign);
- Offset = RoundUpToAlignment(Offset, StackAlign, Skew);
- }
-
- // Update frame info to pretend that this is part of the stack...
- int64_t StackSize = Offset - LocalAreaOffset;
- MFI->setStackSize(StackSize);
- NumBytesStackSpace += StackSize;
-}
-
-/// insertPrologEpilogCode - Scan the function for modified callee saved
-/// registers, insert spill code for these callee saved registers, then add
-/// prolog and epilog code to the function.
-///
-void WasmPEI::insertPrologEpilogCode(MachineFunction &Fn) {
- const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
-
- // Add prologue to the function...
- for (MachineBasicBlock *SaveBlock : SaveBlocks)
- TFI.emitPrologue(Fn, *SaveBlock);
-
- // Add epilogue to restore the callee-save registers in each exiting block.
- for (MachineBasicBlock *RestoreBlock : RestoreBlocks)
- TFI.emitEpilogue(Fn, *RestoreBlock);
-
- for (MachineBasicBlock *SaveBlock : SaveBlocks)
- TFI.inlineStackProbe(Fn, *SaveBlock);
-
- // Emit additional code that is required to support segmented stacks, if
- // we've been asked for it. This, when linked with a runtime with support
- // for segmented stacks (libgcc is one), will result in allocating stack
- // space in small chunks instead of one large contiguous block.
- if (Fn.shouldSplitStack()) {
- for (MachineBasicBlock *SaveBlock : SaveBlocks)
- TFI.adjustForSegmentedStacks(Fn, *SaveBlock);
- }
-
- // Emit additional code that is required to explicitly handle the stack in
- // HiPE native code (if needed) when loaded in the Erlang/OTP runtime. The
- // approach is rather similar to that of Segmented Stacks, but it uses a
- // different conditional check and another BIF for allocating more stack
- // space.
- if (Fn.getFunction()->getCallingConv() == CallingConv::HiPE)
- for (MachineBasicBlock *SaveBlock : SaveBlocks)
- TFI.adjustForHiPEPrologue(Fn, *SaveBlock);
-}
-
-/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
-/// register references and actual offsets.
-///
-void WasmPEI::replaceFrameIndices(MachineFunction &Fn) {
- const TargetFrameLowering &TFI = *Fn.getSubtarget().getFrameLowering();
- if (!TFI.needsFrameIndexResolution(Fn)) return;
-
- // Store SPAdj at exit of a basic block.
- SmallVector<int, 8> SPState;
- SPState.resize(Fn.getNumBlockIDs());
- SmallPtrSet<MachineBasicBlock*, 8> Reachable;
-
- // Iterate over the reachable blocks in DFS order.
- for (auto DFI = df_ext_begin(&Fn, Reachable), DFE = df_ext_end(&Fn, Reachable);
- DFI != DFE; ++DFI) {
- int SPAdj = 0;
- // Check the exit state of the DFS stack predecessor.
- if (DFI.getPathLength() >= 2) {
- MachineBasicBlock *StackPred = DFI.getPath(DFI.getPathLength() - 2);
- assert(Reachable.count(StackPred) &&
- "DFS stack predecessor is already visited.\n");
- SPAdj = SPState[StackPred->getNumber()];
- }
- MachineBasicBlock *BB = *DFI;
- replaceFrameIndices(BB, Fn, SPAdj);
- SPState[BB->getNumber()] = SPAdj;
- }
-
- // Handle the unreachable blocks.
- for (auto &BB : Fn) {
- if (Reachable.count(&BB))
- // Already handled in DFS traversal.
- continue;
- int SPAdj = 0;
- replaceFrameIndices(&BB, Fn, SPAdj);
- }
-}
-
-void WasmPEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &Fn,
- int &SPAdj) {
- assert(Fn.getSubtarget().getRegisterInfo() &&
- "getRegisterInfo() must be implemented!");
- const TargetInstrInfo &TII = *Fn.getSubtarget().getInstrInfo();
- const TargetRegisterInfo &TRI = *Fn.getSubtarget().getRegisterInfo();
- const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering();
- unsigned FrameSetupOpcode = TII.getCallFrameSetupOpcode();
- unsigned FrameDestroyOpcode = TII.getCallFrameDestroyOpcode();
-
- if (RS && !FrameIndexVirtualScavenging) RS->enterBasicBlock(BB);
-
- bool InsideCallSequence = false;
-
- for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
-
- if (I->getOpcode() == FrameSetupOpcode ||
- I->getOpcode() == FrameDestroyOpcode) {
- InsideCallSequence = (I->getOpcode() == FrameSetupOpcode);
- SPAdj += TII.getSPAdjust(I);
-
- MachineBasicBlock::iterator PrevI = BB->end();
- if (I != BB->begin()) PrevI = std::prev(I);
- TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
-
- // Visit the instructions created by eliminateCallFramePseudoInstr().
- if (PrevI == BB->end())
- I = BB->begin(); // The replaced instr was the first in the block.
- else
- I = std::next(PrevI);
- continue;
- }
-
- MachineInstr *MI = I;
- bool DoIncr = true;
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- if (!MI->getOperand(i).isFI())
- continue;
-
- // Frame indices in debug values are encoded in a target independent
- // way with simply the frame index and offset rather than any
- // target-specific addressing mode.
- if (MI->isDebugValue()) {
- assert(i == 0 && "Frame indices can only appear as the first "
- "operand of a DBG_VALUE machine instruction");
- unsigned Reg;
- MachineOperand &Offset = MI->getOperand(1);
- Offset.setImm(Offset.getImm() +
- TFI->getFrameIndexReference(
- Fn, MI->getOperand(0).getIndex(), Reg));
- MI->getOperand(0).ChangeToRegister(Reg, false /*isDef*/);
- continue;
- }
-
- // TODO: This code should be commoned with the code for
- // PATCHPOINT. There's no good reason for the difference in
- // implementation other than historical accident. The only
- // remaining difference is the unconditional use of the stack
- // pointer as the base register.
- if (MI->getOpcode() == TargetOpcode::STATEPOINT) {
- assert((!MI->isDebugValue() || i == 0) &&
- "Frame indicies can only appear as the first operand of a "
- "DBG_VALUE machine instruction");
- unsigned Reg;
- MachineOperand &Offset = MI->getOperand(i + 1);
- const unsigned refOffset =
- TFI->getFrameIndexReferenceFromSP(Fn, MI->getOperand(i).getIndex(),
- Reg);
-
- Offset.setImm(Offset.getImm() + refOffset);
- MI->getOperand(i).ChangeToRegister(Reg, false /*isDef*/);
- continue;
- }
-
- // Some instructions (e.g. inline asm instructions) can have
- // multiple frame indices and/or cause eliminateFrameIndex
- // to insert more than one instruction. We need the register
- // scavenger to go through all of these instructions so that
- // it can update its register information. We keep the
- // iterator at the point before insertion so that we can
- // revisit them in full.
- bool AtBeginning = (I == BB->begin());
- if (!AtBeginning) --I;
-
- // If this instruction has a FrameIndex operand, we need to
- // use that target machine register info object to eliminate
- // it.
- TRI.eliminateFrameIndex(MI, SPAdj, i,
- FrameIndexVirtualScavenging ? nullptr : RS);
-
- // Reset the iterator if we were at the beginning of the BB.
- if (AtBeginning) {
- I = BB->begin();
- DoIncr = false;
- }
-
- MI = nullptr;
- break;
- }
-
- // If we are looking at a call sequence, we need to keep track of
- // the SP adjustment made by each instruction in the sequence.
- // This includes both the frame setup/destroy pseudos (handled above),
- // as well as other instructions that have side effects w.r.t the SP.
- // Note that this must come after eliminateFrameIndex, because
- // if I itself referred to a frame index, we shouldn't count its own
- // adjustment.
- if (MI && InsideCallSequence)
- SPAdj += TII.getSPAdjust(MI);
-
- if (DoIncr && I != BB->end()) ++I;
-
- // Update register states.
- if (RS && !FrameIndexVirtualScavenging && MI) RS->forward(MI);
- }
-}
-
-/// scavengeFrameVirtualRegs - Replace all frame index virtual registers
-/// with physical registers. Use the register scavenger to find an
-/// appropriate register to use.
-///
-/// FIXME: Iterating over the instruction stream is unnecessary. We can simply
-/// iterate over the vreg use list, which at this point only contains machine
-/// operands for which eliminateFrameIndex need a new scratch reg.
-void
-WasmPEI::scavengeFrameVirtualRegs(MachineFunction &Fn) {
- // Run through the instructions and find any virtual registers.
- for (MachineFunction::iterator BB = Fn.begin(),
- E = Fn.end(); BB != E; ++BB) {
- RS->enterBasicBlock(&*BB);
-
- int SPAdj = 0;
-
- // The instruction stream may change in the loop, so check BB->end()
- // directly.
- for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
- // We might end up here again with a NULL iterator if we scavenged a
- // register for which we inserted spill code for definition by what was
- // originally the first instruction in BB.
- if (I == MachineBasicBlock::iterator(nullptr))
- I = BB->begin();
-
- MachineInstr *MI = I;
- MachineBasicBlock::iterator J = std::next(I);
- MachineBasicBlock::iterator P =
- I == BB->begin() ? MachineBasicBlock::iterator(nullptr)
- : std::prev(I);
-
- // RS should process this instruction before we might scavenge at this
- // location. This is because we might be replacing a virtual register
- // defined by this instruction, and if so, registers killed by this
- // instruction are available, and defined registers are not.
- RS->forward(I);
-
- for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- if (MI->getOperand(i).isReg()) {
- MachineOperand &MO = MI->getOperand(i);
- unsigned Reg = MO.getReg();
- if (Reg == 0)
- continue;
- if (!TargetRegisterInfo::isVirtualRegister(Reg))
- continue;
-
- // When we first encounter a new virtual register, it
- // must be a definition.
- assert(MI->getOperand(i).isDef() &&
- "frame index virtual missing def!");
- // Scavenge a new scratch register
- const TargetRegisterClass *RC = Fn.getRegInfo().getRegClass(Reg);
- unsigned ScratchReg = RS->scavengeRegister(RC, J, SPAdj);
-
- ++NumScavengedRegs;
-
- // Replace this reference to the virtual register with the
- // scratch register.
- assert (ScratchReg && "Missing scratch register!");
- Fn.getRegInfo().replaceRegWith(Reg, ScratchReg);
-
- // Because this instruction was processed by the RS before this
- // register was allocated, make sure that the RS now records the
- // register as being used.
- RS->setRegUsed(ScratchReg);
- }
- }
-
- // If the scavenger needed to use one of its spill slots, the
- // spill code will have been inserted in between I and J. This is a
- // problem because we need the spill code before I: Move I to just
- // prior to J.
- if (I != std::prev(J)) {
- BB->splice(J, &*BB, I);
-
- // Before we move I, we need to prepare the RS to visit I again.
- // Specifically, RS will assert if it sees uses of registers that
- // it believes are undefined. Because we have already processed
- // register kills in I, when it visits I again, it will believe that
- // those registers are undefined. To avoid this situation, unprocess
- // the instruction I.
- assert(RS->getCurrentPosition() == I &&
- "The register scavenger has an unexpected position");
- I = P;
- RS->unprocess(P);
- } else
- ++I;
- }
- }
-}
diff --git a/gnu/llvm/lib/Target/X86/AsmParser/Makefile b/gnu/llvm/lib/Target/X86/AsmParser/Makefile
deleted file mode 100644
index f834dfc300a..00000000000
--- a/gnu/llvm/lib/Target/X86/AsmParser/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/X86/AsmParser/Makefile -------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86AsmParser
-
-# Hack: we need to include 'main' X86 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/X86/Disassembler/Makefile b/gnu/llvm/lib/Target/X86/Disassembler/Makefile
deleted file mode 100644
index 51e7b828cf2..00000000000
--- a/gnu/llvm/lib/Target/X86/Disassembler/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- lib/Target/X86/Disassembler/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86Disassembler
-
-# Hack: we need to include 'main' x86 target directory to grab private headers.
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
-
-.PHONY: $(PROJ_SRC_DIR)/X86DisassemblerDecoder.c
diff --git a/gnu/llvm/lib/Target/X86/Disassembler/X86Disassembler.h b/gnu/llvm/lib/Target/X86/Disassembler/X86Disassembler.h
deleted file mode 100644
index d7f426b2641..00000000000
--- a/gnu/llvm/lib/Target/X86/Disassembler/X86Disassembler.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//===-- X86Disassembler.h - Disassembler for x86 and x86_64 -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The X86 disassembler is a table-driven disassembler for the 16-, 32-, and
-// 64-bit X86 instruction sets. The main decode sequence for an assembly
-// instruction in this disassembler is:
-//
-// 1. Read the prefix bytes and determine the attributes of the instruction.
-// These attributes, recorded in enum attributeBits
-// (X86DisassemblerDecoderCommon.h), form a bitmask. The table CONTEXTS_SYM
-// provides a mapping from bitmasks to contexts, which are represented by
-// enum InstructionContext (ibid.).
-//
-// 2. Read the opcode, and determine what kind of opcode it is. The
-// disassembler distinguishes four kinds of opcodes, which are enumerated in
-// OpcodeType (X86DisassemblerDecoderCommon.h): one-byte (0xnn), two-byte
-// (0x0f 0xnn), three-byte-38 (0x0f 0x38 0xnn), or three-byte-3a
-// (0x0f 0x3a 0xnn). Mandatory prefixes are treated as part of the context.
-//
-// 3. Depending on the opcode type, look in one of four ClassDecision structures
-// (X86DisassemblerDecoderCommon.h). Use the opcode class to determine which
-// OpcodeDecision (ibid.) to look the opcode in. Look up the opcode, to get
-// a ModRMDecision (ibid.).
-//
-// 4. Some instructions, such as escape opcodes or extended opcodes, or even
-// instructions that have ModRM*Reg / ModRM*Mem forms in LLVM, need the
-// ModR/M byte to complete decode. The ModRMDecision's type is an entry from
-// ModRMDecisionType (X86DisassemblerDecoderCommon.h) that indicates if the
-// ModR/M byte is required and how to interpret it.
-//
-// 5. After resolving the ModRMDecision, the disassembler has a unique ID
-// of type InstrUID (X86DisassemblerDecoderCommon.h). Looking this ID up in
-// INSTRUCTIONS_SYM yields the name of the instruction and the encodings and
-// meanings of its operands.
-//
-// 6. For each operand, its encoding is an entry from OperandEncoding
-// (X86DisassemblerDecoderCommon.h) and its type is an entry from
-// OperandType (ibid.). The encoding indicates how to read it from the
-// instruction; the type indicates how to interpret the value once it has
-// been read. For example, a register operand could be stored in the R/M
-// field of the ModR/M byte, the REG field of the ModR/M byte, or added to
-// the main opcode. This is orthogonal from its meaning (an GPR or an XMM
-// register, for instance). Given this information, the operands can be
-// extracted and interpreted.
-//
-// 7. As the last step, the disassembler translates the instruction information
-// and operands into a format understandable by the client - in this case, an
-// MCInst for use by the MC infrastructure.
-//
-// The disassembler is broken broadly into two parts: the table emitter that
-// emits the instruction decode tables discussed above during compilation, and
-// the disassembler itself. The table emitter is documented in more detail in
-// utils/TableGen/X86DisassemblerEmitter.h.
-//
-// X86Disassembler.h contains the public interface for the disassembler,
-// adhering to the MCDisassembler interface.
-// X86Disassembler.cpp contains the code responsible for step 7, and for
-// invoking the decoder to execute steps 1-6.
-// X86DisassemblerDecoderCommon.h contains the definitions needed by both the
-// table emitter and the disassembler.
-// X86DisassemblerDecoder.h contains the public interface of the decoder,
-// factored out into C for possible use by other projects.
-// X86DisassemblerDecoder.c contains the source code of the decoder, which is
-// responsible for steps 1-6.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLER_H
-#define LLVM_LIB_TARGET_X86_DISASSEMBLER_X86DISASSEMBLER_H
-
-#include "X86DisassemblerDecoderCommon.h"
-#include "llvm/MC/MCDisassembler.h"
-
-namespace llvm {
-
-class MCInst;
-class MCInstrInfo;
-class MCSubtargetInfo;
-class MemoryObject;
-class raw_ostream;
-
-namespace X86Disassembler {
-
-/// Generic disassembler for all X86 platforms. All each platform class should
-/// have to do is subclass the constructor, and provide a different
-/// disassemblerMode value.
-class X86GenericDisassembler : public MCDisassembler {
- std::unique_ptr<const MCInstrInfo> MII;
-public:
- X86GenericDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
- std::unique_ptr<const MCInstrInfo> MII);
-public:
- DecodeStatus getInstruction(MCInst &instr, uint64_t &size,
- ArrayRef<uint8_t> Bytes, uint64_t Address,
- raw_ostream &vStream,
- raw_ostream &cStream) const override;
-
-private:
- DisassemblerMode fMode;
-};
-
-} // namespace X86Disassembler
-
-} // namespace llvm
-
-#endif
diff --git a/gnu/llvm/lib/Target/X86/InstPrinter/Makefile b/gnu/llvm/lib/Target/X86/InstPrinter/Makefile
deleted file mode 100644
index c82aa330a20..00000000000
--- a/gnu/llvm/lib/Target/X86/InstPrinter/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/X86/AsmPrinter/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86AsmPrinter
-
-# Hack: we need to include 'main' x86 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/X86/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/X86/MCTargetDesc/Makefile
deleted file mode 100644
index b19774ee379..00000000000
--- a/gnu/llvm/lib/Target/X86/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/X86/TargetDesc/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86Desc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp b/gnu/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
deleted file mode 100644
index ddb764facdb..00000000000
--- a/gnu/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//===-- X86ELFRelocationInfo.cpp ----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MCTargetDesc/X86MCTargetDesc.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCRelocationInfo.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Support/ELF.h"
-
-using namespace llvm;
-using namespace object;
-using namespace ELF;
-
-namespace {
-class X86_64ELFRelocationInfo : public MCRelocationInfo {
-public:
- X86_64ELFRelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {}
-
- const MCExpr *createExprForRelocation(RelocationRef Rel) override {
- uint64_t RelType = Rel.getType();
- elf_symbol_iterator SymI = Rel.getSymbol();
-
- ErrorOr<StringRef> SymNameOrErr = SymI->getName();
- if (std::error_code EC = SymNameOrErr.getError())
- report_fatal_error(EC.message());
- StringRef SymName = *SymNameOrErr;
-
- ErrorOr<uint64_t> SymAddr = SymI->getAddress();
- if (std::error_code EC = SymAddr.getError())
- report_fatal_error(EC.message());
- uint64_t SymSize = SymI->getSize();
- int64_t Addend = *ELFRelocationRef(Rel).getAddend();
-
- MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
- // FIXME: check that the value is actually the same.
- if (!Sym->isVariable())
- Sym->setVariableValue(MCConstantExpr::create(*SymAddr, Ctx));
-
- const MCExpr *Expr = nullptr;
- // If hasAddend is true, then we need to add Addend (r_addend) to Expr.
- bool hasAddend = false;
-
- // The AMD64 SysV ABI says:
- // A: the addend used to compute the value of the relocatable field.
- // B: the base address at which a shared object has been loaded into memory
- // during execution. Generally, a shared object is built with a 0 base
- // virtual address, but the execution address will be different.
- // G: the offset into the global offset table at which the relocation
- // entry's symbol will reside during execution.
- // GOT: the address of the global offset table.
- // L: the place (section offset or address) of the Procedure Linkage Table
- // entry for a symbol.
- // P: the place (section offset or address) of the storage unit being
- // relocated (computed using r_offset).
- // S: the value of the symbol whose index resides in the relocation entry.
- // Z: the size of the symbol whose index resides in the relocation entry.
-
- switch(RelType) {
- case R_X86_64_NONE:
- case R_X86_64_COPY:
- // none
- break;
- case R_X86_64_64:
- case R_X86_64_16:
- case R_X86_64_8:
- // S + A
- case R_X86_64_32:
- case R_X86_64_32S:
- // S + A (We don't care about the result not fitting in 32 bits.)
- case R_X86_64_PC32:
- case R_X86_64_PC16:
- case R_X86_64_PC8:
- case R_X86_64_PC64:
- // S + A - P (P/pcrel is implicit)
- hasAddend = true;
- Expr = MCSymbolRefExpr::create(Sym, Ctx);
- break;
- case R_X86_64_GOT32:
- case R_X86_64_GOT64:
- case R_X86_64_GOTPC32:
- case R_X86_64_GOTPC64:
- case R_X86_64_GOTPLT64:
- // G + A
- hasAddend = true;
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, Ctx);
- break;
- case R_X86_64_PLT32:
- // L + A - P -> S@PLT + A
- hasAddend = true;
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_PLT, Ctx);
- break;
- case R_X86_64_GLOB_DAT:
- case R_X86_64_JUMP_SLOT:
- // S
- Expr = MCSymbolRefExpr::create(Sym, Ctx);
- break;
- case R_X86_64_GOTPCREL:
- case R_X86_64_GOTPCREL64:
- // G + GOT + A - P -> S@GOTPCREL + A
- hasAddend = true;
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
- break;
- case R_X86_64_GOTOFF64:
- // S + A - GOT
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTOFF, Ctx);
- break;
- case R_X86_64_PLTOFF64:
- // L + A - GOT
- break;
- case R_X86_64_SIZE32:
- case R_X86_64_SIZE64:
- // Z + A
- Expr = MCConstantExpr::create(SymSize, Ctx);
- break;
- default:
- Expr = MCSymbolRefExpr::create(Sym, Ctx);
- break;
- }
- if (Expr && hasAddend && Addend != 0)
- Expr = MCBinaryExpr::createAdd(Expr,
- MCConstantExpr::create(Addend, Ctx),
- Ctx);
- return Expr;
- }
-};
-} // End unnamed namespace
-
-/// createX86ELFRelocationInfo - Construct an X86 Mach-O RelocationInfo.
-MCRelocationInfo *llvm::createX86_64ELFRelocationInfo(MCContext &Ctx) {
- // We only handle x86-64 for now.
- return new X86_64ELFRelocationInfo(Ctx);
-}
diff --git a/gnu/llvm/lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp b/gnu/llvm/lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp
deleted file mode 100644
index 9bfe999424f..00000000000
--- a/gnu/llvm/lib/Target/X86/MCTargetDesc/X86MachORelocationInfo.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//===-- X86MachORelocationInfo.cpp ----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "MCTargetDesc/X86MCTargetDesc.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCInst.h"
-#include "llvm/MC/MCRelocationInfo.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Object/MachO.h"
-
-using namespace llvm;
-using namespace object;
-using namespace MachO;
-
-namespace {
-class X86_64MachORelocationInfo : public MCRelocationInfo {
-public:
- X86_64MachORelocationInfo(MCContext &Ctx) : MCRelocationInfo(Ctx) {}
-
- const MCExpr *createExprForRelocation(RelocationRef Rel) override {
- const MachOObjectFile *Obj = cast<MachOObjectFile>(Rel.getObject());
-
- uint64_t RelType = Rel.getType();
- symbol_iterator SymI = Rel.getSymbol();
-
- ErrorOr<StringRef> SymNameOrErr = SymI->getName();
- if (std::error_code EC = SymNameOrErr.getError())
- report_fatal_error(EC.message());
- StringRef SymName = *SymNameOrErr;
- uint64_t SymAddr = SymI->getValue();
-
- any_relocation_info RE = Obj->getRelocation(Rel.getRawDataRefImpl());
- bool isPCRel = Obj->getAnyRelocationPCRel(RE);
-
- MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName);
- // FIXME: check that the value is actually the same.
- if (!Sym->isVariable())
- Sym->setVariableValue(MCConstantExpr::create(SymAddr, Ctx));
- const MCExpr *Expr = nullptr;
-
- switch(RelType) {
- case X86_64_RELOC_TLV:
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_TLVP, Ctx);
- break;
- case X86_64_RELOC_SIGNED_4:
- Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
- MCConstantExpr::create(4, Ctx),
- Ctx);
- break;
- case X86_64_RELOC_SIGNED_2:
- Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
- MCConstantExpr::create(2, Ctx),
- Ctx);
- break;
- case X86_64_RELOC_SIGNED_1:
- Expr = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Sym, Ctx),
- MCConstantExpr::create(1, Ctx),
- Ctx);
- break;
- case X86_64_RELOC_GOT_LOAD:
- Expr = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOTPCREL, Ctx);
- break;
- case X86_64_RELOC_GOT:
- Expr = MCSymbolRefExpr::create(Sym, isPCRel ?
- MCSymbolRefExpr::VK_GOTPCREL :
- MCSymbolRefExpr::VK_GOT,
- Ctx);
- break;
- case X86_64_RELOC_SUBTRACTOR:
- {
- Rel.moveNext();
- any_relocation_info RENext =
- Obj->getRelocation(Rel.getRawDataRefImpl());
-
- // X86_64_SUBTRACTOR must be followed by a relocation of type
- // X86_64_RELOC_UNSIGNED.
- // NOTE: Scattered relocations don't exist on x86_64.
- unsigned RType = Obj->getAnyRelocationType(RENext);
- if (RType != X86_64_RELOC_UNSIGNED)
- report_fatal_error("Expected X86_64_RELOC_UNSIGNED after "
- "X86_64_RELOC_SUBTRACTOR.");
-
- const MCExpr *LHS = MCSymbolRefExpr::create(Sym, Ctx);
-
- symbol_iterator RSymI = Rel.getSymbol();
- uint64_t RSymAddr = RSymI->getValue();
- ErrorOr<StringRef> RSymName = RSymI->getName();
- if (std::error_code EC = RSymName.getError())
- report_fatal_error(EC.message());
-
- MCSymbol *RSym = Ctx.getOrCreateSymbol(*RSymName);
- if (!RSym->isVariable())
- RSym->setVariableValue(MCConstantExpr::create(RSymAddr, Ctx));
-
- const MCExpr *RHS = MCSymbolRefExpr::create(RSym, Ctx);
-
- Expr = MCBinaryExpr::createSub(LHS, RHS, Ctx);
- break;
- }
- default:
- Expr = MCSymbolRefExpr::create(Sym, Ctx);
- break;
- }
- return Expr;
- }
-};
-} // End unnamed namespace
-
-/// createX86_64MachORelocationInfo - Construct an X86-64 Mach-O RelocationInfo.
-MCRelocationInfo *llvm::createX86_64MachORelocationInfo(MCContext &Ctx) {
- return new X86_64MachORelocationInfo(Ctx);
-}
diff --git a/gnu/llvm/lib/Target/X86/Makefile b/gnu/llvm/lib/Target/X86/Makefile
deleted file mode 100644
index e518fecf044..00000000000
--- a/gnu/llvm/lib/Target/X86/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Target/X86/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMX86CodeGen
-TARGET = X86
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = X86GenRegisterInfo.inc X86GenInstrInfo.inc \
- X86GenAsmWriter.inc X86GenAsmMatcher.inc \
- X86GenAsmWriter1.inc X86GenDAGISel.inc \
- X86GenDisassemblerTables.inc X86GenFastISel.inc \
- X86GenCallingConv.inc X86GenSubtargetInfo.inc
-
-DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc Utils
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/X86/TargetInfo/Makefile b/gnu/llvm/lib/Target/X86/TargetInfo/Makefile
deleted file mode 100644
index ee91982df0c..00000000000
--- a/gnu/llvm/lib/Target/X86/TargetInfo/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/X86/TargetInfo/Makefile ------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86Info
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/X86/Utils/Makefile b/gnu/llvm/lib/Target/X86/Utils/Makefile
deleted file mode 100644
index 1df6f0f561d..00000000000
--- a/gnu/llvm/lib/Target/X86/Utils/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Target/X86/Utils/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
-LIBRARYNAME = LLVMX86Utils
-
-# Hack: we need to include 'main' x86 target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/XCore/Disassembler/Makefile b/gnu/llvm/lib/Target/XCore/Disassembler/Makefile
deleted file mode 100644
index 4caffdd1da6..00000000000
--- a/gnu/llvm/lib/Target/XCore/Disassembler/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/XCore/Disassembler/Makefile --------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMXCoreDisassembler
-
-# Hack: we need to include 'main' XCore target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/XCore/InstPrinter/Makefile b/gnu/llvm/lib/Target/XCore/InstPrinter/Makefile
deleted file mode 100644
index 1c1c61299c3..00000000000
--- a/gnu/llvm/lib/Target/XCore/InstPrinter/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/XCore/AsmPrinter/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMXCoreAsmPrinter
-
-# Hack: we need to include 'main' xcore target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/XCore/MCTargetDesc/Makefile b/gnu/llvm/lib/Target/XCore/MCTargetDesc/Makefile
deleted file mode 100644
index de61543bfe9..00000000000
--- a/gnu/llvm/lib/Target/XCore/MCTargetDesc/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/XCore/TargetDesc/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMXCoreDesc
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPP.Flags += -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Target/XCore/Makefile b/gnu/llvm/lib/Target/XCore/Makefile
deleted file mode 100644
index 92ddc886087..00000000000
--- a/gnu/llvm/lib/Target/XCore/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-##===- lib/Target/XCore/Makefile ---------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMXCoreCodeGen
-TARGET = XCore
-
-# Make sure that tblgen is run, first thing.
-BUILT_SOURCES = XCoreGenRegisterInfo.inc XCoreGenInstrInfo.inc \
- XCoreGenAsmWriter.inc \
- XCoreGenDAGISel.inc XCoreGenCallingConv.inc \
- XCoreGenDisassemblerTables.inc XCoreGenSubtargetInfo.inc
-
-DIRS = Disassembler InstPrinter TargetInfo MCTargetDesc
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Target/XCore/TargetInfo/Makefile b/gnu/llvm/lib/Target/XCore/TargetInfo/Makefile
deleted file mode 100644
index f8a40951749..00000000000
--- a/gnu/llvm/lib/Target/XCore/TargetInfo/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-##===- lib/Target/XCore/TargetInfo/Makefile ----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-LIBRARYNAME = LLVMXCoreInfo
-
-# Hack: we need to include 'main' target directory to grab private headers
-CPPFLAGS = -I$(PROJ_OBJ_DIR)/.. -I$(PROJ_SRC_DIR)/..
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Transforms/Hello/Makefile b/gnu/llvm/lib/Transforms/Hello/Makefile
deleted file mode 100644
index f1e31489d3c..00000000000
--- a/gnu/llvm/lib/Transforms/Hello/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-##===- lib/Transforms/Hello/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMHello
-LOADABLE_MODULE = 1
-USEDLIBS =
-
-# If we don't need RTTI or EH, there's no reason to export anything
-# from the hello plugin.
-ifneq ($(REQUIRES_RTTI), 1)
-ifneq ($(REQUIRES_EH), 1)
-EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/Hello.exports
-endif
-endif
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/IPO/LowerBitSets.cpp b/gnu/llvm/lib/Transforms/IPO/LowerBitSets.cpp
deleted file mode 100644
index 7b515745c31..00000000000
--- a/gnu/llvm/lib/Transforms/IPO/LowerBitSets.cpp
+++ /dev/null
@@ -1,1055 +0,0 @@
-//===-- LowerBitSets.cpp - Bitset lowering pass ---------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass lowers bitset metadata and calls to the llvm.bitset.test intrinsic.
-// See http://llvm.org/docs/LangRef.html#bitsets for more information.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/LowerBitSets.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/ADT/EquivalenceClasses.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalObject.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "lowerbitsets"
-
-STATISTIC(ByteArraySizeBits, "Byte array size in bits");
-STATISTIC(ByteArraySizeBytes, "Byte array size in bytes");
-STATISTIC(NumByteArraysCreated, "Number of byte arrays created");
-STATISTIC(NumBitSetCallsLowered, "Number of bitset calls lowered");
-STATISTIC(NumBitSetDisjointSets, "Number of disjoint sets of bitsets");
-
-static cl::opt<bool> AvoidReuse(
- "lowerbitsets-avoid-reuse",
- cl::desc("Try to avoid reuse of byte array addresses using aliases"),
- cl::Hidden, cl::init(true));
-
-bool BitSetInfo::containsGlobalOffset(uint64_t Offset) const {
- if (Offset < ByteOffset)
- return false;
-
- if ((Offset - ByteOffset) % (uint64_t(1) << AlignLog2) != 0)
- return false;
-
- uint64_t BitOffset = (Offset - ByteOffset) >> AlignLog2;
- if (BitOffset >= BitSize)
- return false;
-
- return Bits.count(BitOffset);
-}
-
-bool BitSetInfo::containsValue(
- const DataLayout &DL,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout, Value *V,
- uint64_t COffset) const {
- if (auto GV = dyn_cast<GlobalObject>(V)) {
- auto I = GlobalLayout.find(GV);
- if (I == GlobalLayout.end())
- return false;
- return containsGlobalOffset(I->second + COffset);
- }
-
- if (auto GEP = dyn_cast<GEPOperator>(V)) {
- APInt APOffset(DL.getPointerSizeInBits(0), 0);
- bool Result = GEP->accumulateConstantOffset(DL, APOffset);
- if (!Result)
- return false;
- COffset += APOffset.getZExtValue();
- return containsValue(DL, GlobalLayout, GEP->getPointerOperand(),
- COffset);
- }
-
- if (auto Op = dyn_cast<Operator>(V)) {
- if (Op->getOpcode() == Instruction::BitCast)
- return containsValue(DL, GlobalLayout, Op->getOperand(0), COffset);
-
- if (Op->getOpcode() == Instruction::Select)
- return containsValue(DL, GlobalLayout, Op->getOperand(1), COffset) &&
- containsValue(DL, GlobalLayout, Op->getOperand(2), COffset);
- }
-
- return false;
-}
-
-void BitSetInfo::print(raw_ostream &OS) const {
- OS << "offset " << ByteOffset << " size " << BitSize << " align "
- << (1 << AlignLog2);
-
- if (isAllOnes()) {
- OS << " all-ones\n";
- return;
- }
-
- OS << " { ";
- for (uint64_t B : Bits)
- OS << B << ' ';
- OS << "}\n";
-}
-
-BitSetInfo BitSetBuilder::build() {
- if (Min > Max)
- Min = 0;
-
- // Normalize each offset against the minimum observed offset, and compute
- // the bitwise OR of each of the offsets. The number of trailing zeros
- // in the mask gives us the log2 of the alignment of all offsets, which
- // allows us to compress the bitset by only storing one bit per aligned
- // address.
- uint64_t Mask = 0;
- for (uint64_t &Offset : Offsets) {
- Offset -= Min;
- Mask |= Offset;
- }
-
- BitSetInfo BSI;
- BSI.ByteOffset = Min;
-
- BSI.AlignLog2 = 0;
- if (Mask != 0)
- BSI.AlignLog2 = countTrailingZeros(Mask, ZB_Undefined);
-
- // Build the compressed bitset while normalizing the offsets against the
- // computed alignment.
- BSI.BitSize = ((Max - Min) >> BSI.AlignLog2) + 1;
- for (uint64_t Offset : Offsets) {
- Offset >>= BSI.AlignLog2;
- BSI.Bits.insert(Offset);
- }
-
- return BSI;
-}
-
-void GlobalLayoutBuilder::addFragment(const std::set<uint64_t> &F) {
- // Create a new fragment to hold the layout for F.
- Fragments.emplace_back();
- std::vector<uint64_t> &Fragment = Fragments.back();
- uint64_t FragmentIndex = Fragments.size() - 1;
-
- for (auto ObjIndex : F) {
- uint64_t OldFragmentIndex = FragmentMap[ObjIndex];
- if (OldFragmentIndex == 0) {
- // We haven't seen this object index before, so just add it to the current
- // fragment.
- Fragment.push_back(ObjIndex);
- } else {
- // This index belongs to an existing fragment. Copy the elements of the
- // old fragment into this one and clear the old fragment. We don't update
- // the fragment map just yet, this ensures that any further references to
- // indices from the old fragment in this fragment do not insert any more
- // indices.
- std::vector<uint64_t> &OldFragment = Fragments[OldFragmentIndex];
- Fragment.insert(Fragment.end(), OldFragment.begin(), OldFragment.end());
- OldFragment.clear();
- }
- }
-
- // Update the fragment map to point our object indices to this fragment.
- for (uint64_t ObjIndex : Fragment)
- FragmentMap[ObjIndex] = FragmentIndex;
-}
-
-void ByteArrayBuilder::allocate(const std::set<uint64_t> &Bits,
- uint64_t BitSize, uint64_t &AllocByteOffset,
- uint8_t &AllocMask) {
- // Find the smallest current allocation.
- unsigned Bit = 0;
- for (unsigned I = 1; I != BitsPerByte; ++I)
- if (BitAllocs[I] < BitAllocs[Bit])
- Bit = I;
-
- AllocByteOffset = BitAllocs[Bit];
-
- // Add our size to it.
- unsigned ReqSize = AllocByteOffset + BitSize;
- BitAllocs[Bit] = ReqSize;
- if (Bytes.size() < ReqSize)
- Bytes.resize(ReqSize);
-
- // Set our bits.
- AllocMask = 1 << Bit;
- for (uint64_t B : Bits)
- Bytes[AllocByteOffset + B] |= AllocMask;
-}
-
-namespace {
-
-struct ByteArrayInfo {
- std::set<uint64_t> Bits;
- uint64_t BitSize;
- GlobalVariable *ByteArray;
- Constant *Mask;
-};
-
-struct LowerBitSets : public ModulePass {
- static char ID;
- LowerBitSets() : ModulePass(ID) {
- initializeLowerBitSetsPass(*PassRegistry::getPassRegistry());
- }
-
- Module *M;
-
- bool LinkerSubsectionsViaSymbols;
- Triple::ArchType Arch;
- Triple::ObjectFormatType ObjectFormat;
- IntegerType *Int1Ty;
- IntegerType *Int8Ty;
- IntegerType *Int32Ty;
- Type *Int32PtrTy;
- IntegerType *Int64Ty;
- IntegerType *IntPtrTy;
-
- // The llvm.bitsets named metadata.
- NamedMDNode *BitSetNM;
-
- // Mapping from bitset identifiers to the call sites that test them.
- DenseMap<Metadata *, std::vector<CallInst *>> BitSetTestCallSites;
-
- std::vector<ByteArrayInfo> ByteArrayInfos;
-
- BitSetInfo
- buildBitSet(Metadata *BitSet,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout);
- ByteArrayInfo *createByteArray(BitSetInfo &BSI);
- void allocateByteArrays();
- Value *createBitSetTest(IRBuilder<> &B, BitSetInfo &BSI, ByteArrayInfo *&BAI,
- Value *BitOffset);
- void lowerBitSetCalls(ArrayRef<Metadata *> BitSets,
- Constant *CombinedGlobalAddr,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout);
- Value *
- lowerBitSetCall(CallInst *CI, BitSetInfo &BSI, ByteArrayInfo *&BAI,
- Constant *CombinedGlobal,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout);
- void buildBitSetsFromGlobalVariables(ArrayRef<Metadata *> BitSets,
- ArrayRef<GlobalVariable *> Globals);
- unsigned getJumpTableEntrySize();
- Type *getJumpTableEntryType();
- Constant *createJumpTableEntry(GlobalObject *Src, Function *Dest,
- unsigned Distance);
- void verifyBitSetMDNode(MDNode *Op);
- void buildBitSetsFromFunctions(ArrayRef<Metadata *> BitSets,
- ArrayRef<Function *> Functions);
- void buildBitSetsFromDisjointSet(ArrayRef<Metadata *> BitSets,
- ArrayRef<GlobalObject *> Globals);
- bool buildBitSets();
- bool eraseBitSetMetadata();
-
- bool doInitialization(Module &M) override;
- bool runOnModule(Module &M) override;
-};
-
-} // anonymous namespace
-
-INITIALIZE_PASS_BEGIN(LowerBitSets, "lowerbitsets",
- "Lower bitset metadata", false, false)
-INITIALIZE_PASS_END(LowerBitSets, "lowerbitsets",
- "Lower bitset metadata", false, false)
-char LowerBitSets::ID = 0;
-
-ModulePass *llvm::createLowerBitSetsPass() { return new LowerBitSets; }
-
-bool LowerBitSets::doInitialization(Module &Mod) {
- M = &Mod;
- const DataLayout &DL = Mod.getDataLayout();
-
- Triple TargetTriple(M->getTargetTriple());
- LinkerSubsectionsViaSymbols = TargetTriple.isMacOSX();
- Arch = TargetTriple.getArch();
- ObjectFormat = TargetTriple.getObjectFormat();
-
- Int1Ty = Type::getInt1Ty(M->getContext());
- Int8Ty = Type::getInt8Ty(M->getContext());
- Int32Ty = Type::getInt32Ty(M->getContext());
- Int32PtrTy = PointerType::getUnqual(Int32Ty);
- Int64Ty = Type::getInt64Ty(M->getContext());
- IntPtrTy = DL.getIntPtrType(M->getContext(), 0);
-
- BitSetNM = M->getNamedMetadata("llvm.bitsets");
-
- BitSetTestCallSites.clear();
-
- return false;
-}
-
-/// Build a bit set for BitSet using the object layouts in
-/// GlobalLayout.
-BitSetInfo LowerBitSets::buildBitSet(
- Metadata *BitSet,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout) {
- BitSetBuilder BSB;
-
- // Compute the byte offset of each element of this bitset.
- if (BitSetNM) {
- for (MDNode *Op : BitSetNM->operands()) {
- if (Op->getOperand(0) != BitSet || !Op->getOperand(1))
- continue;
- Constant *OpConst =
- cast<ConstantAsMetadata>(Op->getOperand(1))->getValue();
- if (auto GA = dyn_cast<GlobalAlias>(OpConst))
- OpConst = GA->getAliasee();
- auto OpGlobal = dyn_cast<GlobalObject>(OpConst);
- if (!OpGlobal)
- continue;
- uint64_t Offset =
- cast<ConstantInt>(cast<ConstantAsMetadata>(Op->getOperand(2))
- ->getValue())->getZExtValue();
-
- Offset += GlobalLayout.find(OpGlobal)->second;
-
- BSB.addOffset(Offset);
- }
- }
-
- return BSB.build();
-}
-
-/// Build a test that bit BitOffset mod sizeof(Bits)*8 is set in
-/// Bits. This pattern matches to the bt instruction on x86.
-static Value *createMaskedBitTest(IRBuilder<> &B, Value *Bits,
- Value *BitOffset) {
- auto BitsType = cast<IntegerType>(Bits->getType());
- unsigned BitWidth = BitsType->getBitWidth();
-
- BitOffset = B.CreateZExtOrTrunc(BitOffset, BitsType);
- Value *BitIndex =
- B.CreateAnd(BitOffset, ConstantInt::get(BitsType, BitWidth - 1));
- Value *BitMask = B.CreateShl(ConstantInt::get(BitsType, 1), BitIndex);
- Value *MaskedBits = B.CreateAnd(Bits, BitMask);
- return B.CreateICmpNE(MaskedBits, ConstantInt::get(BitsType, 0));
-}
-
-ByteArrayInfo *LowerBitSets::createByteArray(BitSetInfo &BSI) {
- // Create globals to stand in for byte arrays and masks. These never actually
- // get initialized, we RAUW and erase them later in allocateByteArrays() once
- // we know the offset and mask to use.
- auto ByteArrayGlobal = new GlobalVariable(
- *M, Int8Ty, /*isConstant=*/true, GlobalValue::PrivateLinkage, nullptr);
- auto MaskGlobal = new GlobalVariable(
- *M, Int8Ty, /*isConstant=*/true, GlobalValue::PrivateLinkage, nullptr);
-
- ByteArrayInfos.emplace_back();
- ByteArrayInfo *BAI = &ByteArrayInfos.back();
-
- BAI->Bits = BSI.Bits;
- BAI->BitSize = BSI.BitSize;
- BAI->ByteArray = ByteArrayGlobal;
- BAI->Mask = ConstantExpr::getPtrToInt(MaskGlobal, Int8Ty);
- return BAI;
-}
-
-void LowerBitSets::allocateByteArrays() {
- std::stable_sort(ByteArrayInfos.begin(), ByteArrayInfos.end(),
- [](const ByteArrayInfo &BAI1, const ByteArrayInfo &BAI2) {
- return BAI1.BitSize > BAI2.BitSize;
- });
-
- std::vector<uint64_t> ByteArrayOffsets(ByteArrayInfos.size());
-
- ByteArrayBuilder BAB;
- for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
- ByteArrayInfo *BAI = &ByteArrayInfos[I];
-
- uint8_t Mask;
- BAB.allocate(BAI->Bits, BAI->BitSize, ByteArrayOffsets[I], Mask);
-
- BAI->Mask->replaceAllUsesWith(ConstantInt::get(Int8Ty, Mask));
- cast<GlobalVariable>(BAI->Mask->getOperand(0))->eraseFromParent();
- }
-
- Constant *ByteArrayConst = ConstantDataArray::get(M->getContext(), BAB.Bytes);
- auto ByteArray =
- new GlobalVariable(*M, ByteArrayConst->getType(), /*isConstant=*/true,
- GlobalValue::PrivateLinkage, ByteArrayConst);
-
- for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
- ByteArrayInfo *BAI = &ByteArrayInfos[I];
-
- Constant *Idxs[] = {ConstantInt::get(IntPtrTy, 0),
- ConstantInt::get(IntPtrTy, ByteArrayOffsets[I])};
- Constant *GEP = ConstantExpr::getInBoundsGetElementPtr(
- ByteArrayConst->getType(), ByteArray, Idxs);
-
- // Create an alias instead of RAUW'ing the gep directly. On x86 this ensures
- // that the pc-relative displacement is folded into the lea instead of the
- // test instruction getting another displacement.
- if (LinkerSubsectionsViaSymbols) {
- BAI->ByteArray->replaceAllUsesWith(GEP);
- } else {
- GlobalAlias *Alias = GlobalAlias::create(
- Int8Ty, 0, GlobalValue::PrivateLinkage, "bits", GEP, M);
- BAI->ByteArray->replaceAllUsesWith(Alias);
- }
- BAI->ByteArray->eraseFromParent();
- }
-
- ByteArraySizeBits = BAB.BitAllocs[0] + BAB.BitAllocs[1] + BAB.BitAllocs[2] +
- BAB.BitAllocs[3] + BAB.BitAllocs[4] + BAB.BitAllocs[5] +
- BAB.BitAllocs[6] + BAB.BitAllocs[7];
- ByteArraySizeBytes = BAB.Bytes.size();
-}
-
-/// Build a test that bit BitOffset is set in BSI, where
-/// BitSetGlobal is a global containing the bits in BSI.
-Value *LowerBitSets::createBitSetTest(IRBuilder<> &B, BitSetInfo &BSI,
- ByteArrayInfo *&BAI, Value *BitOffset) {
- if (BSI.BitSize <= 64) {
- // If the bit set is sufficiently small, we can avoid a load by bit testing
- // a constant.
- IntegerType *BitsTy;
- if (BSI.BitSize <= 32)
- BitsTy = Int32Ty;
- else
- BitsTy = Int64Ty;
-
- uint64_t Bits = 0;
- for (auto Bit : BSI.Bits)
- Bits |= uint64_t(1) << Bit;
- Constant *BitsConst = ConstantInt::get(BitsTy, Bits);
- return createMaskedBitTest(B, BitsConst, BitOffset);
- } else {
- if (!BAI) {
- ++NumByteArraysCreated;
- BAI = createByteArray(BSI);
- }
-
- Constant *ByteArray = BAI->ByteArray;
- Type *Ty = BAI->ByteArray->getValueType();
- if (!LinkerSubsectionsViaSymbols && AvoidReuse) {
- // Each use of the byte array uses a different alias. This makes the
- // backend less likely to reuse previously computed byte array addresses,
- // improving the security of the CFI mechanism based on this pass.
- ByteArray = GlobalAlias::create(BAI->ByteArray->getValueType(), 0,
- GlobalValue::PrivateLinkage, "bits_use",
- ByteArray, M);
- }
-
- Value *ByteAddr = B.CreateGEP(Ty, ByteArray, BitOffset);
- Value *Byte = B.CreateLoad(ByteAddr);
-
- Value *ByteAndMask = B.CreateAnd(Byte, BAI->Mask);
- return B.CreateICmpNE(ByteAndMask, ConstantInt::get(Int8Ty, 0));
- }
-}
-
-/// Lower a llvm.bitset.test call to its implementation. Returns the value to
-/// replace the call with.
-Value *LowerBitSets::lowerBitSetCall(
- CallInst *CI, BitSetInfo &BSI, ByteArrayInfo *&BAI,
- Constant *CombinedGlobalIntAddr,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout) {
- Value *Ptr = CI->getArgOperand(0);
- const DataLayout &DL = M->getDataLayout();
-
- if (BSI.containsValue(DL, GlobalLayout, Ptr))
- return ConstantInt::getTrue(M->getContext());
-
- Constant *OffsetedGlobalAsInt = ConstantExpr::getAdd(
- CombinedGlobalIntAddr, ConstantInt::get(IntPtrTy, BSI.ByteOffset));
-
- BasicBlock *InitialBB = CI->getParent();
-
- IRBuilder<> B(CI);
-
- Value *PtrAsInt = B.CreatePtrToInt(Ptr, IntPtrTy);
-
- if (BSI.isSingleOffset())
- return B.CreateICmpEQ(PtrAsInt, OffsetedGlobalAsInt);
-
- Value *PtrOffset = B.CreateSub(PtrAsInt, OffsetedGlobalAsInt);
-
- Value *BitOffset;
- if (BSI.AlignLog2 == 0) {
- BitOffset = PtrOffset;
- } else {
- // We need to check that the offset both falls within our range and is
- // suitably aligned. We can check both properties at the same time by
- // performing a right rotate by log2(alignment) followed by an integer
- // comparison against the bitset size. The rotate will move the lower
- // order bits that need to be zero into the higher order bits of the
- // result, causing the comparison to fail if they are nonzero. The rotate
- // also conveniently gives us a bit offset to use during the load from
- // the bitset.
- Value *OffsetSHR =
- B.CreateLShr(PtrOffset, ConstantInt::get(IntPtrTy, BSI.AlignLog2));
- Value *OffsetSHL = B.CreateShl(
- PtrOffset,
- ConstantInt::get(IntPtrTy, DL.getPointerSizeInBits(0) - BSI.AlignLog2));
- BitOffset = B.CreateOr(OffsetSHR, OffsetSHL);
- }
-
- Constant *BitSizeConst = ConstantInt::get(IntPtrTy, BSI.BitSize);
- Value *OffsetInRange = B.CreateICmpULT(BitOffset, BitSizeConst);
-
- // If the bit set is all ones, testing against it is unnecessary.
- if (BSI.isAllOnes())
- return OffsetInRange;
-
- TerminatorInst *Term = SplitBlockAndInsertIfThen(OffsetInRange, CI, false);
- IRBuilder<> ThenB(Term);
-
- // Now that we know that the offset is in range and aligned, load the
- // appropriate bit from the bitset.
- Value *Bit = createBitSetTest(ThenB, BSI, BAI, BitOffset);
-
- // The value we want is 0 if we came directly from the initial block
- // (having failed the range or alignment checks), or the loaded bit if
- // we came from the block in which we loaded it.
- B.SetInsertPoint(CI);
- PHINode *P = B.CreatePHI(Int1Ty, 2);
- P->addIncoming(ConstantInt::get(Int1Ty, 0), InitialBB);
- P->addIncoming(Bit, ThenB.GetInsertBlock());
- return P;
-}
-
-/// Given a disjoint set of bitsets and globals, layout the globals, build the
-/// bit sets and lower the llvm.bitset.test calls.
-void LowerBitSets::buildBitSetsFromGlobalVariables(
- ArrayRef<Metadata *> BitSets, ArrayRef<GlobalVariable *> Globals) {
- // Build a new global with the combined contents of the referenced globals.
- // This global is a struct whose even-indexed elements contain the original
- // contents of the referenced globals and whose odd-indexed elements contain
- // any padding required to align the next element to the next power of 2.
- std::vector<Constant *> GlobalInits;
- const DataLayout &DL = M->getDataLayout();
- for (GlobalVariable *G : Globals) {
- GlobalInits.push_back(G->getInitializer());
- uint64_t InitSize = DL.getTypeAllocSize(G->getValueType());
-
- // Compute the amount of padding required.
- uint64_t Padding = NextPowerOf2(InitSize - 1) - InitSize;
-
- // Cap at 128 was found experimentally to have a good data/instruction
- // overhead tradeoff.
- if (Padding > 128)
- Padding = RoundUpToAlignment(InitSize, 128) - InitSize;
-
- GlobalInits.push_back(
- ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
- }
- if (!GlobalInits.empty())
- GlobalInits.pop_back();
- Constant *NewInit = ConstantStruct::getAnon(M->getContext(), GlobalInits);
- auto *CombinedGlobal =
- new GlobalVariable(*M, NewInit->getType(), /*isConstant=*/true,
- GlobalValue::PrivateLinkage, NewInit);
-
- StructType *NewTy = cast<StructType>(NewInit->getType());
- const StructLayout *CombinedGlobalLayout = DL.getStructLayout(NewTy);
-
- // Compute the offsets of the original globals within the new global.
- DenseMap<GlobalObject *, uint64_t> GlobalLayout;
- for (unsigned I = 0; I != Globals.size(); ++I)
- // Multiply by 2 to account for padding elements.
- GlobalLayout[Globals[I]] = CombinedGlobalLayout->getElementOffset(I * 2);
-
- lowerBitSetCalls(BitSets, CombinedGlobal, GlobalLayout);
-
- // Build aliases pointing to offsets into the combined global for each
- // global from which we built the combined global, and replace references
- // to the original globals with references to the aliases.
- for (unsigned I = 0; I != Globals.size(); ++I) {
- // Multiply by 2 to account for padding elements.
- Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
- ConstantInt::get(Int32Ty, I * 2)};
- Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
- NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs);
- if (LinkerSubsectionsViaSymbols) {
- Globals[I]->replaceAllUsesWith(CombinedGlobalElemPtr);
- } else {
- assert(Globals[I]->getType()->getAddressSpace() == 0);
- GlobalAlias *GAlias = GlobalAlias::create(NewTy->getElementType(I * 2), 0,
- Globals[I]->getLinkage(), "",
- CombinedGlobalElemPtr, M);
- GAlias->setVisibility(Globals[I]->getVisibility());
- GAlias->takeName(Globals[I]);
- Globals[I]->replaceAllUsesWith(GAlias);
- }
- Globals[I]->eraseFromParent();
- }
-}
-
-void LowerBitSets::lowerBitSetCalls(
- ArrayRef<Metadata *> BitSets, Constant *CombinedGlobalAddr,
- const DenseMap<GlobalObject *, uint64_t> &GlobalLayout) {
- Constant *CombinedGlobalIntAddr =
- ConstantExpr::getPtrToInt(CombinedGlobalAddr, IntPtrTy);
-
- // For each bitset in this disjoint set...
- for (Metadata *BS : BitSets) {
- // Build the bitset.
- BitSetInfo BSI = buildBitSet(BS, GlobalLayout);
- DEBUG({
- if (auto BSS = dyn_cast<MDString>(BS))
- dbgs() << BSS->getString() << ": ";
- else
- dbgs() << "<unnamed>: ";
- BSI.print(dbgs());
- });
-
- ByteArrayInfo *BAI = nullptr;
-
- // Lower each call to llvm.bitset.test for this bitset.
- for (CallInst *CI : BitSetTestCallSites[BS]) {
- ++NumBitSetCallsLowered;
- Value *Lowered =
- lowerBitSetCall(CI, BSI, BAI, CombinedGlobalIntAddr, GlobalLayout);
- CI->replaceAllUsesWith(Lowered);
- CI->eraseFromParent();
- }
- }
-}
-
-void LowerBitSets::verifyBitSetMDNode(MDNode *Op) {
- if (Op->getNumOperands() != 3)
- report_fatal_error(
- "All operands of llvm.bitsets metadata must have 3 elements");
- if (!Op->getOperand(1))
- return;
-
- auto OpConstMD = dyn_cast<ConstantAsMetadata>(Op->getOperand(1));
- if (!OpConstMD)
- report_fatal_error("Bit set element must be a constant");
- auto OpGlobal = dyn_cast<GlobalObject>(OpConstMD->getValue());
- if (!OpGlobal)
- return;
-
- if (OpGlobal->isThreadLocal())
- report_fatal_error("Bit set element may not be thread-local");
- if (OpGlobal->hasSection())
- report_fatal_error("Bit set element may not have an explicit section");
-
- if (isa<GlobalVariable>(OpGlobal) && OpGlobal->isDeclarationForLinker())
- report_fatal_error("Bit set global var element must be a definition");
-
- auto OffsetConstMD = dyn_cast<ConstantAsMetadata>(Op->getOperand(2));
- if (!OffsetConstMD)
- report_fatal_error("Bit set element offset must be a constant");
- auto OffsetInt = dyn_cast<ConstantInt>(OffsetConstMD->getValue());
- if (!OffsetInt)
- report_fatal_error("Bit set element offset must be an integer constant");
-}
-
-static const unsigned kX86JumpTableEntrySize = 8;
-
-unsigned LowerBitSets::getJumpTableEntrySize() {
- if (Arch != Triple::x86 && Arch != Triple::x86_64)
- report_fatal_error("Unsupported architecture for jump tables");
-
- return kX86JumpTableEntrySize;
-}
-
-// Create a constant representing a jump table entry for the target. This
-// consists of an instruction sequence containing a relative branch to Dest. The
-// constant will be laid out at address Src+(Len*Distance) where Len is the
-// target-specific jump table entry size.
-Constant *LowerBitSets::createJumpTableEntry(GlobalObject *Src, Function *Dest,
- unsigned Distance) {
- if (Arch != Triple::x86 && Arch != Triple::x86_64)
- report_fatal_error("Unsupported architecture for jump tables");
-
- const unsigned kJmpPCRel32Code = 0xe9;
- const unsigned kInt3Code = 0xcc;
-
- ConstantInt *Jmp = ConstantInt::get(Int8Ty, kJmpPCRel32Code);
-
- // Build a constant representing the displacement between the constant's
- // address and Dest. This will resolve to a PC32 relocation referring to Dest.
- Constant *DestInt = ConstantExpr::getPtrToInt(Dest, IntPtrTy);
- Constant *SrcInt = ConstantExpr::getPtrToInt(Src, IntPtrTy);
- Constant *Disp = ConstantExpr::getSub(DestInt, SrcInt);
- ConstantInt *DispOffset =
- ConstantInt::get(IntPtrTy, Distance * kX86JumpTableEntrySize + 5);
- Constant *OffsetedDisp = ConstantExpr::getSub(Disp, DispOffset);
- OffsetedDisp = ConstantExpr::getTruncOrBitCast(OffsetedDisp, Int32Ty);
-
- ConstantInt *Int3 = ConstantInt::get(Int8Ty, kInt3Code);
-
- Constant *Fields[] = {
- Jmp, OffsetedDisp, Int3, Int3, Int3,
- };
- return ConstantStruct::getAnon(Fields, /*Packed=*/true);
-}
-
-Type *LowerBitSets::getJumpTableEntryType() {
- if (Arch != Triple::x86 && Arch != Triple::x86_64)
- report_fatal_error("Unsupported architecture for jump tables");
-
- return StructType::get(M->getContext(),
- {Int8Ty, Int32Ty, Int8Ty, Int8Ty, Int8Ty},
- /*Packed=*/true);
-}
-
-/// Given a disjoint set of bitsets and functions, build a jump table for the
-/// functions, build the bit sets and lower the llvm.bitset.test calls.
-void LowerBitSets::buildBitSetsFromFunctions(ArrayRef<Metadata *> BitSets,
- ArrayRef<Function *> Functions) {
- // Unlike the global bitset builder, the function bitset builder cannot
- // re-arrange functions in a particular order and base its calculations on the
- // layout of the functions' entry points, as we have no idea how large a
- // particular function will end up being (the size could even depend on what
- // this pass does!) Instead, we build a jump table, which is a block of code
- // consisting of one branch instruction for each of the functions in the bit
- // set that branches to the target function, and redirect any taken function
- // addresses to the corresponding jump table entry. In the object file's
- // symbol table, the symbols for the target functions also refer to the jump
- // table entries, so that addresses taken outside the module will pass any
- // verification done inside the module.
- //
- // In more concrete terms, suppose we have three functions f, g, h which are
- // members of a single bitset, and a function foo that returns their
- // addresses:
- //
- // f:
- // mov 0, %eax
- // ret
- //
- // g:
- // mov 1, %eax
- // ret
- //
- // h:
- // mov 2, %eax
- // ret
- //
- // foo:
- // mov f, %eax
- // mov g, %edx
- // mov h, %ecx
- // ret
- //
- // To create a jump table for these functions, we instruct the LLVM code
- // generator to output a jump table in the .text section. This is done by
- // representing the instructions in the jump table as an LLVM constant and
- // placing them in a global variable in the .text section. The end result will
- // (conceptually) look like this:
- //
- // f:
- // jmp .Ltmp0 ; 5 bytes
- // int3 ; 1 byte
- // int3 ; 1 byte
- // int3 ; 1 byte
- //
- // g:
- // jmp .Ltmp1 ; 5 bytes
- // int3 ; 1 byte
- // int3 ; 1 byte
- // int3 ; 1 byte
- //
- // h:
- // jmp .Ltmp2 ; 5 bytes
- // int3 ; 1 byte
- // int3 ; 1 byte
- // int3 ; 1 byte
- //
- // .Ltmp0:
- // mov 0, %eax
- // ret
- //
- // .Ltmp1:
- // mov 1, %eax
- // ret
- //
- // .Ltmp2:
- // mov 2, %eax
- // ret
- //
- // foo:
- // mov f, %eax
- // mov g, %edx
- // mov h, %ecx
- // ret
- //
- // Because the addresses of f, g, h are evenly spaced at a power of 2, in the
- // normal case the check can be carried out using the same kind of simple
- // arithmetic that we normally use for globals.
-
- assert(!Functions.empty());
-
- // Build a simple layout based on the regular layout of jump tables.
- DenseMap<GlobalObject *, uint64_t> GlobalLayout;
- unsigned EntrySize = getJumpTableEntrySize();
- for (unsigned I = 0; I != Functions.size(); ++I)
- GlobalLayout[Functions[I]] = I * EntrySize;
-
- // Create a constant to hold the jump table.
- ArrayType *JumpTableType =
- ArrayType::get(getJumpTableEntryType(), Functions.size());
- auto JumpTable = new GlobalVariable(*M, JumpTableType,
- /*isConstant=*/true,
- GlobalValue::PrivateLinkage, nullptr);
- JumpTable->setSection(ObjectFormat == Triple::MachO
- ? "__TEXT,__text,regular,pure_instructions"
- : ".text");
- lowerBitSetCalls(BitSets, JumpTable, GlobalLayout);
-
- // Build aliases pointing to offsets into the jump table, and replace
- // references to the original functions with references to the aliases.
- for (unsigned I = 0; I != Functions.size(); ++I) {
- Constant *CombinedGlobalElemPtr = ConstantExpr::getBitCast(
- ConstantExpr::getGetElementPtr(
- JumpTableType, JumpTable,
- ArrayRef<Constant *>{ConstantInt::get(IntPtrTy, 0),
- ConstantInt::get(IntPtrTy, I)}),
- Functions[I]->getType());
- if (LinkerSubsectionsViaSymbols || Functions[I]->isDeclarationForLinker()) {
- Functions[I]->replaceAllUsesWith(CombinedGlobalElemPtr);
- } else {
- assert(Functions[I]->getType()->getAddressSpace() == 0);
- GlobalAlias *GAlias = GlobalAlias::create(Functions[I]->getValueType(), 0,
- Functions[I]->getLinkage(), "",
- CombinedGlobalElemPtr, M);
- GAlias->setVisibility(Functions[I]->getVisibility());
- GAlias->takeName(Functions[I]);
- Functions[I]->replaceAllUsesWith(GAlias);
- }
- if (!Functions[I]->isDeclarationForLinker())
- Functions[I]->setLinkage(GlobalValue::PrivateLinkage);
- }
-
- // Build and set the jump table's initializer.
- std::vector<Constant *> JumpTableEntries;
- for (unsigned I = 0; I != Functions.size(); ++I)
- JumpTableEntries.push_back(
- createJumpTableEntry(JumpTable, Functions[I], I));
- JumpTable->setInitializer(
- ConstantArray::get(JumpTableType, JumpTableEntries));
-}
-
-void LowerBitSets::buildBitSetsFromDisjointSet(
- ArrayRef<Metadata *> BitSets, ArrayRef<GlobalObject *> Globals) {
- llvm::DenseMap<Metadata *, uint64_t> BitSetIndices;
- llvm::DenseMap<GlobalObject *, uint64_t> GlobalIndices;
- for (unsigned I = 0; I != BitSets.size(); ++I)
- BitSetIndices[BitSets[I]] = I;
- for (unsigned I = 0; I != Globals.size(); ++I)
- GlobalIndices[Globals[I]] = I;
-
- // For each bitset, build a set of indices that refer to globals referenced by
- // the bitset.
- std::vector<std::set<uint64_t>> BitSetMembers(BitSets.size());
- if (BitSetNM) {
- for (MDNode *Op : BitSetNM->operands()) {
- // Op = { bitset name, global, offset }
- if (!Op->getOperand(1))
- continue;
- auto I = BitSetIndices.find(Op->getOperand(0));
- if (I == BitSetIndices.end())
- continue;
-
- auto OpGlobal = dyn_cast<GlobalObject>(
- cast<ConstantAsMetadata>(Op->getOperand(1))->getValue());
- if (!OpGlobal)
- continue;
- BitSetMembers[I->second].insert(GlobalIndices[OpGlobal]);
- }
- }
-
- // Order the sets of indices by size. The GlobalLayoutBuilder works best
- // when given small index sets first.
- std::stable_sort(
- BitSetMembers.begin(), BitSetMembers.end(),
- [](const std::set<uint64_t> &O1, const std::set<uint64_t> &O2) {
- return O1.size() < O2.size();
- });
-
- // Create a GlobalLayoutBuilder and provide it with index sets as layout
- // fragments. The GlobalLayoutBuilder tries to lay out members of fragments as
- // close together as possible.
- GlobalLayoutBuilder GLB(Globals.size());
- for (auto &&MemSet : BitSetMembers)
- GLB.addFragment(MemSet);
-
- // Build the bitsets from this disjoint set.
- if (Globals.empty() || isa<GlobalVariable>(Globals[0])) {
- // Build a vector of global variables with the computed layout.
- std::vector<GlobalVariable *> OrderedGVs(Globals.size());
- auto OGI = OrderedGVs.begin();
- for (auto &&F : GLB.Fragments) {
- for (auto &&Offset : F) {
- auto GV = dyn_cast<GlobalVariable>(Globals[Offset]);
- if (!GV)
- report_fatal_error(
- "Bit set may not contain both global variables and functions");
- *OGI++ = GV;
- }
- }
-
- buildBitSetsFromGlobalVariables(BitSets, OrderedGVs);
- } else {
- // Build a vector of functions with the computed layout.
- std::vector<Function *> OrderedFns(Globals.size());
- auto OFI = OrderedFns.begin();
- for (auto &&F : GLB.Fragments) {
- for (auto &&Offset : F) {
- auto Fn = dyn_cast<Function>(Globals[Offset]);
- if (!Fn)
- report_fatal_error(
- "Bit set may not contain both global variables and functions");
- *OFI++ = Fn;
- }
- }
-
- buildBitSetsFromFunctions(BitSets, OrderedFns);
- }
-}
-
-/// Lower all bit sets in this module.
-bool LowerBitSets::buildBitSets() {
- Function *BitSetTestFunc =
- M->getFunction(Intrinsic::getName(Intrinsic::bitset_test));
- if (!BitSetTestFunc)
- return false;
-
- // Equivalence class set containing bitsets and the globals they reference.
- // This is used to partition the set of bitsets in the module into disjoint
- // sets.
- typedef EquivalenceClasses<PointerUnion<GlobalObject *, Metadata *>>
- GlobalClassesTy;
- GlobalClassesTy GlobalClasses;
-
- // Verify the bitset metadata and build a mapping from bitset identifiers to
- // their last observed index in BitSetNM. This will used later to
- // deterministically order the list of bitset identifiers.
- llvm::DenseMap<Metadata *, unsigned> BitSetIdIndices;
- if (BitSetNM) {
- for (unsigned I = 0, E = BitSetNM->getNumOperands(); I != E; ++I) {
- MDNode *Op = BitSetNM->getOperand(I);
- verifyBitSetMDNode(Op);
- BitSetIdIndices[Op->getOperand(0)] = I;
- }
- }
-
- for (const Use &U : BitSetTestFunc->uses()) {
- auto CI = cast<CallInst>(U.getUser());
-
- auto BitSetMDVal = dyn_cast<MetadataAsValue>(CI->getArgOperand(1));
- if (!BitSetMDVal)
- report_fatal_error(
- "Second argument of llvm.bitset.test must be metadata");
- auto BitSet = BitSetMDVal->getMetadata();
-
- // Add the call site to the list of call sites for this bit set. We also use
- // BitSetTestCallSites to keep track of whether we have seen this bit set
- // before. If we have, we don't need to re-add the referenced globals to the
- // equivalence class.
- std::pair<DenseMap<Metadata *, std::vector<CallInst *>>::iterator,
- bool> Ins =
- BitSetTestCallSites.insert(
- std::make_pair(BitSet, std::vector<CallInst *>()));
- Ins.first->second.push_back(CI);
- if (!Ins.second)
- continue;
-
- // Add the bitset to the equivalence class.
- GlobalClassesTy::iterator GCI = GlobalClasses.insert(BitSet);
- GlobalClassesTy::member_iterator CurSet = GlobalClasses.findLeader(GCI);
-
- if (!BitSetNM)
- continue;
-
- // Add the referenced globals to the bitset's equivalence class.
- for (MDNode *Op : BitSetNM->operands()) {
- if (Op->getOperand(0) != BitSet || !Op->getOperand(1))
- continue;
-
- auto OpGlobal = dyn_cast<GlobalObject>(
- cast<ConstantAsMetadata>(Op->getOperand(1))->getValue());
- if (!OpGlobal)
- continue;
-
- CurSet = GlobalClasses.unionSets(
- CurSet, GlobalClasses.findLeader(GlobalClasses.insert(OpGlobal)));
- }
- }
-
- if (GlobalClasses.empty())
- return false;
-
- // Build a list of disjoint sets ordered by their maximum BitSetNM index
- // for determinism.
- std::vector<std::pair<GlobalClassesTy::iterator, unsigned>> Sets;
- for (GlobalClassesTy::iterator I = GlobalClasses.begin(),
- E = GlobalClasses.end();
- I != E; ++I) {
- if (!I->isLeader()) continue;
- ++NumBitSetDisjointSets;
-
- unsigned MaxIndex = 0;
- for (GlobalClassesTy::member_iterator MI = GlobalClasses.member_begin(I);
- MI != GlobalClasses.member_end(); ++MI) {
- if ((*MI).is<Metadata *>())
- MaxIndex = std::max(MaxIndex, BitSetIdIndices[MI->get<Metadata *>()]);
- }
- Sets.emplace_back(I, MaxIndex);
- }
- std::sort(Sets.begin(), Sets.end(),
- [](const std::pair<GlobalClassesTy::iterator, unsigned> &S1,
- const std::pair<GlobalClassesTy::iterator, unsigned> &S2) {
- return S1.second < S2.second;
- });
-
- // For each disjoint set we found...
- for (const auto &S : Sets) {
- // Build the list of bitsets in this disjoint set.
- std::vector<Metadata *> BitSets;
- std::vector<GlobalObject *> Globals;
- for (GlobalClassesTy::member_iterator MI =
- GlobalClasses.member_begin(S.first);
- MI != GlobalClasses.member_end(); ++MI) {
- if ((*MI).is<Metadata *>())
- BitSets.push_back(MI->get<Metadata *>());
- else
- Globals.push_back(MI->get<GlobalObject *>());
- }
-
- // Order bitsets by BitSetNM index for determinism. This ordering is stable
- // as there is a one-to-one mapping between metadata and indices.
- std::sort(BitSets.begin(), BitSets.end(), [&](Metadata *M1, Metadata *M2) {
- return BitSetIdIndices[M1] < BitSetIdIndices[M2];
- });
-
- // Lower the bitsets in this disjoint set.
- buildBitSetsFromDisjointSet(BitSets, Globals);
- }
-
- allocateByteArrays();
-
- return true;
-}
-
-bool LowerBitSets::eraseBitSetMetadata() {
- if (!BitSetNM)
- return false;
-
- M->eraseNamedMetadata(BitSetNM);
- return true;
-}
-
-bool LowerBitSets::runOnModule(Module &M) {
- bool Changed = buildBitSets();
- Changed |= eraseBitSetMetadata();
- return Changed;
-}
diff --git a/gnu/llvm/lib/Transforms/IPO/Makefile b/gnu/llvm/lib/Transforms/IPO/Makefile
deleted file mode 100644
index 5c42374139a..00000000000
--- a/gnu/llvm/lib/Transforms/IPO/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/IPO/Makefile -------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMipo
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/InstCombine/Makefile b/gnu/llvm/lib/Transforms/InstCombine/Makefile
deleted file mode 100644
index 0c488e78b6d..00000000000
--- a/gnu/llvm/lib/Transforms/InstCombine/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/InstCombine/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMInstCombine
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/Instrumentation/Makefile b/gnu/llvm/lib/Transforms/Instrumentation/Makefile
deleted file mode 100644
index 6cbc7a9cd88..00000000000
--- a/gnu/llvm/lib/Transforms/Instrumentation/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/Instrumentation/Makefile -------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMInstrumentation
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/Instrumentation/SafeStack.cpp b/gnu/llvm/lib/Transforms/Instrumentation/SafeStack.cpp
deleted file mode 100644
index abed465f102..00000000000
--- a/gnu/llvm/lib/Transforms/Instrumentation/SafeStack.cpp
+++ /dev/null
@@ -1,760 +0,0 @@
-//===-- SafeStack.cpp - Safe Stack Insertion ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass splits the stack into the safe stack (kept as-is for LLVM backend)
-// and the unsafe stack (explicitly allocated and managed through the runtime
-// support library).
-//
-// http://clang.llvm.org/docs/SafeStack.html
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
-#include "llvm/CodeGen/Passes.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/InstIterator.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_os_ostream.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/ModuleUtils.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "safestack"
-
-enum UnsafeStackPtrStorageVal { ThreadLocalUSP, SingleThreadUSP };
-
-static cl::opt<UnsafeStackPtrStorageVal> USPStorage("safe-stack-usp-storage",
- cl::Hidden, cl::init(ThreadLocalUSP),
- cl::desc("Type of storage for the unsafe stack pointer"),
- cl::values(clEnumValN(ThreadLocalUSP, "thread-local",
- "Thread-local storage"),
- clEnumValN(SingleThreadUSP, "single-thread",
- "Non-thread-local storage"),
- clEnumValEnd));
-
-namespace llvm {
-
-STATISTIC(NumFunctions, "Total number of functions");
-STATISTIC(NumUnsafeStackFunctions, "Number of functions with unsafe stack");
-STATISTIC(NumUnsafeStackRestorePointsFunctions,
- "Number of functions that use setjmp or exceptions");
-
-STATISTIC(NumAllocas, "Total number of allocas");
-STATISTIC(NumUnsafeStaticAllocas, "Number of unsafe static allocas");
-STATISTIC(NumUnsafeDynamicAllocas, "Number of unsafe dynamic allocas");
-STATISTIC(NumUnsafeByValArguments, "Number of unsafe byval arguments");
-STATISTIC(NumUnsafeStackRestorePoints, "Number of setjmps and landingpads");
-
-} // namespace llvm
-
-namespace {
-
-/// Rewrite an SCEV expression for a memory access address to an expression that
-/// represents offset from the given alloca.
-///
-/// The implementation simply replaces all mentions of the alloca with zero.
-class AllocaOffsetRewriter : public SCEVRewriteVisitor<AllocaOffsetRewriter> {
- const Value *AllocaPtr;
-
-public:
- AllocaOffsetRewriter(ScalarEvolution &SE, const Value *AllocaPtr)
- : SCEVRewriteVisitor(SE), AllocaPtr(AllocaPtr) {}
-
- const SCEV *visitUnknown(const SCEVUnknown *Expr) {
- if (Expr->getValue() == AllocaPtr)
- return SE.getZero(Expr->getType());
- return Expr;
- }
-};
-
-/// The SafeStack pass splits the stack of each function into the safe
-/// stack, which is only accessed through memory safe dereferences (as
-/// determined statically), and the unsafe stack, which contains all
-/// local variables that are accessed in ways that we can't prove to
-/// be safe.
-class SafeStack : public FunctionPass {
- const TargetMachine *TM;
- const TargetLoweringBase *TL;
- const DataLayout *DL;
- ScalarEvolution *SE;
-
- Type *StackPtrTy;
- Type *IntPtrTy;
- Type *Int32Ty;
- Type *Int8Ty;
-
- Value *UnsafeStackPtr = nullptr;
-
- /// Unsafe stack alignment. Each stack frame must ensure that the stack is
- /// aligned to this value. We need to re-align the unsafe stack if the
- /// alignment of any object on the stack exceeds this value.
- ///
- /// 16 seems like a reasonable upper bound on the alignment of objects that we
- /// might expect to appear on the stack on most common targets.
- enum { StackAlignment = 16 };
-
- /// \brief Build a value representing a pointer to the unsafe stack pointer.
- Value *getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F);
-
- /// \brief Find all static allocas, dynamic allocas, return instructions and
- /// stack restore points (exception unwind blocks and setjmp calls) in the
- /// given function and append them to the respective vectors.
- void findInsts(Function &F, SmallVectorImpl<AllocaInst *> &StaticAllocas,
- SmallVectorImpl<AllocaInst *> &DynamicAllocas,
- SmallVectorImpl<Argument *> &ByValArguments,
- SmallVectorImpl<ReturnInst *> &Returns,
- SmallVectorImpl<Instruction *> &StackRestorePoints);
-
- /// \brief Calculate the allocation size of a given alloca. Returns 0 if the
- /// size can not be statically determined.
- uint64_t getStaticAllocaAllocationSize(const AllocaInst* AI);
-
- /// \brief Allocate space for all static allocas in \p StaticAllocas,
- /// replace allocas with pointers into the unsafe stack and generate code to
- /// restore the stack pointer before all return instructions in \p Returns.
- ///
- /// \returns A pointer to the top of the unsafe stack after all unsafe static
- /// allocas are allocated.
- Value *moveStaticAllocasToUnsafeStack(IRBuilder<> &IRB, Function &F,
- ArrayRef<AllocaInst *> StaticAllocas,
- ArrayRef<Argument *> ByValArguments,
- ArrayRef<ReturnInst *> Returns);
-
- /// \brief Generate code to restore the stack after all stack restore points
- /// in \p StackRestorePoints.
- ///
- /// \returns A local variable in which to maintain the dynamic top of the
- /// unsafe stack if needed.
- AllocaInst *
- createStackRestorePoints(IRBuilder<> &IRB, Function &F,
- ArrayRef<Instruction *> StackRestorePoints,
- Value *StaticTop, bool NeedDynamicTop);
-
- /// \brief Replace all allocas in \p DynamicAllocas with code to allocate
- /// space dynamically on the unsafe stack and store the dynamic unsafe stack
- /// top to \p DynamicTop if non-null.
- void moveDynamicAllocasToUnsafeStack(Function &F, Value *UnsafeStackPtr,
- AllocaInst *DynamicTop,
- ArrayRef<AllocaInst *> DynamicAllocas);
-
- bool IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize);
-
- bool IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
- const Value *AllocaPtr, uint64_t AllocaSize);
- bool IsAccessSafe(Value *Addr, uint64_t Size, const Value *AllocaPtr,
- uint64_t AllocaSize);
-
-public:
- static char ID; // Pass identification, replacement for typeid.
- SafeStack(const TargetMachine *TM)
- : FunctionPass(ID), TM(TM), TL(nullptr), DL(nullptr) {
- initializeSafeStackPass(*PassRegistry::getPassRegistry());
- }
- SafeStack() : SafeStack(nullptr) {}
-
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<ScalarEvolutionWrapperPass>();
- }
-
- bool doInitialization(Module &M) override {
- DL = &M.getDataLayout();
-
- StackPtrTy = Type::getInt8PtrTy(M.getContext());
- IntPtrTy = DL->getIntPtrType(M.getContext());
- Int32Ty = Type::getInt32Ty(M.getContext());
- Int8Ty = Type::getInt8Ty(M.getContext());
-
- return false;
- }
-
- bool runOnFunction(Function &F) override;
-}; // class SafeStack
-
-uint64_t SafeStack::getStaticAllocaAllocationSize(const AllocaInst* AI) {
- uint64_t Size = DL->getTypeAllocSize(AI->getAllocatedType());
- if (AI->isArrayAllocation()) {
- auto C = dyn_cast<ConstantInt>(AI->getArraySize());
- if (!C)
- return 0;
- Size *= C->getZExtValue();
- }
- return Size;
-}
-
-bool SafeStack::IsAccessSafe(Value *Addr, uint64_t AccessSize,
- const Value *AllocaPtr, uint64_t AllocaSize) {
- AllocaOffsetRewriter Rewriter(*SE, AllocaPtr);
- const SCEV *Expr = Rewriter.visit(SE->getSCEV(Addr));
-
- uint64_t BitWidth = SE->getTypeSizeInBits(Expr->getType());
- ConstantRange AccessStartRange = SE->getUnsignedRange(Expr);
- ConstantRange SizeRange =
- ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AccessSize));
- ConstantRange AccessRange = AccessStartRange.add(SizeRange);
- ConstantRange AllocaRange =
- ConstantRange(APInt(BitWidth, 0), APInt(BitWidth, AllocaSize));
- bool Safe = AllocaRange.contains(AccessRange);
-
- DEBUG(dbgs() << "[SafeStack] "
- << (isa<AllocaInst>(AllocaPtr) ? "Alloca " : "ByValArgument ")
- << *AllocaPtr << "\n"
- << " Access " << *Addr << "\n"
- << " SCEV " << *Expr
- << " U: " << SE->getUnsignedRange(Expr)
- << ", S: " << SE->getSignedRange(Expr) << "\n"
- << " Range " << AccessRange << "\n"
- << " AllocaRange " << AllocaRange << "\n"
- << " " << (Safe ? "safe" : "unsafe") << "\n");
-
- return Safe;
-}
-
-bool SafeStack::IsMemIntrinsicSafe(const MemIntrinsic *MI, const Use &U,
- const Value *AllocaPtr,
- uint64_t AllocaSize) {
- // All MemIntrinsics have destination address in Arg0 and size in Arg2.
- if (MI->getRawDest() != U) return true;
- const auto *Len = dyn_cast<ConstantInt>(MI->getLength());
- // Non-constant size => unsafe. FIXME: try SCEV getRange.
- if (!Len) return false;
- return IsAccessSafe(U, Len->getZExtValue(), AllocaPtr, AllocaSize);
-}
-
-/// Check whether a given allocation must be put on the safe
-/// stack or not. The function analyzes all uses of AI and checks whether it is
-/// only accessed in a memory safe way (as decided statically).
-bool SafeStack::IsSafeStackAlloca(const Value *AllocaPtr, uint64_t AllocaSize) {
- // Go through all uses of this alloca and check whether all accesses to the
- // allocated object are statically known to be memory safe and, hence, the
- // object can be placed on the safe stack.
- SmallPtrSet<const Value *, 16> Visited;
- SmallVector<const Value *, 8> WorkList;
- WorkList.push_back(AllocaPtr);
-
- // A DFS search through all uses of the alloca in bitcasts/PHI/GEPs/etc.
- while (!WorkList.empty()) {
- const Value *V = WorkList.pop_back_val();
- for (const Use &UI : V->uses()) {
- auto I = cast<const Instruction>(UI.getUser());
- assert(V == UI.get());
-
- switch (I->getOpcode()) {
- case Instruction::Load: {
- if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getType()), AllocaPtr,
- AllocaSize))
- return false;
- break;
- }
- case Instruction::VAArg:
- // "va-arg" from a pointer is safe.
- break;
- case Instruction::Store: {
- if (V == I->getOperand(0)) {
- // Stored the pointer - conservatively assume it may be unsafe.
- DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
- << "\n store of address: " << *I << "\n");
- return false;
- }
-
- if (!IsAccessSafe(UI, DL->getTypeStoreSize(I->getOperand(0)->getType()),
- AllocaPtr, AllocaSize))
- return false;
- break;
- }
- case Instruction::Ret: {
- // Information leak.
- return false;
- }
-
- case Instruction::Call:
- case Instruction::Invoke: {
- ImmutableCallSite CS(I);
-
- if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
- II->getIntrinsicID() == Intrinsic::lifetime_end)
- continue;
- }
-
- if (const MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
- if (!IsMemIntrinsicSafe(MI, UI, AllocaPtr, AllocaSize)) {
- DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
- << "\n unsafe memintrinsic: " << *I
- << "\n");
- return false;
- }
- continue;
- }
-
- // LLVM 'nocapture' attribute is only set for arguments whose address
- // is not stored, passed around, or used in any other non-trivial way.
- // We assume that passing a pointer to an object as a 'nocapture
- // readnone' argument is safe.
- // FIXME: a more precise solution would require an interprocedural
- // analysis here, which would look at all uses of an argument inside
- // the function being called.
- ImmutableCallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();
- for (ImmutableCallSite::arg_iterator A = B; A != E; ++A)
- if (A->get() == V)
- if (!(CS.doesNotCapture(A - B) && (CS.doesNotAccessMemory(A - B) ||
- CS.doesNotAccessMemory()))) {
- DEBUG(dbgs() << "[SafeStack] Unsafe alloca: " << *AllocaPtr
- << "\n unsafe call: " << *I << "\n");
- return false;
- }
- continue;
- }
-
- default:
- if (Visited.insert(I).second)
- WorkList.push_back(cast<const Instruction>(I));
- }
- }
- }
-
- // All uses of the alloca are safe, we can place it on the safe stack.
- return true;
-}
-
-Value *SafeStack::getOrCreateUnsafeStackPtr(IRBuilder<> &IRB, Function &F) {
- // Check if there is a target-specific location for the unsafe stack pointer.
- if (TL)
- if (Value *V = TL->getSafeStackPointerLocation(IRB))
- return V;
-
- // Otherwise, assume the target links with compiler-rt, which provides a
- // thread-local variable with a magic name.
- Module &M = *F.getParent();
- const char *UnsafeStackPtrVar = "__safestack_unsafe_stack_ptr";
- auto UnsafeStackPtr =
- dyn_cast_or_null<GlobalVariable>(M.getNamedValue(UnsafeStackPtrVar));
-
- bool UseTLS = USPStorage == ThreadLocalUSP;
-
- if (!UnsafeStackPtr) {
- auto TLSModel = UseTLS ?
- GlobalValue::InitialExecTLSModel :
- GlobalValue::NotThreadLocal;
- // The global variable is not defined yet, define it ourselves.
- // We use the initial-exec TLS model because we do not support the
- // variable living anywhere other than in the main executable.
- UnsafeStackPtr = new GlobalVariable(
- M, StackPtrTy, false, GlobalValue::ExternalLinkage, nullptr,
- UnsafeStackPtrVar, nullptr, TLSModel);
- } else {
- // The variable exists, check its type and attributes.
- if (UnsafeStackPtr->getValueType() != StackPtrTy)
- report_fatal_error(Twine(UnsafeStackPtrVar) + " must have void* type");
- if (UseTLS != UnsafeStackPtr->isThreadLocal())
- report_fatal_error(Twine(UnsafeStackPtrVar) + " must " +
- (UseTLS ? "" : "not ") + "be thread-local");
- }
- return UnsafeStackPtr;
-}
-
-void SafeStack::findInsts(Function &F,
- SmallVectorImpl<AllocaInst *> &StaticAllocas,
- SmallVectorImpl<AllocaInst *> &DynamicAllocas,
- SmallVectorImpl<Argument *> &ByValArguments,
- SmallVectorImpl<ReturnInst *> &Returns,
- SmallVectorImpl<Instruction *> &StackRestorePoints) {
- for (Instruction &I : instructions(&F)) {
- if (auto AI = dyn_cast<AllocaInst>(&I)) {
- ++NumAllocas;
-
- uint64_t Size = getStaticAllocaAllocationSize(AI);
- if (IsSafeStackAlloca(AI, Size))
- continue;
-
- if (AI->isStaticAlloca()) {
- ++NumUnsafeStaticAllocas;
- StaticAllocas.push_back(AI);
- } else {
- ++NumUnsafeDynamicAllocas;
- DynamicAllocas.push_back(AI);
- }
- } else if (auto RI = dyn_cast<ReturnInst>(&I)) {
- Returns.push_back(RI);
- } else if (auto CI = dyn_cast<CallInst>(&I)) {
- // setjmps require stack restore.
- if (CI->getCalledFunction() && CI->canReturnTwice())
- StackRestorePoints.push_back(CI);
- } else if (auto LP = dyn_cast<LandingPadInst>(&I)) {
- // Exception landing pads require stack restore.
- StackRestorePoints.push_back(LP);
- } else if (auto II = dyn_cast<IntrinsicInst>(&I)) {
- if (II->getIntrinsicID() == Intrinsic::gcroot)
- llvm::report_fatal_error(
- "gcroot intrinsic not compatible with safestack attribute");
- }
- }
- for (Argument &Arg : F.args()) {
- if (!Arg.hasByValAttr())
- continue;
- uint64_t Size =
- DL->getTypeStoreSize(Arg.getType()->getPointerElementType());
- if (IsSafeStackAlloca(&Arg, Size))
- continue;
-
- ++NumUnsafeByValArguments;
- ByValArguments.push_back(&Arg);
- }
-}
-
-AllocaInst *
-SafeStack::createStackRestorePoints(IRBuilder<> &IRB, Function &F,
- ArrayRef<Instruction *> StackRestorePoints,
- Value *StaticTop, bool NeedDynamicTop) {
- if (StackRestorePoints.empty())
- return nullptr;
-
- // We need the current value of the shadow stack pointer to restore
- // after longjmp or exception catching.
-
- // FIXME: On some platforms this could be handled by the longjmp/exception
- // runtime itself.
-
- AllocaInst *DynamicTop = nullptr;
- if (NeedDynamicTop)
- // If we also have dynamic alloca's, the stack pointer value changes
- // throughout the function. For now we store it in an alloca.
- DynamicTop = IRB.CreateAlloca(StackPtrTy, /*ArraySize=*/nullptr,
- "unsafe_stack_dynamic_ptr");
-
- if (!StaticTop)
- // We need the original unsafe stack pointer value, even if there are
- // no unsafe static allocas.
- StaticTop = IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr");
-
- if (NeedDynamicTop)
- IRB.CreateStore(StaticTop, DynamicTop);
-
- // Restore current stack pointer after longjmp/exception catch.
- for (Instruction *I : StackRestorePoints) {
- ++NumUnsafeStackRestorePoints;
-
- IRB.SetInsertPoint(I->getNextNode());
- Value *CurrentTop = DynamicTop ? IRB.CreateLoad(DynamicTop) : StaticTop;
- IRB.CreateStore(CurrentTop, UnsafeStackPtr);
- }
-
- return DynamicTop;
-}
-
-Value *SafeStack::moveStaticAllocasToUnsafeStack(
- IRBuilder<> &IRB, Function &F, ArrayRef<AllocaInst *> StaticAllocas,
- ArrayRef<Argument *> ByValArguments, ArrayRef<ReturnInst *> Returns) {
- if (StaticAllocas.empty() && ByValArguments.empty())
- return nullptr;
-
- DIBuilder DIB(*F.getParent());
-
- // We explicitly compute and set the unsafe stack layout for all unsafe
- // static alloca instructions. We save the unsafe "base pointer" in the
- // prologue into a local variable and restore it in the epilogue.
-
- // Load the current stack pointer (we'll also use it as a base pointer).
- // FIXME: use a dedicated register for it ?
- Instruction *BasePointer =
- IRB.CreateLoad(UnsafeStackPtr, false, "unsafe_stack_ptr");
- assert(BasePointer->getType() == StackPtrTy);
-
- for (ReturnInst *RI : Returns) {
- IRB.SetInsertPoint(RI);
- IRB.CreateStore(BasePointer, UnsafeStackPtr);
- }
-
- // Compute maximum alignment among static objects on the unsafe stack.
- unsigned MaxAlignment = 0;
- for (Argument *Arg : ByValArguments) {
- Type *Ty = Arg->getType()->getPointerElementType();
- unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty),
- Arg->getParamAlignment());
- if (Align > MaxAlignment)
- MaxAlignment = Align;
- }
- for (AllocaInst *AI : StaticAllocas) {
- Type *Ty = AI->getAllocatedType();
- unsigned Align =
- std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment());
- if (Align > MaxAlignment)
- MaxAlignment = Align;
- }
-
- if (MaxAlignment > StackAlignment) {
- // Re-align the base pointer according to the max requested alignment.
- assert(isPowerOf2_32(MaxAlignment));
- IRB.SetInsertPoint(BasePointer->getNextNode());
- BasePointer = cast<Instruction>(IRB.CreateIntToPtr(
- IRB.CreateAnd(IRB.CreatePtrToInt(BasePointer, IntPtrTy),
- ConstantInt::get(IntPtrTy, ~uint64_t(MaxAlignment - 1))),
- StackPtrTy));
- }
-
- int64_t StaticOffset = 0; // Current stack top.
- IRB.SetInsertPoint(BasePointer->getNextNode());
-
- for (Argument *Arg : ByValArguments) {
- Type *Ty = Arg->getType()->getPointerElementType();
-
- uint64_t Size = DL->getTypeStoreSize(Ty);
- if (Size == 0)
- Size = 1; // Don't create zero-sized stack objects.
-
- // Ensure the object is properly aligned.
- unsigned Align = std::max((unsigned)DL->getPrefTypeAlignment(Ty),
- Arg->getParamAlignment());
-
- // Add alignment.
- // NOTE: we ensure that BasePointer itself is aligned to >= Align.
- StaticOffset += Size;
- StaticOffset = RoundUpToAlignment(StaticOffset, Align);
-
- Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8*
- ConstantInt::get(Int32Ty, -StaticOffset));
- Value *NewArg = IRB.CreateBitCast(Off, Arg->getType(),
- Arg->getName() + ".unsafe-byval");
-
- // Replace alloc with the new location.
- replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB,
- /*Deref=*/true, -StaticOffset);
- Arg->replaceAllUsesWith(NewArg);
- IRB.SetInsertPoint(cast<Instruction>(NewArg)->getNextNode());
- IRB.CreateMemCpy(Off, Arg, Size, Arg->getParamAlignment());
- }
-
- // Allocate space for every unsafe static AllocaInst on the unsafe stack.
- for (AllocaInst *AI : StaticAllocas) {
- IRB.SetInsertPoint(AI);
-
- Type *Ty = AI->getAllocatedType();
- uint64_t Size = getStaticAllocaAllocationSize(AI);
- if (Size == 0)
- Size = 1; // Don't create zero-sized stack objects.
-
- // Ensure the object is properly aligned.
- unsigned Align =
- std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment());
-
- // Add alignment.
- // NOTE: we ensure that BasePointer itself is aligned to >= Align.
- StaticOffset += Size;
- StaticOffset = RoundUpToAlignment(StaticOffset, Align);
-
- Value *Off = IRB.CreateGEP(BasePointer, // BasePointer is i8*
- ConstantInt::get(Int32Ty, -StaticOffset));
- Value *NewAI = IRB.CreateBitCast(Off, AI->getType(), AI->getName());
- if (AI->hasName() && isa<Instruction>(NewAI))
- cast<Instruction>(NewAI)->takeName(AI);
-
- // Replace alloc with the new location.
- replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -StaticOffset);
- AI->replaceAllUsesWith(NewAI);
- AI->eraseFromParent();
- }
-
- // Re-align BasePointer so that our callees would see it aligned as
- // expected.
- // FIXME: no need to update BasePointer in leaf functions.
- StaticOffset = RoundUpToAlignment(StaticOffset, StackAlignment);
-
- // Update shadow stack pointer in the function epilogue.
- IRB.SetInsertPoint(BasePointer->getNextNode());
-
- Value *StaticTop =
- IRB.CreateGEP(BasePointer, ConstantInt::get(Int32Ty, -StaticOffset),
- "unsafe_stack_static_top");
- IRB.CreateStore(StaticTop, UnsafeStackPtr);
- return StaticTop;
-}
-
-void SafeStack::moveDynamicAllocasToUnsafeStack(
- Function &F, Value *UnsafeStackPtr, AllocaInst *DynamicTop,
- ArrayRef<AllocaInst *> DynamicAllocas) {
- DIBuilder DIB(*F.getParent());
-
- for (AllocaInst *AI : DynamicAllocas) {
- IRBuilder<> IRB(AI);
-
- // Compute the new SP value (after AI).
- Value *ArraySize = AI->getArraySize();
- if (ArraySize->getType() != IntPtrTy)
- ArraySize = IRB.CreateIntCast(ArraySize, IntPtrTy, false);
-
- Type *Ty = AI->getAllocatedType();
- uint64_t TySize = DL->getTypeAllocSize(Ty);
- Value *Size = IRB.CreateMul(ArraySize, ConstantInt::get(IntPtrTy, TySize));
-
- Value *SP = IRB.CreatePtrToInt(IRB.CreateLoad(UnsafeStackPtr), IntPtrTy);
- SP = IRB.CreateSub(SP, Size);
-
- // Align the SP value to satisfy the AllocaInst, type and stack alignments.
- unsigned Align = std::max(
- std::max((unsigned)DL->getPrefTypeAlignment(Ty), AI->getAlignment()),
- (unsigned)StackAlignment);
-
- assert(isPowerOf2_32(Align));
- Value *NewTop = IRB.CreateIntToPtr(
- IRB.CreateAnd(SP, ConstantInt::get(IntPtrTy, ~uint64_t(Align - 1))),
- StackPtrTy);
-
- // Save the stack pointer.
- IRB.CreateStore(NewTop, UnsafeStackPtr);
- if (DynamicTop)
- IRB.CreateStore(NewTop, DynamicTop);
-
- Value *NewAI = IRB.CreatePointerCast(NewTop, AI->getType());
- if (AI->hasName() && isa<Instruction>(NewAI))
- NewAI->takeName(AI);
-
- replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true);
- AI->replaceAllUsesWith(NewAI);
- AI->eraseFromParent();
- }
-
- if (!DynamicAllocas.empty()) {
- // Now go through the instructions again, replacing stacksave/stackrestore.
- for (inst_iterator It = inst_begin(&F), Ie = inst_end(&F); It != Ie;) {
- Instruction *I = &*(It++);
- auto II = dyn_cast<IntrinsicInst>(I);
- if (!II)
- continue;
-
- if (II->getIntrinsicID() == Intrinsic::stacksave) {
- IRBuilder<> IRB(II);
- Instruction *LI = IRB.CreateLoad(UnsafeStackPtr);
- LI->takeName(II);
- II->replaceAllUsesWith(LI);
- II->eraseFromParent();
- } else if (II->getIntrinsicID() == Intrinsic::stackrestore) {
- IRBuilder<> IRB(II);
- Instruction *SI = IRB.CreateStore(II->getArgOperand(0), UnsafeStackPtr);
- SI->takeName(II);
- assert(II->use_empty());
- II->eraseFromParent();
- }
- }
- }
-}
-
-bool SafeStack::runOnFunction(Function &F) {
- DEBUG(dbgs() << "[SafeStack] Function: " << F.getName() << "\n");
-
- if (!F.hasFnAttribute(Attribute::SafeStack)) {
- DEBUG(dbgs() << "[SafeStack] safestack is not requested"
- " for this function\n");
- return false;
- }
-
- if (F.isDeclaration()) {
- DEBUG(dbgs() << "[SafeStack] function definition"
- " is not available\n");
- return false;
- }
-
- TL = TM ? TM->getSubtargetImpl(F)->getTargetLowering() : nullptr;
- SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
-
- {
- // Make sure the regular stack protector won't run on this function
- // (safestack attribute takes precedence).
- AttrBuilder B;
- B.addAttribute(Attribute::StackProtect)
- .addAttribute(Attribute::StackProtectReq)
- .addAttribute(Attribute::StackProtectStrong);
- F.removeAttributes(
- AttributeSet::FunctionIndex,
- AttributeSet::get(F.getContext(), AttributeSet::FunctionIndex, B));
- }
-
- ++NumFunctions;
-
- SmallVector<AllocaInst *, 16> StaticAllocas;
- SmallVector<AllocaInst *, 4> DynamicAllocas;
- SmallVector<Argument *, 4> ByValArguments;
- SmallVector<ReturnInst *, 4> Returns;
-
- // Collect all points where stack gets unwound and needs to be restored
- // This is only necessary because the runtime (setjmp and unwind code) is
- // not aware of the unsafe stack and won't unwind/restore it prorerly.
- // To work around this problem without changing the runtime, we insert
- // instrumentation to restore the unsafe stack pointer when necessary.
- SmallVector<Instruction *, 4> StackRestorePoints;
-
- // Find all static and dynamic alloca instructions that must be moved to the
- // unsafe stack, all return instructions and stack restore points.
- findInsts(F, StaticAllocas, DynamicAllocas, ByValArguments, Returns,
- StackRestorePoints);
-
- if (StaticAllocas.empty() && DynamicAllocas.empty() &&
- ByValArguments.empty() && StackRestorePoints.empty())
- return false; // Nothing to do in this function.
-
- if (!StaticAllocas.empty() || !DynamicAllocas.empty() ||
- !ByValArguments.empty())
- ++NumUnsafeStackFunctions; // This function has the unsafe stack.
-
- if (!StackRestorePoints.empty())
- ++NumUnsafeStackRestorePointsFunctions;
-
- IRBuilder<> IRB(&F.front(), F.begin()->getFirstInsertionPt());
- UnsafeStackPtr = getOrCreateUnsafeStackPtr(IRB, F);
-
- // The top of the unsafe stack after all unsafe static allocas are allocated.
- Value *StaticTop = moveStaticAllocasToUnsafeStack(IRB, F, StaticAllocas,
- ByValArguments, Returns);
-
- // Safe stack object that stores the current unsafe stack top. It is updated
- // as unsafe dynamic (non-constant-sized) allocas are allocated and freed.
- // This is only needed if we need to restore stack pointer after longjmp
- // or exceptions, and we have dynamic allocations.
- // FIXME: a better alternative might be to store the unsafe stack pointer
- // before setjmp / invoke instructions.
- AllocaInst *DynamicTop = createStackRestorePoints(
- IRB, F, StackRestorePoints, StaticTop, !DynamicAllocas.empty());
-
- // Handle dynamic allocas.
- moveDynamicAllocasToUnsafeStack(F, UnsafeStackPtr, DynamicTop,
- DynamicAllocas);
-
- DEBUG(dbgs() << "[SafeStack] safestack applied\n");
- return true;
-}
-
-} // anonymous namespace
-
-char SafeStack::ID = 0;
-INITIALIZE_TM_PASS_BEGIN(SafeStack, "safe-stack",
- "Safe Stack instrumentation pass", false, false)
-INITIALIZE_TM_PASS_END(SafeStack, "safe-stack",
- "Safe Stack instrumentation pass", false, false)
-
-FunctionPass *llvm::createSafeStackPass(const llvm::TargetMachine *TM) {
- return new SafeStack(TM);
-}
diff --git a/gnu/llvm/lib/Transforms/Makefile b/gnu/llvm/lib/Transforms/Makefile
deleted file mode 100644
index c390517d07c..00000000000
--- a/gnu/llvm/lib/Transforms/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-##===- lib/Transforms/Makefile -----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-PARALLEL_DIRS = Utils Instrumentation Scalar InstCombine IPO Vectorize Hello ObjCARC
-
-include $(LEVEL)/Makefile.config
-
-# No support for plugins on windows targets
-ifeq ($(HOST_OS), $(filter $(HOST_OS), Cygwin MingW Minix))
- PARALLEL_DIRS := $(filter-out Hello, $(PARALLEL_DIRS))
-endif
-
-include $(LEVEL)/Makefile.common
diff --git a/gnu/llvm/lib/Transforms/ObjCARC/Makefile b/gnu/llvm/lib/Transforms/ObjCARC/Makefile
deleted file mode 100644
index 2a34e21714f..00000000000
--- a/gnu/llvm/lib/Transforms/ObjCARC/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/ObjCARC/Makefile ---------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMObjCARCOpts
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/Scalar/Makefile b/gnu/llvm/lib/Transforms/Scalar/Makefile
deleted file mode 100644
index cc42fd00ac7..00000000000
--- a/gnu/llvm/lib/Transforms/Scalar/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/Scalar/Makefile ----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMScalarOpts
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/gnu/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
deleted file mode 100644
index 114d22ddf2e..00000000000
--- a/gnu/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp
+++ /dev/null
@@ -1,2630 +0,0 @@
-//===- ScalarReplAggregates.cpp - Scalar Replacement of Aggregates --------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This transformation implements the well known scalar replacement of
-// aggregates transformation. This xform breaks up alloca instructions of
-// aggregate type (structure or array) into individual alloca instructions for
-// each member (if possible). Then, if possible, it transforms the individual
-// alloca instructions into nice clean scalar SSA form.
-//
-// This combines a simple SRoA algorithm with the Mem2Reg algorithm because they
-// often interact, especially for C++ programs. As such, iterating between
-// SRoA, then Mem2Reg until we run out of things to promote works well.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/Loads.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/CallSite.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/GetElementPtrTypeIterator.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Utils/Local.h"
-#include "llvm/Transforms/Utils/PromoteMemToReg.h"
-#include "llvm/Transforms/Utils/SSAUpdater.h"
-using namespace llvm;
-
-#define DEBUG_TYPE "scalarrepl"
-
-STATISTIC(NumReplaced, "Number of allocas broken up");
-STATISTIC(NumPromoted, "Number of allocas promoted");
-STATISTIC(NumAdjusted, "Number of scalar allocas adjusted to allow promotion");
-STATISTIC(NumConverted, "Number of aggregates converted to scalar");
-
-namespace {
-#define SROA SROA_
- struct SROA : public FunctionPass {
- SROA(int T, bool hasDT, char &ID, int ST, int AT, int SLT)
- : FunctionPass(ID), HasDomTree(hasDT) {
- if (T == -1)
- SRThreshold = 128;
- else
- SRThreshold = T;
- if (ST == -1)
- StructMemberThreshold = 32;
- else
- StructMemberThreshold = ST;
- if (AT == -1)
- ArrayElementThreshold = 8;
- else
- ArrayElementThreshold = AT;
- if (SLT == -1)
- // Do not limit the scalar integer load size if no threshold is given.
- ScalarLoadThreshold = -1;
- else
- ScalarLoadThreshold = SLT;
- }
-
- bool runOnFunction(Function &F) override;
-
- bool performScalarRepl(Function &F);
- bool performPromotion(Function &F);
-
- private:
- bool HasDomTree;
-
- /// DeadInsts - Keep track of instructions we have made dead, so that
- /// we can remove them after we are done working.
- SmallVector<Value*, 32> DeadInsts;
-
- /// AllocaInfo - When analyzing uses of an alloca instruction, this captures
- /// information about the uses. All these fields are initialized to false
- /// and set to true when something is learned.
- struct AllocaInfo {
- /// The alloca to promote.
- AllocaInst *AI;
-
- /// CheckedPHIs - This is a set of verified PHI nodes, to prevent infinite
- /// looping and avoid redundant work.
- SmallPtrSet<PHINode*, 8> CheckedPHIs;
-
- /// isUnsafe - This is set to true if the alloca cannot be SROA'd.
- bool isUnsafe : 1;
-
- /// isMemCpySrc - This is true if this aggregate is memcpy'd from.
- bool isMemCpySrc : 1;
-
- /// isMemCpyDst - This is true if this aggregate is memcpy'd into.
- bool isMemCpyDst : 1;
-
- /// hasSubelementAccess - This is true if a subelement of the alloca is
- /// ever accessed, or false if the alloca is only accessed with mem
- /// intrinsics or load/store that only access the entire alloca at once.
- bool hasSubelementAccess : 1;
-
- /// hasALoadOrStore - This is true if there are any loads or stores to it.
- /// The alloca may just be accessed with memcpy, for example, which would
- /// not set this.
- bool hasALoadOrStore : 1;
-
- explicit AllocaInfo(AllocaInst *ai)
- : AI(ai), isUnsafe(false), isMemCpySrc(false), isMemCpyDst(false),
- hasSubelementAccess(false), hasALoadOrStore(false) {}
- };
-
- /// SRThreshold - The maximum alloca size to considered for SROA.
- unsigned SRThreshold;
-
- /// StructMemberThreshold - The maximum number of members a struct can
- /// contain to be considered for SROA.
- unsigned StructMemberThreshold;
-
- /// ArrayElementThreshold - The maximum number of elements an array can
- /// have to be considered for SROA.
- unsigned ArrayElementThreshold;
-
- /// ScalarLoadThreshold - The maximum size in bits of scalars to load when
- /// converting to scalar
- unsigned ScalarLoadThreshold;
-
- void MarkUnsafe(AllocaInfo &I, Instruction *User) {
- I.isUnsafe = true;
- DEBUG(dbgs() << " Transformation preventing inst: " << *User << '\n');
- }
-
- bool isSafeAllocaToScalarRepl(AllocaInst *AI);
-
- void isSafeForScalarRepl(Instruction *I, uint64_t Offset, AllocaInfo &Info);
- void isSafePHISelectUseForScalarRepl(Instruction *User, uint64_t Offset,
- AllocaInfo &Info);
- void isSafeGEP(GetElementPtrInst *GEPI, uint64_t &Offset, AllocaInfo &Info);
- void isSafeMemAccess(uint64_t Offset, uint64_t MemSize,
- Type *MemOpType, bool isStore, AllocaInfo &Info,
- Instruction *TheAccess, bool AllowWholeAccess);
- bool TypeHasComponent(Type *T, uint64_t Offset, uint64_t Size,
- const DataLayout &DL);
- uint64_t FindElementAndOffset(Type *&T, uint64_t &Offset, Type *&IdxTy,
- const DataLayout &DL);
-
- void DoScalarReplacement(AllocaInst *AI,
- std::vector<AllocaInst*> &WorkList);
- void DeleteDeadInstructions();
-
- void RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteBitCast(BitCastInst *BC, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteLifetimeIntrinsic(IntrinsicInst *II, AllocaInst *AI,
- uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
- AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts);
- void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts);
- bool ShouldAttemptScalarRepl(AllocaInst *AI);
- };
-
- // SROA_DT - SROA that uses DominatorTree.
- struct SROA_DT : public SROA {
- static char ID;
- public:
- SROA_DT(int T = -1, int ST = -1, int AT = -1, int SLT = -1) :
- SROA(T, true, ID, ST, AT, SLT) {
- initializeSROA_DTPass(*PassRegistry::getPassRegistry());
- }
-
- // getAnalysisUsage - This pass does not require any passes, but we know it
- // will not alter the CFG, so say so.
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<AssumptionCacheTracker>();
- AU.addRequired<DominatorTreeWrapperPass>();
- AU.setPreservesCFG();
- }
- };
-
- // SROA_SSAUp - SROA that uses SSAUpdater.
- struct SROA_SSAUp : public SROA {
- static char ID;
- public:
- SROA_SSAUp(int T = -1, int ST = -1, int AT = -1, int SLT = -1) :
- SROA(T, false, ID, ST, AT, SLT) {
- initializeSROA_SSAUpPass(*PassRegistry::getPassRegistry());
- }
-
- // getAnalysisUsage - This pass does not require any passes, but we know it
- // will not alter the CFG, so say so.
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.addRequired<AssumptionCacheTracker>();
- AU.setPreservesCFG();
- }
- };
-
-}
-
-char SROA_DT::ID = 0;
-char SROA_SSAUp::ID = 0;
-
-INITIALIZE_PASS_BEGIN(SROA_DT, "scalarrepl",
- "Scalar Replacement of Aggregates (DT)", false, false)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_END(SROA_DT, "scalarrepl",
- "Scalar Replacement of Aggregates (DT)", false, false)
-
-INITIALIZE_PASS_BEGIN(SROA_SSAUp, "scalarrepl-ssa",
- "Scalar Replacement of Aggregates (SSAUp)", false, false)
-INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
-INITIALIZE_PASS_END(SROA_SSAUp, "scalarrepl-ssa",
- "Scalar Replacement of Aggregates (SSAUp)", false, false)
-
-// Public interface to the ScalarReplAggregates pass
-FunctionPass *llvm::createScalarReplAggregatesPass(int Threshold,
- bool UseDomTree,
- int StructMemberThreshold,
- int ArrayElementThreshold,
- int ScalarLoadThreshold) {
- if (UseDomTree)
- return new SROA_DT(Threshold, StructMemberThreshold, ArrayElementThreshold,
- ScalarLoadThreshold);
- return new SROA_SSAUp(Threshold, StructMemberThreshold,
- ArrayElementThreshold, ScalarLoadThreshold);
-}
-
-
-//===----------------------------------------------------------------------===//
-// Convert To Scalar Optimization.
-//===----------------------------------------------------------------------===//
-
-namespace {
-/// ConvertToScalarInfo - This class implements the "Convert To Scalar"
-/// optimization, which scans the uses of an alloca and determines if it can
-/// rewrite it in terms of a single new alloca that can be mem2reg'd.
-class ConvertToScalarInfo {
- /// AllocaSize - The size of the alloca being considered in bytes.
- unsigned AllocaSize;
- const DataLayout &DL;
- unsigned ScalarLoadThreshold;
-
- /// IsNotTrivial - This is set to true if there is some access to the object
- /// which means that mem2reg can't promote it.
- bool IsNotTrivial;
-
- /// ScalarKind - Tracks the kind of alloca being considered for promotion,
- /// computed based on the uses of the alloca rather than the LLVM type system.
- enum {
- Unknown,
-
- // Accesses via GEPs that are consistent with element access of a vector
- // type. This will not be converted into a vector unless there is a later
- // access using an actual vector type.
- ImplicitVector,
-
- // Accesses via vector operations and GEPs that are consistent with the
- // layout of a vector type.
- Vector,
-
- // An integer bag-of-bits with bitwise operations for insertion and
- // extraction. Any combination of types can be converted into this kind
- // of scalar.
- Integer
- } ScalarKind;
-
- /// VectorTy - This tracks the type that we should promote the vector to if
- /// it is possible to turn it into a vector. This starts out null, and if it
- /// isn't possible to turn into a vector type, it gets set to VoidTy.
- VectorType *VectorTy;
-
- /// HadNonMemTransferAccess - True if there is at least one access to the
- /// alloca that is not a MemTransferInst. We don't want to turn structs into
- /// large integers unless there is some potential for optimization.
- bool HadNonMemTransferAccess;
-
- /// HadDynamicAccess - True if some element of this alloca was dynamic.
- /// We don't yet have support for turning a dynamic access into a large
- /// integer.
- bool HadDynamicAccess;
-
-public:
- explicit ConvertToScalarInfo(unsigned Size, const DataLayout &DL,
- unsigned SLT)
- : AllocaSize(Size), DL(DL), ScalarLoadThreshold(SLT), IsNotTrivial(false),
- ScalarKind(Unknown), VectorTy(nullptr), HadNonMemTransferAccess(false),
- HadDynamicAccess(false) { }
-
- AllocaInst *TryConvert(AllocaInst *AI);
-
-private:
- bool CanConvertToScalar(Value *V, uint64_t Offset, Value* NonConstantIdx);
- void MergeInTypeForLoadOrStore(Type *In, uint64_t Offset);
- bool MergeInVectorType(VectorType *VInTy, uint64_t Offset);
- void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset,
- Value *NonConstantIdx);
-
- Value *ConvertScalar_ExtractValue(Value *NV, Type *ToType,
- uint64_t Offset, Value* NonConstantIdx,
- IRBuilder<> &Builder);
- Value *ConvertScalar_InsertValue(Value *StoredVal, Value *ExistingVal,
- uint64_t Offset, Value* NonConstantIdx,
- IRBuilder<> &Builder);
-};
-} // end anonymous namespace.
-
-
-/// TryConvert - Analyze the specified alloca, and if it is safe to do so,
-/// rewrite it to be a new alloca which is mem2reg'able. This returns the new
-/// alloca if possible or null if not.
-AllocaInst *ConvertToScalarInfo::TryConvert(AllocaInst *AI) {
- // If we can't convert this scalar, or if mem2reg can trivially do it, bail
- // out.
- if (!CanConvertToScalar(AI, 0, nullptr) || !IsNotTrivial)
- return nullptr;
-
- // If an alloca has only memset / memcpy uses, it may still have an Unknown
- // ScalarKind. Treat it as an Integer below.
- if (ScalarKind == Unknown)
- ScalarKind = Integer;
-
- if (ScalarKind == Vector && VectorTy->getBitWidth() != AllocaSize * 8)
- ScalarKind = Integer;
-
- // If we were able to find a vector type that can handle this with
- // insert/extract elements, and if there was at least one use that had
- // a vector type, promote this to a vector. We don't want to promote
- // random stuff that doesn't use vectors (e.g. <9 x double>) because then
- // we just get a lot of insert/extracts. If at least one vector is
- // involved, then we probably really do have a union of vector/array.
- Type *NewTy;
- if (ScalarKind == Vector) {
- assert(VectorTy && "Missing type for vector scalar.");
- DEBUG(dbgs() << "CONVERT TO VECTOR: " << *AI << "\n TYPE = "
- << *VectorTy << '\n');
- NewTy = VectorTy; // Use the vector type.
- } else {
- unsigned BitWidth = AllocaSize * 8;
-
- // Do not convert to scalar integer if the alloca size exceeds the
- // scalar load threshold.
- if (BitWidth > ScalarLoadThreshold)
- return nullptr;
-
- if ((ScalarKind == ImplicitVector || ScalarKind == Integer) &&
- !HadNonMemTransferAccess && !DL.fitsInLegalInteger(BitWidth))
- return nullptr;
- // Dynamic accesses on integers aren't yet supported. They need us to shift
- // by a dynamic amount which could be difficult to work out as we might not
- // know whether to use a left or right shift.
- if (ScalarKind == Integer && HadDynamicAccess)
- return nullptr;
-
- DEBUG(dbgs() << "CONVERT TO SCALAR INTEGER: " << *AI << "\n");
- // Create and insert the integer alloca.
- NewTy = IntegerType::get(AI->getContext(), BitWidth);
- }
- AllocaInst *NewAI =
- new AllocaInst(NewTy, nullptr, "", &AI->getParent()->front());
- ConvertUsesToScalar(AI, NewAI, 0, nullptr);
- return NewAI;
-}
-
-/// MergeInTypeForLoadOrStore - Add the 'In' type to the accumulated vector type
-/// (VectorTy) so far at the offset specified by Offset (which is specified in
-/// bytes).
-///
-/// There are two cases we handle here:
-/// 1) A union of vector types of the same size and potentially its elements.
-/// Here we turn element accesses into insert/extract element operations.
-/// This promotes a <4 x float> with a store of float to the third element
-/// into a <4 x float> that uses insert element.
-/// 2) A fully general blob of memory, which we turn into some (potentially
-/// large) integer type with extract and insert operations where the loads
-/// and stores would mutate the memory. We mark this by setting VectorTy
-/// to VoidTy.
-void ConvertToScalarInfo::MergeInTypeForLoadOrStore(Type *In,
- uint64_t Offset) {
- // If we already decided to turn this into a blob of integer memory, there is
- // nothing to be done.
- if (ScalarKind == Integer)
- return;
-
- // If this could be contributing to a vector, analyze it.
-
- // If the In type is a vector that is the same size as the alloca, see if it
- // matches the existing VecTy.
- if (VectorType *VInTy = dyn_cast<VectorType>(In)) {
- if (MergeInVectorType(VInTy, Offset))
- return;
- } else if (In->isFloatTy() || In->isDoubleTy() ||
- (In->isIntegerTy() && In->getPrimitiveSizeInBits() >= 8 &&
- isPowerOf2_32(In->getPrimitiveSizeInBits()))) {
- // Full width accesses can be ignored, because they can always be turned
- // into bitcasts.
- unsigned EltSize = In->getPrimitiveSizeInBits()/8;
- if (EltSize == AllocaSize)
- return;
-
- // If we're accessing something that could be an element of a vector, see
- // if the implied vector agrees with what we already have and if Offset is
- // compatible with it.
- if (Offset % EltSize == 0 && AllocaSize % EltSize == 0 &&
- (!VectorTy || EltSize == VectorTy->getElementType()
- ->getPrimitiveSizeInBits()/8)) {
- if (!VectorTy) {
- ScalarKind = ImplicitVector;
- VectorTy = VectorType::get(In, AllocaSize/EltSize);
- }
- return;
- }
- }
-
- // Otherwise, we have a case that we can't handle with an optimized vector
- // form. We can still turn this into a large integer.
- ScalarKind = Integer;
-}
-
-/// MergeInVectorType - Handles the vector case of MergeInTypeForLoadOrStore,
-/// returning true if the type was successfully merged and false otherwise.
-bool ConvertToScalarInfo::MergeInVectorType(VectorType *VInTy,
- uint64_t Offset) {
- if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) {
- // If we're storing/loading a vector of the right size, allow it as a
- // vector. If this the first vector we see, remember the type so that
- // we know the element size. If this is a subsequent access, ignore it
- // even if it is a differing type but the same size. Worst case we can
- // bitcast the resultant vectors.
- if (!VectorTy)
- VectorTy = VInTy;
- ScalarKind = Vector;
- return true;
- }
-
- return false;
-}
-
-/// CanConvertToScalar - V is a pointer. If we can convert the pointee and all
-/// its accesses to a single vector type, return true and set VecTy to
-/// the new type. If we could convert the alloca into a single promotable
-/// integer, return true but set VecTy to VoidTy. Further, if the use is not a
-/// completely trivial use that mem2reg could promote, set IsNotTrivial. Offset
-/// is the current offset from the base of the alloca being analyzed.
-///
-/// If we see at least one access to the value that is as a vector type, set the
-/// SawVec flag.
-bool ConvertToScalarInfo::CanConvertToScalar(Value *V, uint64_t Offset,
- Value* NonConstantIdx) {
- for (User *U : V->users()) {
- Instruction *UI = cast<Instruction>(U);
-
- if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
- // Don't break volatile loads.
- if (!LI->isSimple())
- return false;
- // Don't touch MMX operations.
- if (LI->getType()->isX86_MMXTy())
- return false;
- HadNonMemTransferAccess = true;
- MergeInTypeForLoadOrStore(LI->getType(), Offset);
- continue;
- }
-
- if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
- // Storing the pointer, not into the value?
- if (SI->getOperand(0) == V || !SI->isSimple()) return false;
- // Don't touch MMX operations.
- if (SI->getOperand(0)->getType()->isX86_MMXTy())
- return false;
- HadNonMemTransferAccess = true;
- MergeInTypeForLoadOrStore(SI->getOperand(0)->getType(), Offset);
- continue;
- }
-
- if (BitCastInst *BCI = dyn_cast<BitCastInst>(UI)) {
- if (!onlyUsedByLifetimeMarkers(BCI))
- IsNotTrivial = true; // Can't be mem2reg'd.
- if (!CanConvertToScalar(BCI, Offset, NonConstantIdx))
- return false;
- continue;
- }
-
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(UI)) {
- // If this is a GEP with a variable indices, we can't handle it.
- PointerType* PtrTy = dyn_cast<PointerType>(GEP->getPointerOperandType());
- if (!PtrTy)
- return false;
-
- // Compute the offset that this GEP adds to the pointer.
- SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end());
- Value *GEPNonConstantIdx = nullptr;
- if (!GEP->hasAllConstantIndices()) {
- if (!isa<VectorType>(PtrTy->getElementType()))
- return false;
- if (NonConstantIdx)
- return false;
- GEPNonConstantIdx = Indices.pop_back_val();
- if (!GEPNonConstantIdx->getType()->isIntegerTy(32))
- return false;
- HadDynamicAccess = true;
- } else
- GEPNonConstantIdx = NonConstantIdx;
- uint64_t GEPOffset = DL.getIndexedOffset(PtrTy,
- Indices);
- // See if all uses can be converted.
- if (!CanConvertToScalar(GEP, Offset+GEPOffset, GEPNonConstantIdx))
- return false;
- IsNotTrivial = true; // Can't be mem2reg'd.
- HadNonMemTransferAccess = true;
- continue;
- }
-
- // If this is a constant sized memset of a constant value (e.g. 0) we can
- // handle it.
- if (MemSetInst *MSI = dyn_cast<MemSetInst>(UI)) {
- // Store to dynamic index.
- if (NonConstantIdx)
- return false;
- // Store of constant value.
- if (!isa<ConstantInt>(MSI->getValue()))
- return false;
-
- // Store of constant size.
- ConstantInt *Len = dyn_cast<ConstantInt>(MSI->getLength());
- if (!Len)
- return false;
-
- // If the size differs from the alloca, we can only convert the alloca to
- // an integer bag-of-bits.
- // FIXME: This should handle all of the cases that are currently accepted
- // as vector element insertions.
- if (Len->getZExtValue() != AllocaSize || Offset != 0)
- ScalarKind = Integer;
-
- IsNotTrivial = true; // Can't be mem2reg'd.
- HadNonMemTransferAccess = true;
- continue;
- }
-
- // If this is a memcpy or memmove into or out of the whole allocation, we
- // can handle it like a load or store of the scalar type.
- if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(UI)) {
- // Store to dynamic index.
- if (NonConstantIdx)
- return false;
- ConstantInt *Len = dyn_cast<ConstantInt>(MTI->getLength());
- if (!Len || Len->getZExtValue() != AllocaSize || Offset != 0)
- return false;
-
- IsNotTrivial = true; // Can't be mem2reg'd.
- continue;
- }
-
- // If this is a lifetime intrinsic, we can handle it.
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(UI)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
- II->getIntrinsicID() == Intrinsic::lifetime_end) {
- continue;
- }
- }
-
- // Otherwise, we cannot handle this!
- return false;
- }
-
- return true;
-}
-
-/// ConvertUsesToScalar - Convert all of the users of Ptr to use the new alloca
-/// directly. This happens when we are converting an "integer union" to a
-/// single integer scalar, or when we are converting a "vector union" to a
-/// vector with insert/extractelement instructions.
-///
-/// Offset is an offset from the original alloca, in bits that need to be
-/// shifted to the right. By the end of this, there should be no uses of Ptr.
-void ConvertToScalarInfo::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI,
- uint64_t Offset,
- Value* NonConstantIdx) {
- while (!Ptr->use_empty()) {
- Instruction *User = cast<Instruction>(Ptr->user_back());
-
- if (BitCastInst *CI = dyn_cast<BitCastInst>(User)) {
- ConvertUsesToScalar(CI, NewAI, Offset, NonConstantIdx);
- CI->eraseFromParent();
- continue;
- }
-
- if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(User)) {
- // Compute the offset that this GEP adds to the pointer.
- SmallVector<Value*, 8> Indices(GEP->op_begin()+1, GEP->op_end());
- Value* GEPNonConstantIdx = nullptr;
- if (!GEP->hasAllConstantIndices()) {
- assert(!NonConstantIdx &&
- "Dynamic GEP reading from dynamic GEP unsupported");
- GEPNonConstantIdx = Indices.pop_back_val();
- } else
- GEPNonConstantIdx = NonConstantIdx;
- uint64_t GEPOffset = DL.getIndexedOffset(GEP->getPointerOperandType(),
- Indices);
- ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8, GEPNonConstantIdx);
- GEP->eraseFromParent();
- continue;
- }
-
- IRBuilder<> Builder(User);
-
- if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- // The load is a bit extract from NewAI shifted right by Offset bits.
- Value *LoadedVal = Builder.CreateLoad(NewAI);
- Value *NewLoadVal
- = ConvertScalar_ExtractValue(LoadedVal, LI->getType(), Offset,
- NonConstantIdx, Builder);
- LI->replaceAllUsesWith(NewLoadVal);
- LI->eraseFromParent();
- continue;
- }
-
- if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
- assert(SI->getOperand(0) != Ptr && "Consistency error!");
- Instruction *Old = Builder.CreateLoad(NewAI, NewAI->getName()+".in");
- Value *New = ConvertScalar_InsertValue(SI->getOperand(0), Old, Offset,
- NonConstantIdx, Builder);
- Builder.CreateStore(New, NewAI);
- SI->eraseFromParent();
-
- // If the load we just inserted is now dead, then the inserted store
- // overwrote the entire thing.
- if (Old->use_empty())
- Old->eraseFromParent();
- continue;
- }
-
- // If this is a constant sized memset of a constant value (e.g. 0) we can
- // transform it into a store of the expanded constant value.
- if (MemSetInst *MSI = dyn_cast<MemSetInst>(User)) {
- assert(MSI->getRawDest() == Ptr && "Consistency error!");
- assert(!NonConstantIdx && "Cannot replace dynamic memset with insert");
- int64_t SNumBytes = cast<ConstantInt>(MSI->getLength())->getSExtValue();
- if (SNumBytes > 0 && (SNumBytes >> 32) == 0) {
- unsigned NumBytes = static_cast<unsigned>(SNumBytes);
- unsigned Val = cast<ConstantInt>(MSI->getValue())->getZExtValue();
-
- // Compute the value replicated the right number of times.
- APInt APVal(NumBytes*8, Val);
-
- // Splat the value if non-zero.
- if (Val)
- for (unsigned i = 1; i != NumBytes; ++i)
- APVal |= APVal << 8;
-
- Instruction *Old = Builder.CreateLoad(NewAI, NewAI->getName()+".in");
- Value *New = ConvertScalar_InsertValue(
- ConstantInt::get(User->getContext(), APVal),
- Old, Offset, nullptr, Builder);
- Builder.CreateStore(New, NewAI);
-
- // If the load we just inserted is now dead, then the memset overwrote
- // the entire thing.
- if (Old->use_empty())
- Old->eraseFromParent();
- }
- MSI->eraseFromParent();
- continue;
- }
-
- // If this is a memcpy or memmove into or out of the whole allocation, we
- // can handle it like a load or store of the scalar type.
- if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(User)) {
- assert(Offset == 0 && "must be store to start of alloca");
- assert(!NonConstantIdx && "Cannot replace dynamic transfer with insert");
-
- // If the source and destination are both to the same alloca, then this is
- // a noop copy-to-self, just delete it. Otherwise, emit a load and store
- // as appropriate.
- AllocaInst *OrigAI = cast<AllocaInst>(GetUnderlyingObject(Ptr, DL, 0));
-
- if (GetUnderlyingObject(MTI->getSource(), DL, 0) != OrigAI) {
- // Dest must be OrigAI, change this to be a load from the original
- // pointer (bitcasted), then a store to our new alloca.
- assert(MTI->getRawDest() == Ptr && "Neither use is of pointer?");
- Value *SrcPtr = MTI->getSource();
- PointerType* SPTy = cast<PointerType>(SrcPtr->getType());
- PointerType* AIPTy = cast<PointerType>(NewAI->getType());
- if (SPTy->getAddressSpace() != AIPTy->getAddressSpace()) {
- AIPTy = PointerType::get(AIPTy->getElementType(),
- SPTy->getAddressSpace());
- }
- SrcPtr = Builder.CreateBitCast(SrcPtr, AIPTy);
-
- LoadInst *SrcVal = Builder.CreateLoad(SrcPtr, "srcval");
- SrcVal->setAlignment(MTI->getAlignment());
- Builder.CreateStore(SrcVal, NewAI);
- } else if (GetUnderlyingObject(MTI->getDest(), DL, 0) != OrigAI) {
- // Src must be OrigAI, change this to be a load from NewAI then a store
- // through the original dest pointer (bitcasted).
- assert(MTI->getRawSource() == Ptr && "Neither use is of pointer?");
- LoadInst *SrcVal = Builder.CreateLoad(NewAI, "srcval");
-
- PointerType* DPTy = cast<PointerType>(MTI->getDest()->getType());
- PointerType* AIPTy = cast<PointerType>(NewAI->getType());
- if (DPTy->getAddressSpace() != AIPTy->getAddressSpace()) {
- AIPTy = PointerType::get(AIPTy->getElementType(),
- DPTy->getAddressSpace());
- }
- Value *DstPtr = Builder.CreateBitCast(MTI->getDest(), AIPTy);
-
- StoreInst *NewStore = Builder.CreateStore(SrcVal, DstPtr);
- NewStore->setAlignment(MTI->getAlignment());
- } else {
- // Noop transfer. Src == Dst
- }
-
- MTI->eraseFromParent();
- continue;
- }
-
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(User)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
- II->getIntrinsicID() == Intrinsic::lifetime_end) {
- // There's no need to preserve these, as the resulting alloca will be
- // converted to a register anyways.
- II->eraseFromParent();
- continue;
- }
- }
-
- llvm_unreachable("Unsupported operation!");
- }
-}
-
-/// ConvertScalar_ExtractValue - Extract a value of type ToType from an integer
-/// or vector value FromVal, extracting the bits from the offset specified by
-/// Offset. This returns the value, which is of type ToType.
-///
-/// This happens when we are converting an "integer union" to a single
-/// integer scalar, or when we are converting a "vector union" to a vector with
-/// insert/extractelement instructions.
-///
-/// Offset is an offset from the original alloca, in bits that need to be
-/// shifted to the right.
-Value *ConvertToScalarInfo::
-ConvertScalar_ExtractValue(Value *FromVal, Type *ToType,
- uint64_t Offset, Value* NonConstantIdx,
- IRBuilder<> &Builder) {
- // If the load is of the whole new alloca, no conversion is needed.
- Type *FromType = FromVal->getType();
- if (FromType == ToType && Offset == 0)
- return FromVal;
-
- // If the result alloca is a vector type, this is either an element
- // access or a bitcast to another vector type of the same size.
- if (VectorType *VTy = dyn_cast<VectorType>(FromType)) {
- unsigned FromTypeSize = DL.getTypeAllocSize(FromType);
- unsigned ToTypeSize = DL.getTypeAllocSize(ToType);
- if (FromTypeSize == ToTypeSize)
- return Builder.CreateBitCast(FromVal, ToType);
-
- // Otherwise it must be an element access.
- unsigned Elt = 0;
- if (Offset) {
- unsigned EltSize = DL.getTypeAllocSizeInBits(VTy->getElementType());
- Elt = Offset/EltSize;
- assert(EltSize*Elt == Offset && "Invalid modulus in validity checking");
- }
- // Return the element extracted out of it.
- Value *Idx;
- if (NonConstantIdx) {
- if (Elt)
- Idx = Builder.CreateAdd(NonConstantIdx,
- Builder.getInt32(Elt),
- "dyn.offset");
- else
- Idx = NonConstantIdx;
- } else
- Idx = Builder.getInt32(Elt);
- Value *V = Builder.CreateExtractElement(FromVal, Idx);
- if (V->getType() != ToType)
- V = Builder.CreateBitCast(V, ToType);
- return V;
- }
-
- // If ToType is a first class aggregate, extract out each of the pieces and
- // use insertvalue's to form the FCA.
- if (StructType *ST = dyn_cast<StructType>(ToType)) {
- assert(!NonConstantIdx &&
- "Dynamic indexing into struct types not supported");
- const StructLayout &Layout = *DL.getStructLayout(ST);
- Value *Res = UndefValue::get(ST);
- for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
- Value *Elt = ConvertScalar_ExtractValue(FromVal, ST->getElementType(i),
- Offset+Layout.getElementOffsetInBits(i),
- nullptr, Builder);
- Res = Builder.CreateInsertValue(Res, Elt, i);
- }
- return Res;
- }
-
- if (ArrayType *AT = dyn_cast<ArrayType>(ToType)) {
- assert(!NonConstantIdx &&
- "Dynamic indexing into array types not supported");
- uint64_t EltSize = DL.getTypeAllocSizeInBits(AT->getElementType());
- Value *Res = UndefValue::get(AT);
- for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
- Value *Elt = ConvertScalar_ExtractValue(FromVal, AT->getElementType(),
- Offset+i*EltSize, nullptr,
- Builder);
- Res = Builder.CreateInsertValue(Res, Elt, i);
- }
- return Res;
- }
-
- // Otherwise, this must be a union that was converted to an integer value.
- IntegerType *NTy = cast<IntegerType>(FromVal->getType());
-
- // If this is a big-endian system and the load is narrower than the
- // full alloca type, we need to do a shift to get the right bits.
- int ShAmt = 0;
- if (DL.isBigEndian()) {
- // On big-endian machines, the lowest bit is stored at the bit offset
- // from the pointer given by getTypeStoreSizeInBits. This matters for
- // integers with a bitwidth that is not a multiple of 8.
- ShAmt = DL.getTypeStoreSizeInBits(NTy) -
- DL.getTypeStoreSizeInBits(ToType) - Offset;
- } else {
- ShAmt = Offset;
- }
-
- // Note: we support negative bitwidths (with shl) which are not defined.
- // We do this to support (f.e.) loads off the end of a structure where
- // only some bits are used.
- if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth())
- FromVal = Builder.CreateLShr(FromVal,
- ConstantInt::get(FromVal->getType(), ShAmt));
- else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth())
- FromVal = Builder.CreateShl(FromVal,
- ConstantInt::get(FromVal->getType(), -ShAmt));
-
- // Finally, unconditionally truncate the integer to the right width.
- unsigned LIBitWidth = DL.getTypeSizeInBits(ToType);
- if (LIBitWidth < NTy->getBitWidth())
- FromVal =
- Builder.CreateTrunc(FromVal, IntegerType::get(FromVal->getContext(),
- LIBitWidth));
- else if (LIBitWidth > NTy->getBitWidth())
- FromVal =
- Builder.CreateZExt(FromVal, IntegerType::get(FromVal->getContext(),
- LIBitWidth));
-
- // If the result is an integer, this is a trunc or bitcast.
- if (ToType->isIntegerTy()) {
- // Should be done.
- } else if (ToType->isFloatingPointTy() || ToType->isVectorTy()) {
- // Just do a bitcast, we know the sizes match up.
- FromVal = Builder.CreateBitCast(FromVal, ToType);
- } else {
- // Otherwise must be a pointer.
- FromVal = Builder.CreateIntToPtr(FromVal, ToType);
- }
- assert(FromVal->getType() == ToType && "Didn't convert right?");
- return FromVal;
-}
-
-/// ConvertScalar_InsertValue - Insert the value "SV" into the existing integer
-/// or vector value "Old" at the offset specified by Offset.
-///
-/// This happens when we are converting an "integer union" to a
-/// single integer scalar, or when we are converting a "vector union" to a
-/// vector with insert/extractelement instructions.
-///
-/// Offset is an offset from the original alloca, in bits that need to be
-/// shifted to the right.
-///
-/// NonConstantIdx is an index value if there was a GEP with a non-constant
-/// index value. If this is 0 then all GEPs used to find this insert address
-/// are constant.
-Value *ConvertToScalarInfo::
-ConvertScalar_InsertValue(Value *SV, Value *Old,
- uint64_t Offset, Value* NonConstantIdx,
- IRBuilder<> &Builder) {
- // Convert the stored type to the actual type, shift it left to insert
- // then 'or' into place.
- Type *AllocaType = Old->getType();
- LLVMContext &Context = Old->getContext();
-
- if (VectorType *VTy = dyn_cast<VectorType>(AllocaType)) {
- uint64_t VecSize = DL.getTypeAllocSizeInBits(VTy);
- uint64_t ValSize = DL.getTypeAllocSizeInBits(SV->getType());
-
- // Changing the whole vector with memset or with an access of a different
- // vector type?
- if (ValSize == VecSize)
- return Builder.CreateBitCast(SV, AllocaType);
-
- // Must be an element insertion.
- Type *EltTy = VTy->getElementType();
- if (SV->getType() != EltTy)
- SV = Builder.CreateBitCast(SV, EltTy);
- uint64_t EltSize = DL.getTypeAllocSizeInBits(EltTy);
- unsigned Elt = Offset/EltSize;
- Value *Idx;
- if (NonConstantIdx) {
- if (Elt)
- Idx = Builder.CreateAdd(NonConstantIdx,
- Builder.getInt32(Elt),
- "dyn.offset");
- else
- Idx = NonConstantIdx;
- } else
- Idx = Builder.getInt32(Elt);
- return Builder.CreateInsertElement(Old, SV, Idx);
- }
-
- // If SV is a first-class aggregate value, insert each value recursively.
- if (StructType *ST = dyn_cast<StructType>(SV->getType())) {
- assert(!NonConstantIdx &&
- "Dynamic indexing into struct types not supported");
- const StructLayout &Layout = *DL.getStructLayout(ST);
- for (unsigned i = 0, e = ST->getNumElements(); i != e; ++i) {
- Value *Elt = Builder.CreateExtractValue(SV, i);
- Old = ConvertScalar_InsertValue(Elt, Old,
- Offset+Layout.getElementOffsetInBits(i),
- nullptr, Builder);
- }
- return Old;
- }
-
- if (ArrayType *AT = dyn_cast<ArrayType>(SV->getType())) {
- assert(!NonConstantIdx &&
- "Dynamic indexing into array types not supported");
- uint64_t EltSize = DL.getTypeAllocSizeInBits(AT->getElementType());
- for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
- Value *Elt = Builder.CreateExtractValue(SV, i);
- Old = ConvertScalar_InsertValue(Elt, Old, Offset+i*EltSize, nullptr,
- Builder);
- }
- return Old;
- }
-
- // If SV is a float, convert it to the appropriate integer type.
- // If it is a pointer, do the same.
- unsigned SrcWidth = DL.getTypeSizeInBits(SV->getType());
- unsigned DestWidth = DL.getTypeSizeInBits(AllocaType);
- unsigned SrcStoreWidth = DL.getTypeStoreSizeInBits(SV->getType());
- unsigned DestStoreWidth = DL.getTypeStoreSizeInBits(AllocaType);
- if (SV->getType()->isFloatingPointTy() || SV->getType()->isVectorTy())
- SV = Builder.CreateBitCast(SV, IntegerType::get(SV->getContext(),SrcWidth));
- else if (SV->getType()->isPointerTy())
- SV = Builder.CreatePtrToInt(SV, DL.getIntPtrType(SV->getType()));
-
- // Zero extend or truncate the value if needed.
- if (SV->getType() != AllocaType) {
- if (SV->getType()->getPrimitiveSizeInBits() <
- AllocaType->getPrimitiveSizeInBits())
- SV = Builder.CreateZExt(SV, AllocaType);
- else {
- // Truncation may be needed if storing more than the alloca can hold
- // (undefined behavior).
- SV = Builder.CreateTrunc(SV, AllocaType);
- SrcWidth = DestWidth;
- SrcStoreWidth = DestStoreWidth;
- }
- }
-
- // If this is a big-endian system and the store is narrower than the
- // full alloca type, we need to do a shift to get the right bits.
- int ShAmt = 0;
- if (DL.isBigEndian()) {
- // On big-endian machines, the lowest bit is stored at the bit offset
- // from the pointer given by getTypeStoreSizeInBits. This matters for
- // integers with a bitwidth that is not a multiple of 8.
- ShAmt = DestStoreWidth - SrcStoreWidth - Offset;
- } else {
- ShAmt = Offset;
- }
-
- // Note: we support negative bitwidths (with shr) which are not defined.
- // We do this to support (f.e.) stores off the end of a structure where
- // only some bits in the structure are set.
- APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth));
- if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) {
- SV = Builder.CreateShl(SV, ConstantInt::get(SV->getType(), ShAmt));
- Mask <<= ShAmt;
- } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) {
- SV = Builder.CreateLShr(SV, ConstantInt::get(SV->getType(), -ShAmt));
- Mask = Mask.lshr(-ShAmt);
- }
-
- // Mask out the bits we are about to insert from the old value, and or
- // in the new bits.
- if (SrcWidth != DestWidth) {
- assert(DestWidth > SrcWidth);
- Old = Builder.CreateAnd(Old, ConstantInt::get(Context, ~Mask), "mask");
- SV = Builder.CreateOr(Old, SV, "ins");
- }
- return SV;
-}
-
-
-//===----------------------------------------------------------------------===//
-// SRoA Driver
-//===----------------------------------------------------------------------===//
-
-
-bool SROA::runOnFunction(Function &F) {
- if (skipOptnoneFunction(F))
- return false;
-
- bool Changed = performPromotion(F);
-
- while (1) {
- bool LocalChange = performScalarRepl(F);
- if (!LocalChange) break; // No need to repromote if no scalarrepl
- Changed = true;
- LocalChange = performPromotion(F);
- if (!LocalChange) break; // No need to re-scalarrepl if no promotion
- }
-
- return Changed;
-}
-
-namespace {
-class AllocaPromoter : public LoadAndStorePromoter {
- AllocaInst *AI;
- DIBuilder *DIB;
- SmallVector<DbgDeclareInst *, 4> DDIs;
- SmallVector<DbgValueInst *, 4> DVIs;
-public:
- AllocaPromoter(ArrayRef<Instruction*> Insts, SSAUpdater &S,
- DIBuilder *DB)
- : LoadAndStorePromoter(Insts, S), AI(nullptr), DIB(DB) {}
-
- void run(AllocaInst *AI, const SmallVectorImpl<Instruction*> &Insts) {
- // Remember which alloca we're promoting (for isInstInList).
- this->AI = AI;
- if (auto *L = LocalAsMetadata::getIfExists(AI)) {
- if (auto *DINode = MetadataAsValue::getIfExists(AI->getContext(), L)) {
- for (User *U : DINode->users())
- if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(U))
- DDIs.push_back(DDI);
- else if (DbgValueInst *DVI = dyn_cast<DbgValueInst>(U))
- DVIs.push_back(DVI);
- }
- }
-
- LoadAndStorePromoter::run(Insts);
- AI->eraseFromParent();
- for (SmallVectorImpl<DbgDeclareInst *>::iterator I = DDIs.begin(),
- E = DDIs.end(); I != E; ++I) {
- DbgDeclareInst *DDI = *I;
- DDI->eraseFromParent();
- }
- for (SmallVectorImpl<DbgValueInst *>::iterator I = DVIs.begin(),
- E = DVIs.end(); I != E; ++I) {
- DbgValueInst *DVI = *I;
- DVI->eraseFromParent();
- }
- }
-
- bool isInstInList(Instruction *I,
- const SmallVectorImpl<Instruction*> &Insts) const override {
- if (LoadInst *LI = dyn_cast<LoadInst>(I))
- return LI->getOperand(0) == AI;
- return cast<StoreInst>(I)->getPointerOperand() == AI;
- }
-
- void updateDebugInfo(Instruction *Inst) const override {
- for (SmallVectorImpl<DbgDeclareInst *>::const_iterator I = DDIs.begin(),
- E = DDIs.end(); I != E; ++I) {
- DbgDeclareInst *DDI = *I;
- if (StoreInst *SI = dyn_cast<StoreInst>(Inst))
- ConvertDebugDeclareToDebugValue(DDI, SI, *DIB);
- else if (LoadInst *LI = dyn_cast<LoadInst>(Inst))
- ConvertDebugDeclareToDebugValue(DDI, LI, *DIB);
- }
- for (SmallVectorImpl<DbgValueInst *>::const_iterator I = DVIs.begin(),
- E = DVIs.end(); I != E; ++I) {
- DbgValueInst *DVI = *I;
- Value *Arg = nullptr;
- if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
- // If an argument is zero extended then use argument directly. The ZExt
- // may be zapped by an optimization pass in future.
- if (ZExtInst *ZExt = dyn_cast<ZExtInst>(SI->getOperand(0)))
- Arg = dyn_cast<Argument>(ZExt->getOperand(0));
- if (SExtInst *SExt = dyn_cast<SExtInst>(SI->getOperand(0)))
- Arg = dyn_cast<Argument>(SExt->getOperand(0));
- if (!Arg)
- Arg = SI->getOperand(0);
- } else if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
- Arg = LI->getOperand(0);
- } else {
- continue;
- }
- DIB->insertDbgValueIntrinsic(Arg, 0, DVI->getVariable(),
- DVI->getExpression(), DVI->getDebugLoc(),
- Inst);
- }
- }
-};
-} // end anon namespace
-
-/// isSafeSelectToSpeculate - Select instructions that use an alloca and are
-/// subsequently loaded can be rewritten to load both input pointers and then
-/// select between the result, allowing the load of the alloca to be promoted.
-/// From this:
-/// %P2 = select i1 %cond, i32* %Alloca, i32* %Other
-/// %V = load i32* %P2
-/// to:
-/// %V1 = load i32* %Alloca -> will be mem2reg'd
-/// %V2 = load i32* %Other
-/// %V = select i1 %cond, i32 %V1, i32 %V2
-///
-/// We can do this to a select if its only uses are loads and if the operand to
-/// the select can be loaded unconditionally.
-static bool isSafeSelectToSpeculate(SelectInst *SI) {
- const DataLayout &DL = SI->getModule()->getDataLayout();
- bool TDerefable = isDereferenceablePointer(SI->getTrueValue(), DL);
- bool FDerefable = isDereferenceablePointer(SI->getFalseValue(), DL);
-
- for (User *U : SI->users()) {
- LoadInst *LI = dyn_cast<LoadInst>(U);
- if (!LI || !LI->isSimple()) return false;
-
- // Both operands to the select need to be dereferencable, either absolutely
- // (e.g. allocas) or at this point because we can see other accesses to it.
- if (!TDerefable &&
- !isSafeToLoadUnconditionally(SI->getTrueValue(), LI,
- LI->getAlignment()))
- return false;
- if (!FDerefable &&
- !isSafeToLoadUnconditionally(SI->getFalseValue(), LI,
- LI->getAlignment()))
- return false;
- }
-
- return true;
-}
-
-/// isSafePHIToSpeculate - PHI instructions that use an alloca and are
-/// subsequently loaded can be rewritten to load both input pointers in the pred
-/// blocks and then PHI the results, allowing the load of the alloca to be
-/// promoted.
-/// From this:
-/// %P2 = phi [i32* %Alloca, i32* %Other]
-/// %V = load i32* %P2
-/// to:
-/// %V1 = load i32* %Alloca -> will be mem2reg'd
-/// ...
-/// %V2 = load i32* %Other
-/// ...
-/// %V = phi [i32 %V1, i32 %V2]
-///
-/// We can do this to a select if its only uses are loads and if the operand to
-/// the select can be loaded unconditionally.
-static bool isSafePHIToSpeculate(PHINode *PN) {
- // For now, we can only do this promotion if the load is in the same block as
- // the PHI, and if there are no stores between the phi and load.
- // TODO: Allow recursive phi users.
- // TODO: Allow stores.
- BasicBlock *BB = PN->getParent();
- unsigned MaxAlign = 0;
- for (User *U : PN->users()) {
- LoadInst *LI = dyn_cast<LoadInst>(U);
- if (!LI || !LI->isSimple()) return false;
-
- // For now we only allow loads in the same block as the PHI. This is a
- // common case that happens when instcombine merges two loads through a PHI.
- if (LI->getParent() != BB) return false;
-
- // Ensure that there are no instructions between the PHI and the load that
- // could store.
- for (BasicBlock::iterator BBI(PN); &*BBI != LI; ++BBI)
- if (BBI->mayWriteToMemory())
- return false;
-
- MaxAlign = std::max(MaxAlign, LI->getAlignment());
- }
-
- const DataLayout &DL = PN->getModule()->getDataLayout();
-
- // Okay, we know that we have one or more loads in the same block as the PHI.
- // We can transform this if it is safe to push the loads into the predecessor
- // blocks. The only thing to watch out for is that we can't put a possibly
- // trapping load in the predecessor if it is a critical edge.
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- BasicBlock *Pred = PN->getIncomingBlock(i);
- Value *InVal = PN->getIncomingValue(i);
-
- // If the terminator of the predecessor has side-effects (an invoke),
- // there is no safe place to put a load in the predecessor.
- if (Pred->getTerminator()->mayHaveSideEffects())
- return false;
-
- // If the value is produced by the terminator of the predecessor
- // (an invoke), there is no valid place to put a load in the predecessor.
- if (Pred->getTerminator() == InVal)
- return false;
-
- // If the predecessor has a single successor, then the edge isn't critical.
- if (Pred->getTerminator()->getNumSuccessors() == 1)
- continue;
-
- // If this pointer is always safe to load, or if we can prove that there is
- // already a load in the block, then we can move the load to the pred block.
- if (isDereferenceablePointer(InVal, DL) ||
- isSafeToLoadUnconditionally(InVal, Pred->getTerminator(), MaxAlign))
- continue;
-
- return false;
- }
-
- return true;
-}
-
-
-/// tryToMakeAllocaBePromotable - This returns true if the alloca only has
-/// direct (non-volatile) loads and stores to it. If the alloca is close but
-/// not quite there, this will transform the code to allow promotion. As such,
-/// it is a non-pure predicate.
-static bool tryToMakeAllocaBePromotable(AllocaInst *AI, const DataLayout &DL) {
- SetVector<Instruction*, SmallVector<Instruction*, 4>,
- SmallPtrSet<Instruction*, 4> > InstsToRewrite;
- for (User *U : AI->users()) {
- if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
- if (!LI->isSimple())
- return false;
- continue;
- }
-
- if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
- if (SI->getOperand(0) == AI || !SI->isSimple())
- return false; // Don't allow a store OF the AI, only INTO the AI.
- continue;
- }
-
- if (SelectInst *SI = dyn_cast<SelectInst>(U)) {
- // If the condition being selected on is a constant, fold the select, yes
- // this does (rarely) happen early on.
- if (ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition())) {
- Value *Result = SI->getOperand(1+CI->isZero());
- SI->replaceAllUsesWith(Result);
- SI->eraseFromParent();
-
- // This is very rare and we just scrambled the use list of AI, start
- // over completely.
- return tryToMakeAllocaBePromotable(AI, DL);
- }
-
- // If it is safe to turn "load (select c, AI, ptr)" into a select of two
- // loads, then we can transform this by rewriting the select.
- if (!isSafeSelectToSpeculate(SI))
- return false;
-
- InstsToRewrite.insert(SI);
- continue;
- }
-
- if (PHINode *PN = dyn_cast<PHINode>(U)) {
- if (PN->use_empty()) { // Dead PHIs can be stripped.
- InstsToRewrite.insert(PN);
- continue;
- }
-
- // If it is safe to turn "load (phi [AI, ptr, ...])" into a PHI of loads
- // in the pred blocks, then we can transform this by rewriting the PHI.
- if (!isSafePHIToSpeculate(PN))
- return false;
-
- InstsToRewrite.insert(PN);
- continue;
- }
-
- if (BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
- if (onlyUsedByLifetimeMarkers(BCI)) {
- InstsToRewrite.insert(BCI);
- continue;
- }
- }
-
- return false;
- }
-
- // If there are no instructions to rewrite, then all uses are load/stores and
- // we're done!
- if (InstsToRewrite.empty())
- return true;
-
- // If we have instructions that need to be rewritten for this to be promotable
- // take care of it now.
- for (unsigned i = 0, e = InstsToRewrite.size(); i != e; ++i) {
- if (BitCastInst *BCI = dyn_cast<BitCastInst>(InstsToRewrite[i])) {
- // This could only be a bitcast used by nothing but lifetime intrinsics.
- for (BitCastInst::user_iterator I = BCI->user_begin(), E = BCI->user_end();
- I != E;)
- cast<Instruction>(*I++)->eraseFromParent();
- BCI->eraseFromParent();
- continue;
- }
-
- if (SelectInst *SI = dyn_cast<SelectInst>(InstsToRewrite[i])) {
- // Selects in InstsToRewrite only have load uses. Rewrite each as two
- // loads with a new select.
- while (!SI->use_empty()) {
- LoadInst *LI = cast<LoadInst>(SI->user_back());
-
- IRBuilder<> Builder(LI);
- LoadInst *TrueLoad =
- Builder.CreateLoad(SI->getTrueValue(), LI->getName()+".t");
- LoadInst *FalseLoad =
- Builder.CreateLoad(SI->getFalseValue(), LI->getName()+".f");
-
- // Transfer alignment and AA info if present.
- TrueLoad->setAlignment(LI->getAlignment());
- FalseLoad->setAlignment(LI->getAlignment());
-
- AAMDNodes Tags;
- LI->getAAMetadata(Tags);
- if (Tags) {
- TrueLoad->setAAMetadata(Tags);
- FalseLoad->setAAMetadata(Tags);
- }
-
- Value *V = Builder.CreateSelect(SI->getCondition(), TrueLoad, FalseLoad);
- V->takeName(LI);
- LI->replaceAllUsesWith(V);
- LI->eraseFromParent();
- }
-
- // Now that all the loads are gone, the select is gone too.
- SI->eraseFromParent();
- continue;
- }
-
- // Otherwise, we have a PHI node which allows us to push the loads into the
- // predecessors.
- PHINode *PN = cast<PHINode>(InstsToRewrite[i]);
- if (PN->use_empty()) {
- PN->eraseFromParent();
- continue;
- }
-
- Type *LoadTy = cast<PointerType>(PN->getType())->getElementType();
- PHINode *NewPN = PHINode::Create(LoadTy, PN->getNumIncomingValues(),
- PN->getName()+".ld", PN);
-
- // Get the AA tags and alignment to use from one of the loads. It doesn't
- // matter which one we get and if any differ, it doesn't matter.
- LoadInst *SomeLoad = cast<LoadInst>(PN->user_back());
-
- AAMDNodes AATags;
- SomeLoad->getAAMetadata(AATags);
- unsigned Align = SomeLoad->getAlignment();
-
- // Rewrite all loads of the PN to use the new PHI.
- while (!PN->use_empty()) {
- LoadInst *LI = cast<LoadInst>(PN->user_back());
- LI->replaceAllUsesWith(NewPN);
- LI->eraseFromParent();
- }
-
- // Inject loads into all of the pred blocks. Keep track of which blocks we
- // insert them into in case we have multiple edges from the same block.
- DenseMap<BasicBlock*, LoadInst*> InsertedLoads;
-
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- BasicBlock *Pred = PN->getIncomingBlock(i);
- LoadInst *&Load = InsertedLoads[Pred];
- if (!Load) {
- Load = new LoadInst(PN->getIncomingValue(i),
- PN->getName() + "." + Pred->getName(),
- Pred->getTerminator());
- Load->setAlignment(Align);
- if (AATags) Load->setAAMetadata(AATags);
- }
-
- NewPN->addIncoming(Load, Pred);
- }
-
- PN->eraseFromParent();
- }
-
- ++NumAdjusted;
- return true;
-}
-
-bool SROA::performPromotion(Function &F) {
- std::vector<AllocaInst*> Allocas;
- const DataLayout &DL = F.getParent()->getDataLayout();
- DominatorTree *DT = nullptr;
- if (HasDomTree)
- DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
- AssumptionCache &AC =
- getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
-
- BasicBlock &BB = F.getEntryBlock(); // Get the entry node for the function
- DIBuilder DIB(*F.getParent(), /*AllowUnresolved*/ false);
- bool Changed = false;
- SmallVector<Instruction*, 64> Insts;
- while (1) {
- Allocas.clear();
-
- // Find allocas that are safe to promote, by looking at all instructions in
- // the entry node
- for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I)
- if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) // Is it an alloca?
- if (tryToMakeAllocaBePromotable(AI, DL))
- Allocas.push_back(AI);
-
- if (Allocas.empty()) break;
-
- if (HasDomTree)
- PromoteMemToReg(Allocas, *DT, nullptr, &AC);
- else {
- SSAUpdater SSA;
- for (unsigned i = 0, e = Allocas.size(); i != e; ++i) {
- AllocaInst *AI = Allocas[i];
-
- // Build list of instructions to promote.
- for (User *U : AI->users())
- Insts.push_back(cast<Instruction>(U));
- AllocaPromoter(Insts, SSA, &DIB).run(AI, Insts);
- Insts.clear();
- }
- }
- NumPromoted += Allocas.size();
- Changed = true;
- }
-
- return Changed;
-}
-
-
-/// ShouldAttemptScalarRepl - Decide if an alloca is a good candidate for
-/// SROA. It must be a struct or array type with a small number of elements.
-bool SROA::ShouldAttemptScalarRepl(AllocaInst *AI) {
- Type *T = AI->getAllocatedType();
- // Do not promote any struct that has too many members.
- if (StructType *ST = dyn_cast<StructType>(T))
- return ST->getNumElements() <= StructMemberThreshold;
- // Do not promote any array that has too many elements.
- if (ArrayType *AT = dyn_cast<ArrayType>(T))
- return AT->getNumElements() <= ArrayElementThreshold;
- return false;
-}
-
-// performScalarRepl - This algorithm is a simple worklist driven algorithm,
-// which runs on all of the alloca instructions in the entry block, removing
-// them if they are only used by getelementptr instructions.
-//
-bool SROA::performScalarRepl(Function &F) {
- std::vector<AllocaInst*> WorkList;
- const DataLayout &DL = F.getParent()->getDataLayout();
-
- // Scan the entry basic block, adding allocas to the worklist.
- BasicBlock &BB = F.getEntryBlock();
- for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
- if (AllocaInst *A = dyn_cast<AllocaInst>(I))
- WorkList.push_back(A);
-
- // Process the worklist
- bool Changed = false;
- while (!WorkList.empty()) {
- AllocaInst *AI = WorkList.back();
- WorkList.pop_back();
-
- // Handle dead allocas trivially. These can be formed by SROA'ing arrays
- // with unused elements.
- if (AI->use_empty()) {
- AI->eraseFromParent();
- Changed = true;
- continue;
- }
-
- // If this alloca is impossible for us to promote, reject it early.
- if (AI->isArrayAllocation() || !AI->getAllocatedType()->isSized())
- continue;
-
- // Check to see if we can perform the core SROA transformation. We cannot
- // transform the allocation instruction if it is an array allocation
- // (allocations OF arrays are ok though), and an allocation of a scalar
- // value cannot be decomposed at all.
- uint64_t AllocaSize = DL.getTypeAllocSize(AI->getAllocatedType());
-
- // Do not promote [0 x %struct].
- if (AllocaSize == 0) continue;
-
- // Do not promote any struct whose size is too big.
- if (AllocaSize > SRThreshold) continue;
-
- // If the alloca looks like a good candidate for scalar replacement, and if
- // all its users can be transformed, then split up the aggregate into its
- // separate elements.
- if (ShouldAttemptScalarRepl(AI) && isSafeAllocaToScalarRepl(AI)) {
- DoScalarReplacement(AI, WorkList);
- Changed = true;
- continue;
- }
-
- // If we can turn this aggregate value (potentially with casts) into a
- // simple scalar value that can be mem2reg'd into a register value.
- // IsNotTrivial tracks whether this is something that mem2reg could have
- // promoted itself. If so, we don't want to transform it needlessly. Note
- // that we can't just check based on the type: the alloca may be of an i32
- // but that has pointer arithmetic to set byte 3 of it or something.
- if (AllocaInst *NewAI =
- ConvertToScalarInfo((unsigned)AllocaSize, DL, ScalarLoadThreshold)
- .TryConvert(AI)) {
- NewAI->takeName(AI);
- AI->eraseFromParent();
- ++NumConverted;
- Changed = true;
- continue;
- }
-
- // Otherwise, couldn't process this alloca.
- }
-
- return Changed;
-}
-
-/// DoScalarReplacement - This alloca satisfied the isSafeAllocaToScalarRepl
-/// predicate, do SROA now.
-void SROA::DoScalarReplacement(AllocaInst *AI,
- std::vector<AllocaInst*> &WorkList) {
- DEBUG(dbgs() << "Found inst to SROA: " << *AI << '\n');
- SmallVector<AllocaInst*, 32> ElementAllocas;
- if (StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
- ElementAllocas.reserve(ST->getNumContainedTypes());
- for (unsigned i = 0, e = ST->getNumContainedTypes(); i != e; ++i) {
- AllocaInst *NA = new AllocaInst(ST->getContainedType(i), nullptr,
- AI->getAlignment(),
- AI->getName() + "." + Twine(i), AI);
- ElementAllocas.push_back(NA);
- WorkList.push_back(NA); // Add to worklist for recursive processing
- }
- } else {
- ArrayType *AT = cast<ArrayType>(AI->getAllocatedType());
- ElementAllocas.reserve(AT->getNumElements());
- Type *ElTy = AT->getElementType();
- for (unsigned i = 0, e = AT->getNumElements(); i != e; ++i) {
- AllocaInst *NA = new AllocaInst(ElTy, nullptr, AI->getAlignment(),
- AI->getName() + "." + Twine(i), AI);
- ElementAllocas.push_back(NA);
- WorkList.push_back(NA); // Add to worklist for recursive processing
- }
- }
-
- // Now that we have created the new alloca instructions, rewrite all the
- // uses of the old alloca.
- RewriteForScalarRepl(AI, AI, 0, ElementAllocas);
-
- // Now erase any instructions that were made dead while rewriting the alloca.
- DeleteDeadInstructions();
- AI->eraseFromParent();
-
- ++NumReplaced;
-}
-
-/// DeleteDeadInstructions - Erase instructions on the DeadInstrs list,
-/// recursively including all their operands that become trivially dead.
-void SROA::DeleteDeadInstructions() {
- while (!DeadInsts.empty()) {
- Instruction *I = cast<Instruction>(DeadInsts.pop_back_val());
-
- for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI)
- if (Instruction *U = dyn_cast<Instruction>(*OI)) {
- // Zero out the operand and see if it becomes trivially dead.
- // (But, don't add allocas to the dead instruction list -- they are
- // already on the worklist and will be deleted separately.)
- *OI = nullptr;
- if (isInstructionTriviallyDead(U) && !isa<AllocaInst>(U))
- DeadInsts.push_back(U);
- }
-
- I->eraseFromParent();
- }
-}
-
-/// isSafeForScalarRepl - Check if instruction I is a safe use with regard to
-/// performing scalar replacement of alloca AI. The results are flagged in
-/// the Info parameter. Offset indicates the position within AI that is
-/// referenced by this instruction.
-void SROA::isSafeForScalarRepl(Instruction *I, uint64_t Offset,
- AllocaInfo &Info) {
- const DataLayout &DL = I->getModule()->getDataLayout();
- for (Use &U : I->uses()) {
- Instruction *User = cast<Instruction>(U.getUser());
-
- if (BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
- isSafeForScalarRepl(BC, Offset, Info);
- } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
- uint64_t GEPOffset = Offset;
- isSafeGEP(GEPI, GEPOffset, Info);
- if (!Info.isUnsafe)
- isSafeForScalarRepl(GEPI, GEPOffset, Info);
- } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(User)) {
- ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
- if (!Length || Length->isNegative())
- return MarkUnsafe(Info, User);
-
- isSafeMemAccess(Offset, Length->getZExtValue(), nullptr,
- U.getOperandNo() == 0, Info, MI,
- true /*AllowWholeAccess*/);
- } else if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- if (!LI->isSimple())
- return MarkUnsafe(Info, User);
- Type *LIType = LI->getType();
- isSafeMemAccess(Offset, DL.getTypeAllocSize(LIType), LIType, false, Info,
- LI, true /*AllowWholeAccess*/);
- Info.hasALoadOrStore = true;
-
- } else if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
- // Store is ok if storing INTO the pointer, not storing the pointer
- if (!SI->isSimple() || SI->getOperand(0) == I)
- return MarkUnsafe(Info, User);
-
- Type *SIType = SI->getOperand(0)->getType();
- isSafeMemAccess(Offset, DL.getTypeAllocSize(SIType), SIType, true, Info,
- SI, true /*AllowWholeAccess*/);
- Info.hasALoadOrStore = true;
- } else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(User)) {
- if (II->getIntrinsicID() != Intrinsic::lifetime_start &&
- II->getIntrinsicID() != Intrinsic::lifetime_end)
- return MarkUnsafe(Info, User);
- } else if (isa<PHINode>(User) || isa<SelectInst>(User)) {
- isSafePHISelectUseForScalarRepl(User, Offset, Info);
- } else {
- return MarkUnsafe(Info, User);
- }
- if (Info.isUnsafe) return;
- }
-}
-
-
-/// isSafePHIUseForScalarRepl - If we see a PHI node or select using a pointer
-/// derived from the alloca, we can often still split the alloca into elements.
-/// This is useful if we have a large alloca where one element is phi'd
-/// together somewhere: we can SRoA and promote all the other elements even if
-/// we end up not being able to promote this one.
-///
-/// All we require is that the uses of the PHI do not index into other parts of
-/// the alloca. The most important use case for this is single load and stores
-/// that are PHI'd together, which can happen due to code sinking.
-void SROA::isSafePHISelectUseForScalarRepl(Instruction *I, uint64_t Offset,
- AllocaInfo &Info) {
- // If we've already checked this PHI, don't do it again.
- if (PHINode *PN = dyn_cast<PHINode>(I))
- if (!Info.CheckedPHIs.insert(PN).second)
- return;
-
- const DataLayout &DL = I->getModule()->getDataLayout();
- for (User *U : I->users()) {
- Instruction *UI = cast<Instruction>(U);
-
- if (BitCastInst *BC = dyn_cast<BitCastInst>(UI)) {
- isSafePHISelectUseForScalarRepl(BC, Offset, Info);
- } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(UI)) {
- // Only allow "bitcast" GEPs for simplicity. We could generalize this,
- // but would have to prove that we're staying inside of an element being
- // promoted.
- if (!GEPI->hasAllZeroIndices())
- return MarkUnsafe(Info, UI);
- isSafePHISelectUseForScalarRepl(GEPI, Offset, Info);
- } else if (LoadInst *LI = dyn_cast<LoadInst>(UI)) {
- if (!LI->isSimple())
- return MarkUnsafe(Info, UI);
- Type *LIType = LI->getType();
- isSafeMemAccess(Offset, DL.getTypeAllocSize(LIType), LIType, false, Info,
- LI, false /*AllowWholeAccess*/);
- Info.hasALoadOrStore = true;
-
- } else if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
- // Store is ok if storing INTO the pointer, not storing the pointer
- if (!SI->isSimple() || SI->getOperand(0) == I)
- return MarkUnsafe(Info, UI);
-
- Type *SIType = SI->getOperand(0)->getType();
- isSafeMemAccess(Offset, DL.getTypeAllocSize(SIType), SIType, true, Info,
- SI, false /*AllowWholeAccess*/);
- Info.hasALoadOrStore = true;
- } else if (isa<PHINode>(UI) || isa<SelectInst>(UI)) {
- isSafePHISelectUseForScalarRepl(UI, Offset, Info);
- } else {
- return MarkUnsafe(Info, UI);
- }
- if (Info.isUnsafe) return;
- }
-}
-
-/// isSafeGEP - Check if a GEP instruction can be handled for scalar
-/// replacement. It is safe when all the indices are constant, in-bounds
-/// references, and when the resulting offset corresponds to an element within
-/// the alloca type. The results are flagged in the Info parameter. Upon
-/// return, Offset is adjusted as specified by the GEP indices.
-void SROA::isSafeGEP(GetElementPtrInst *GEPI,
- uint64_t &Offset, AllocaInfo &Info) {
- gep_type_iterator GEPIt = gep_type_begin(GEPI), E = gep_type_end(GEPI);
- if (GEPIt == E)
- return;
- bool NonConstant = false;
- unsigned NonConstantIdxSize = 0;
-
- // Walk through the GEP type indices, checking the types that this indexes
- // into.
- for (; GEPIt != E; ++GEPIt) {
- // Ignore struct elements, no extra checking needed for these.
- if ((*GEPIt)->isStructTy())
- continue;
-
- ConstantInt *IdxVal = dyn_cast<ConstantInt>(GEPIt.getOperand());
- if (!IdxVal)
- return MarkUnsafe(Info, GEPI);
- }
-
- // Compute the offset due to this GEP and check if the alloca has a
- // component element at that offset.
- SmallVector<Value*, 8> Indices(GEPI->op_begin() + 1, GEPI->op_end());
- // If this GEP is non-constant then the last operand must have been a
- // dynamic index into a vector. Pop this now as it has no impact on the
- // constant part of the offset.
- if (NonConstant)
- Indices.pop_back();
-
- const DataLayout &DL = GEPI->getModule()->getDataLayout();
- Offset += DL.getIndexedOffset(GEPI->getPointerOperandType(), Indices);
- if (!TypeHasComponent(Info.AI->getAllocatedType(), Offset, NonConstantIdxSize,
- DL))
- MarkUnsafe(Info, GEPI);
-}
-
-/// isHomogeneousAggregate - Check if type T is a struct or array containing
-/// elements of the same type (which is always true for arrays). If so,
-/// return true with NumElts and EltTy set to the number of elements and the
-/// element type, respectively.
-static bool isHomogeneousAggregate(Type *T, unsigned &NumElts,
- Type *&EltTy) {
- if (ArrayType *AT = dyn_cast<ArrayType>(T)) {
- NumElts = AT->getNumElements();
- EltTy = (NumElts == 0 ? nullptr : AT->getElementType());
- return true;
- }
- if (StructType *ST = dyn_cast<StructType>(T)) {
- NumElts = ST->getNumContainedTypes();
- EltTy = (NumElts == 0 ? nullptr : ST->getContainedType(0));
- for (unsigned n = 1; n < NumElts; ++n) {
- if (ST->getContainedType(n) != EltTy)
- return false;
- }
- return true;
- }
- return false;
-}
-
-/// isCompatibleAggregate - Check if T1 and T2 are either the same type or are
-/// "homogeneous" aggregates with the same element type and number of elements.
-static bool isCompatibleAggregate(Type *T1, Type *T2) {
- if (T1 == T2)
- return true;
-
- unsigned NumElts1, NumElts2;
- Type *EltTy1, *EltTy2;
- if (isHomogeneousAggregate(T1, NumElts1, EltTy1) &&
- isHomogeneousAggregate(T2, NumElts2, EltTy2) &&
- NumElts1 == NumElts2 &&
- EltTy1 == EltTy2)
- return true;
-
- return false;
-}
-
-/// isSafeMemAccess - Check if a load/store/memcpy operates on the entire AI
-/// alloca or has an offset and size that corresponds to a component element
-/// within it. The offset checked here may have been formed from a GEP with a
-/// pointer bitcasted to a different type.
-///
-/// If AllowWholeAccess is true, then this allows uses of the entire alloca as a
-/// unit. If false, it only allows accesses known to be in a single element.
-void SROA::isSafeMemAccess(uint64_t Offset, uint64_t MemSize,
- Type *MemOpType, bool isStore,
- AllocaInfo &Info, Instruction *TheAccess,
- bool AllowWholeAccess) {
- const DataLayout &DL = TheAccess->getModule()->getDataLayout();
- // Check if this is a load/store of the entire alloca.
- if (Offset == 0 && AllowWholeAccess &&
- MemSize == DL.getTypeAllocSize(Info.AI->getAllocatedType())) {
- // This can be safe for MemIntrinsics (where MemOpType is 0) and integer
- // loads/stores (which are essentially the same as the MemIntrinsics with
- // regard to copying padding between elements). But, if an alloca is
- // flagged as both a source and destination of such operations, we'll need
- // to check later for padding between elements.
- if (!MemOpType || MemOpType->isIntegerTy()) {
- if (isStore)
- Info.isMemCpyDst = true;
- else
- Info.isMemCpySrc = true;
- return;
- }
- // This is also safe for references using a type that is compatible with
- // the type of the alloca, so that loads/stores can be rewritten using
- // insertvalue/extractvalue.
- if (isCompatibleAggregate(MemOpType, Info.AI->getAllocatedType())) {
- Info.hasSubelementAccess = true;
- return;
- }
- }
- // Check if the offset/size correspond to a component within the alloca type.
- Type *T = Info.AI->getAllocatedType();
- if (TypeHasComponent(T, Offset, MemSize, DL)) {
- Info.hasSubelementAccess = true;
- return;
- }
-
- return MarkUnsafe(Info, TheAccess);
-}
-
-/// TypeHasComponent - Return true if T has a component type with the
-/// specified offset and size. If Size is zero, do not check the size.
-bool SROA::TypeHasComponent(Type *T, uint64_t Offset, uint64_t Size,
- const DataLayout &DL) {
- Type *EltTy;
- uint64_t EltSize;
- if (StructType *ST = dyn_cast<StructType>(T)) {
- const StructLayout *Layout = DL.getStructLayout(ST);
- unsigned EltIdx = Layout->getElementContainingOffset(Offset);
- EltTy = ST->getContainedType(EltIdx);
- EltSize = DL.getTypeAllocSize(EltTy);
- Offset -= Layout->getElementOffset(EltIdx);
- } else if (ArrayType *AT = dyn_cast<ArrayType>(T)) {
- EltTy = AT->getElementType();
- EltSize = DL.getTypeAllocSize(EltTy);
- if (Offset >= AT->getNumElements() * EltSize)
- return false;
- Offset %= EltSize;
- } else if (VectorType *VT = dyn_cast<VectorType>(T)) {
- EltTy = VT->getElementType();
- EltSize = DL.getTypeAllocSize(EltTy);
- if (Offset >= VT->getNumElements() * EltSize)
- return false;
- Offset %= EltSize;
- } else {
- return false;
- }
- if (Offset == 0 && (Size == 0 || EltSize == Size))
- return true;
- // Check if the component spans multiple elements.
- if (Offset + Size > EltSize)
- return false;
- return TypeHasComponent(EltTy, Offset, Size, DL);
-}
-
-/// RewriteForScalarRepl - Alloca AI is being split into NewElts, so rewrite
-/// the instruction I, which references it, to use the separate elements.
-/// Offset indicates the position within AI that is referenced by this
-/// instruction.
-void SROA::RewriteForScalarRepl(Instruction *I, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- const DataLayout &DL = I->getModule()->getDataLayout();
- for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI!=E;) {
- Use &TheUse = *UI++;
- Instruction *User = cast<Instruction>(TheUse.getUser());
-
- if (BitCastInst *BC = dyn_cast<BitCastInst>(User)) {
- RewriteBitCast(BC, AI, Offset, NewElts);
- continue;
- }
-
- if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(User)) {
- RewriteGEP(GEPI, AI, Offset, NewElts);
- continue;
- }
-
- if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(User)) {
- ConstantInt *Length = dyn_cast<ConstantInt>(MI->getLength());
- uint64_t MemSize = Length->getZExtValue();
- if (Offset == 0 && MemSize == DL.getTypeAllocSize(AI->getAllocatedType()))
- RewriteMemIntrinUserOfAlloca(MI, I, AI, NewElts);
- // Otherwise the intrinsic can only touch a single element and the
- // address operand will be updated, so nothing else needs to be done.
- continue;
- }
-
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(User)) {
- if (II->getIntrinsicID() == Intrinsic::lifetime_start ||
- II->getIntrinsicID() == Intrinsic::lifetime_end) {
- RewriteLifetimeIntrinsic(II, AI, Offset, NewElts);
- }
- continue;
- }
-
- if (LoadInst *LI = dyn_cast<LoadInst>(User)) {
- Type *LIType = LI->getType();
-
- if (isCompatibleAggregate(LIType, AI->getAllocatedType())) {
- // Replace:
- // %res = load { i32, i32 }* %alloc
- // with:
- // %load.0 = load i32* %alloc.0
- // %insert.0 insertvalue { i32, i32 } zeroinitializer, i32 %load.0, 0
- // %load.1 = load i32* %alloc.1
- // %insert = insertvalue { i32, i32 } %insert.0, i32 %load.1, 1
- // (Also works for arrays instead of structs)
- Value *Insert = UndefValue::get(LIType);
- IRBuilder<> Builder(LI);
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- Value *Load = Builder.CreateLoad(NewElts[i], "load");
- Insert = Builder.CreateInsertValue(Insert, Load, i, "insert");
- }
- LI->replaceAllUsesWith(Insert);
- DeadInsts.push_back(LI);
- } else if (LIType->isIntegerTy() &&
- DL.getTypeAllocSize(LIType) ==
- DL.getTypeAllocSize(AI->getAllocatedType())) {
- // If this is a load of the entire alloca to an integer, rewrite it.
- RewriteLoadUserOfWholeAlloca(LI, AI, NewElts);
- }
- continue;
- }
-
- if (StoreInst *SI = dyn_cast<StoreInst>(User)) {
- Value *Val = SI->getOperand(0);
- Type *SIType = Val->getType();
- if (isCompatibleAggregate(SIType, AI->getAllocatedType())) {
- // Replace:
- // store { i32, i32 } %val, { i32, i32 }* %alloc
- // with:
- // %val.0 = extractvalue { i32, i32 } %val, 0
- // store i32 %val.0, i32* %alloc.0
- // %val.1 = extractvalue { i32, i32 } %val, 1
- // store i32 %val.1, i32* %alloc.1
- // (Also works for arrays instead of structs)
- IRBuilder<> Builder(SI);
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- Value *Extract = Builder.CreateExtractValue(Val, i, Val->getName());
- Builder.CreateStore(Extract, NewElts[i]);
- }
- DeadInsts.push_back(SI);
- } else if (SIType->isIntegerTy() &&
- DL.getTypeAllocSize(SIType) ==
- DL.getTypeAllocSize(AI->getAllocatedType())) {
- // If this is a store of the entire alloca from an integer, rewrite it.
- RewriteStoreUserOfWholeAlloca(SI, AI, NewElts);
- }
- continue;
- }
-
- if (isa<SelectInst>(User) || isa<PHINode>(User)) {
- // If we have a PHI user of the alloca itself (as opposed to a GEP or
- // bitcast) we have to rewrite it. GEP and bitcast uses will be RAUW'd to
- // the new pointer.
- if (!isa<AllocaInst>(I)) continue;
-
- assert(Offset == 0 && NewElts[0] &&
- "Direct alloca use should have a zero offset");
-
- // If we have a use of the alloca, we know the derived uses will be
- // utilizing just the first element of the scalarized result. Insert a
- // bitcast of the first alloca before the user as required.
- AllocaInst *NewAI = NewElts[0];
- BitCastInst *BCI = new BitCastInst(NewAI, AI->getType(), "", NewAI);
- NewAI->moveBefore(BCI);
- TheUse = BCI;
- continue;
- }
- }
-}
-
-/// RewriteBitCast - Update a bitcast reference to the alloca being replaced
-/// and recursively continue updating all of its uses.
-void SROA::RewriteBitCast(BitCastInst *BC, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- RewriteForScalarRepl(BC, AI, Offset, NewElts);
- if (BC->getOperand(0) != AI)
- return;
-
- // The bitcast references the original alloca. Replace its uses with
- // references to the alloca containing offset zero (which is normally at
- // index zero, but might not be in cases involving structs with elements
- // of size zero).
- Type *T = AI->getAllocatedType();
- uint64_t EltOffset = 0;
- Type *IdxTy;
- uint64_t Idx = FindElementAndOffset(T, EltOffset, IdxTy,
- BC->getModule()->getDataLayout());
- Instruction *Val = NewElts[Idx];
- if (Val->getType() != BC->getDestTy()) {
- Val = new BitCastInst(Val, BC->getDestTy(), "", BC);
- Val->takeName(BC);
- }
- BC->replaceAllUsesWith(Val);
- DeadInsts.push_back(BC);
-}
-
-/// FindElementAndOffset - Return the index of the element containing Offset
-/// within the specified type, which must be either a struct or an array.
-/// Sets T to the type of the element and Offset to the offset within that
-/// element. IdxTy is set to the type of the index result to be used in a
-/// GEP instruction.
-uint64_t SROA::FindElementAndOffset(Type *&T, uint64_t &Offset, Type *&IdxTy,
- const DataLayout &DL) {
- uint64_t Idx = 0;
-
- if (StructType *ST = dyn_cast<StructType>(T)) {
- const StructLayout *Layout = DL.getStructLayout(ST);
- Idx = Layout->getElementContainingOffset(Offset);
- T = ST->getContainedType(Idx);
- Offset -= Layout->getElementOffset(Idx);
- IdxTy = Type::getInt32Ty(T->getContext());
- return Idx;
- } else if (ArrayType *AT = dyn_cast<ArrayType>(T)) {
- T = AT->getElementType();
- uint64_t EltSize = DL.getTypeAllocSize(T);
- Idx = Offset / EltSize;
- Offset -= Idx * EltSize;
- IdxTy = Type::getInt64Ty(T->getContext());
- return Idx;
- }
- VectorType *VT = cast<VectorType>(T);
- T = VT->getElementType();
- uint64_t EltSize = DL.getTypeAllocSize(T);
- Idx = Offset / EltSize;
- Offset -= Idx * EltSize;
- IdxTy = Type::getInt64Ty(T->getContext());
- return Idx;
-}
-
-/// RewriteGEP - Check if this GEP instruction moves the pointer across
-/// elements of the alloca that are being split apart, and if so, rewrite
-/// the GEP to be relative to the new element.
-void SROA::RewriteGEP(GetElementPtrInst *GEPI, AllocaInst *AI, uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- uint64_t OldOffset = Offset;
- const DataLayout &DL = GEPI->getModule()->getDataLayout();
- SmallVector<Value*, 8> Indices(GEPI->op_begin() + 1, GEPI->op_end());
- // If the GEP was dynamic then it must have been a dynamic vector lookup.
- // In this case, it must be the last GEP operand which is dynamic so keep that
- // aside until we've found the constant GEP offset then add it back in at the
- // end.
- Value* NonConstantIdx = nullptr;
- if (!GEPI->hasAllConstantIndices())
- NonConstantIdx = Indices.pop_back_val();
- Offset += DL.getIndexedOffset(GEPI->getPointerOperandType(), Indices);
-
- RewriteForScalarRepl(GEPI, AI, Offset, NewElts);
-
- Type *T = AI->getAllocatedType();
- Type *IdxTy;
- uint64_t OldIdx = FindElementAndOffset(T, OldOffset, IdxTy, DL);
- if (GEPI->getOperand(0) == AI)
- OldIdx = ~0ULL; // Force the GEP to be rewritten.
-
- T = AI->getAllocatedType();
- uint64_t EltOffset = Offset;
- uint64_t Idx = FindElementAndOffset(T, EltOffset, IdxTy, DL);
-
- // If this GEP does not move the pointer across elements of the alloca
- // being split, then it does not needs to be rewritten.
- if (Idx == OldIdx)
- return;
-
- Type *i32Ty = Type::getInt32Ty(AI->getContext());
- SmallVector<Value*, 8> NewArgs;
- NewArgs.push_back(Constant::getNullValue(i32Ty));
- while (EltOffset != 0) {
- uint64_t EltIdx = FindElementAndOffset(T, EltOffset, IdxTy, DL);
- NewArgs.push_back(ConstantInt::get(IdxTy, EltIdx));
- }
- if (NonConstantIdx) {
- Type* GepTy = T;
- // This GEP has a dynamic index. We need to add "i32 0" to index through
- // any structs or arrays in the original type until we get to the vector
- // to index.
- while (!isa<VectorType>(GepTy)) {
- NewArgs.push_back(Constant::getNullValue(i32Ty));
- GepTy = cast<CompositeType>(GepTy)->getTypeAtIndex(0U);
- }
- NewArgs.push_back(NonConstantIdx);
- }
- Instruction *Val = NewElts[Idx];
- if (NewArgs.size() > 1) {
- Val = GetElementPtrInst::CreateInBounds(Val, NewArgs, "", GEPI);
- Val->takeName(GEPI);
- }
- if (Val->getType() != GEPI->getType())
- Val = new BitCastInst(Val, GEPI->getType(), Val->getName(), GEPI);
- GEPI->replaceAllUsesWith(Val);
- DeadInsts.push_back(GEPI);
-}
-
-/// RewriteLifetimeIntrinsic - II is a lifetime.start/lifetime.end. Rewrite it
-/// to mark the lifetime of the scalarized memory.
-void SROA::RewriteLifetimeIntrinsic(IntrinsicInst *II, AllocaInst *AI,
- uint64_t Offset,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- ConstantInt *OldSize = cast<ConstantInt>(II->getArgOperand(0));
- // Put matching lifetime markers on everything from Offset up to
- // Offset+OldSize.
- Type *AIType = AI->getAllocatedType();
- const DataLayout &DL = II->getModule()->getDataLayout();
- uint64_t NewOffset = Offset;
- Type *IdxTy;
- uint64_t Idx = FindElementAndOffset(AIType, NewOffset, IdxTy, DL);
-
- IRBuilder<> Builder(II);
- uint64_t Size = OldSize->getLimitedValue();
-
- if (NewOffset) {
- // Splice the first element and index 'NewOffset' bytes in. SROA will
- // split the alloca again later.
- unsigned AS = AI->getType()->getAddressSpace();
- Value *V = Builder.CreateBitCast(NewElts[Idx], Builder.getInt8PtrTy(AS));
- V = Builder.CreateGEP(Builder.getInt8Ty(), V, Builder.getInt64(NewOffset));
-
- IdxTy = NewElts[Idx]->getAllocatedType();
- uint64_t EltSize = DL.getTypeAllocSize(IdxTy) - NewOffset;
- if (EltSize > Size) {
- EltSize = Size;
- Size = 0;
- } else {
- Size -= EltSize;
- }
- if (II->getIntrinsicID() == Intrinsic::lifetime_start)
- Builder.CreateLifetimeStart(V, Builder.getInt64(EltSize));
- else
- Builder.CreateLifetimeEnd(V, Builder.getInt64(EltSize));
- ++Idx;
- }
-
- for (; Idx != NewElts.size() && Size; ++Idx) {
- IdxTy = NewElts[Idx]->getAllocatedType();
- uint64_t EltSize = DL.getTypeAllocSize(IdxTy);
- if (EltSize > Size) {
- EltSize = Size;
- Size = 0;
- } else {
- Size -= EltSize;
- }
- if (II->getIntrinsicID() == Intrinsic::lifetime_start)
- Builder.CreateLifetimeStart(NewElts[Idx],
- Builder.getInt64(EltSize));
- else
- Builder.CreateLifetimeEnd(NewElts[Idx],
- Builder.getInt64(EltSize));
- }
- DeadInsts.push_back(II);
-}
-
-/// RewriteMemIntrinUserOfAlloca - MI is a memcpy/memset/memmove from or to AI.
-/// Rewrite it to copy or set the elements of the scalarized memory.
-void
-SROA::RewriteMemIntrinUserOfAlloca(MemIntrinsic *MI, Instruction *Inst,
- AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- // If this is a memcpy/memmove, construct the other pointer as the
- // appropriate type. The "Other" pointer is the pointer that goes to memory
- // that doesn't have anything to do with the alloca that we are promoting. For
- // memset, this Value* stays null.
- Value *OtherPtr = nullptr;
- unsigned MemAlignment = MI->getAlignment();
- if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) { // memmove/memcopy
- if (Inst == MTI->getRawDest())
- OtherPtr = MTI->getRawSource();
- else {
- assert(Inst == MTI->getRawSource());
- OtherPtr = MTI->getRawDest();
- }
- }
-
- // If there is an other pointer, we want to convert it to the same pointer
- // type as AI has, so we can GEP through it safely.
- if (OtherPtr) {
- unsigned AddrSpace =
- cast<PointerType>(OtherPtr->getType())->getAddressSpace();
-
- // Remove bitcasts and all-zero GEPs from OtherPtr. This is an
- // optimization, but it's also required to detect the corner case where
- // both pointer operands are referencing the same memory, and where
- // OtherPtr may be a bitcast or GEP that currently being rewritten. (This
- // function is only called for mem intrinsics that access the whole
- // aggregate, so non-zero GEPs are not an issue here.)
- OtherPtr = OtherPtr->stripPointerCasts();
-
- // Copying the alloca to itself is a no-op: just delete it.
- if (OtherPtr == AI || OtherPtr == NewElts[0]) {
- // This code will run twice for a no-op memcpy -- once for each operand.
- // Put only one reference to MI on the DeadInsts list.
- for (SmallVectorImpl<Value *>::const_iterator I = DeadInsts.begin(),
- E = DeadInsts.end(); I != E; ++I)
- if (*I == MI) return;
- DeadInsts.push_back(MI);
- return;
- }
-
- // If the pointer is not the right type, insert a bitcast to the right
- // type.
- Type *NewTy =
- PointerType::get(AI->getType()->getElementType(), AddrSpace);
-
- if (OtherPtr->getType() != NewTy)
- OtherPtr = new BitCastInst(OtherPtr, NewTy, OtherPtr->getName(), MI);
- }
-
- // Process each element of the aggregate.
- bool SROADest = MI->getRawDest() == Inst;
-
- Constant *Zero = Constant::getNullValue(Type::getInt32Ty(MI->getContext()));
- const DataLayout &DL = MI->getModule()->getDataLayout();
-
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- // If this is a memcpy/memmove, emit a GEP of the other element address.
- Value *OtherElt = nullptr;
- unsigned OtherEltAlign = MemAlignment;
-
- if (OtherPtr) {
- Value *Idx[2] = { Zero,
- ConstantInt::get(Type::getInt32Ty(MI->getContext()), i) };
- OtherElt = GetElementPtrInst::CreateInBounds(OtherPtr, Idx,
- OtherPtr->getName()+"."+Twine(i),
- MI);
- uint64_t EltOffset;
- PointerType *OtherPtrTy = cast<PointerType>(OtherPtr->getType());
- Type *OtherTy = OtherPtrTy->getElementType();
- if (StructType *ST = dyn_cast<StructType>(OtherTy)) {
- EltOffset = DL.getStructLayout(ST)->getElementOffset(i);
- } else {
- Type *EltTy = cast<SequentialType>(OtherTy)->getElementType();
- EltOffset = DL.getTypeAllocSize(EltTy) * i;
- }
-
- // The alignment of the other pointer is the guaranteed alignment of the
- // element, which is affected by both the known alignment of the whole
- // mem intrinsic and the alignment of the element. If the alignment of
- // the memcpy (f.e.) is 32 but the element is at a 4-byte offset, then the
- // known alignment is just 4 bytes.
- OtherEltAlign = (unsigned)MinAlign(OtherEltAlign, EltOffset);
- }
-
- Value *EltPtr = NewElts[i];
- Type *EltTy = cast<PointerType>(EltPtr->getType())->getElementType();
-
- // If we got down to a scalar, insert a load or store as appropriate.
- if (EltTy->isSingleValueType()) {
- if (isa<MemTransferInst>(MI)) {
- if (SROADest) {
- // From Other to Alloca.
- Value *Elt = new LoadInst(OtherElt, "tmp", false, OtherEltAlign, MI);
- new StoreInst(Elt, EltPtr, MI);
- } else {
- // From Alloca to Other.
- Value *Elt = new LoadInst(EltPtr, "tmp", MI);
- new StoreInst(Elt, OtherElt, false, OtherEltAlign, MI);
- }
- continue;
- }
- assert(isa<MemSetInst>(MI));
-
- // If the stored element is zero (common case), just store a null
- // constant.
- Constant *StoreVal;
- if (ConstantInt *CI = dyn_cast<ConstantInt>(MI->getArgOperand(1))) {
- if (CI->isZero()) {
- StoreVal = Constant::getNullValue(EltTy); // 0.0, null, 0, <0,0>
- } else {
- // If EltTy is a vector type, get the element type.
- Type *ValTy = EltTy->getScalarType();
-
- // Construct an integer with the right value.
- unsigned EltSize = DL.getTypeSizeInBits(ValTy);
- APInt OneVal(EltSize, CI->getZExtValue());
- APInt TotalVal(OneVal);
- // Set each byte.
- for (unsigned i = 0; 8*i < EltSize; ++i) {
- TotalVal = TotalVal.shl(8);
- TotalVal |= OneVal;
- }
-
- // Convert the integer value to the appropriate type.
- StoreVal = ConstantInt::get(CI->getContext(), TotalVal);
- if (ValTy->isPointerTy())
- StoreVal = ConstantExpr::getIntToPtr(StoreVal, ValTy);
- else if (ValTy->isFloatingPointTy())
- StoreVal = ConstantExpr::getBitCast(StoreVal, ValTy);
- assert(StoreVal->getType() == ValTy && "Type mismatch!");
-
- // If the requested value was a vector constant, create it.
- if (EltTy->isVectorTy()) {
- unsigned NumElts = cast<VectorType>(EltTy)->getNumElements();
- StoreVal = ConstantVector::getSplat(NumElts, StoreVal);
- }
- }
- new StoreInst(StoreVal, EltPtr, MI);
- continue;
- }
- // Otherwise, if we're storing a byte variable, use a memset call for
- // this element.
- }
-
- unsigned EltSize = DL.getTypeAllocSize(EltTy);
- if (!EltSize)
- continue;
-
- IRBuilder<> Builder(MI);
-
- // Finally, insert the meminst for this element.
- if (isa<MemSetInst>(MI)) {
- Builder.CreateMemSet(EltPtr, MI->getArgOperand(1), EltSize,
- MI->isVolatile());
- } else {
- assert(isa<MemTransferInst>(MI));
- Value *Dst = SROADest ? EltPtr : OtherElt; // Dest ptr
- Value *Src = SROADest ? OtherElt : EltPtr; // Src ptr
-
- if (isa<MemCpyInst>(MI))
- Builder.CreateMemCpy(Dst, Src, EltSize, OtherEltAlign,MI->isVolatile());
- else
- Builder.CreateMemMove(Dst, Src, EltSize,OtherEltAlign,MI->isVolatile());
- }
- }
- DeadInsts.push_back(MI);
-}
-
-/// RewriteStoreUserOfWholeAlloca - We found a store of an integer that
-/// overwrites the entire allocation. Extract out the pieces of the stored
-/// integer and store them individually.
-void
-SROA::RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- // Extract each element out of the integer according to its structure offset
- // and store the element value to the individual alloca.
- Value *SrcVal = SI->getOperand(0);
- Type *AllocaEltTy = AI->getAllocatedType();
- const DataLayout &DL = SI->getModule()->getDataLayout();
- uint64_t AllocaSizeBits = DL.getTypeAllocSizeInBits(AllocaEltTy);
-
- IRBuilder<> Builder(SI);
-
- // Handle tail padding by extending the operand
- if (DL.getTypeSizeInBits(SrcVal->getType()) != AllocaSizeBits)
- SrcVal = Builder.CreateZExt(SrcVal,
- IntegerType::get(SI->getContext(), AllocaSizeBits));
-
- DEBUG(dbgs() << "PROMOTING STORE TO WHOLE ALLOCA: " << *AI << '\n' << *SI
- << '\n');
-
- // There are two forms here: AI could be an array or struct. Both cases
- // have different ways to compute the element offset.
- if (StructType *EltSTy = dyn_cast<StructType>(AllocaEltTy)) {
- const StructLayout *Layout = DL.getStructLayout(EltSTy);
-
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- // Get the number of bits to shift SrcVal to get the value.
- Type *FieldTy = EltSTy->getElementType(i);
- uint64_t Shift = Layout->getElementOffsetInBits(i);
-
- if (DL.isBigEndian())
- Shift = AllocaSizeBits - Shift - DL.getTypeAllocSizeInBits(FieldTy);
-
- Value *EltVal = SrcVal;
- if (Shift) {
- Value *ShiftVal = ConstantInt::get(EltVal->getType(), Shift);
- EltVal = Builder.CreateLShr(EltVal, ShiftVal, "sroa.store.elt");
- }
-
- // Truncate down to an integer of the right size.
- uint64_t FieldSizeBits = DL.getTypeSizeInBits(FieldTy);
-
- // Ignore zero sized fields like {}, they obviously contain no data.
- if (FieldSizeBits == 0) continue;
-
- if (FieldSizeBits != AllocaSizeBits)
- EltVal = Builder.CreateTrunc(EltVal,
- IntegerType::get(SI->getContext(), FieldSizeBits));
- Value *DestField = NewElts[i];
- if (EltVal->getType() == FieldTy) {
- // Storing to an integer field of this size, just do it.
- } else if (FieldTy->isFloatingPointTy() || FieldTy->isVectorTy()) {
- // Bitcast to the right element type (for fp/vector values).
- EltVal = Builder.CreateBitCast(EltVal, FieldTy);
- } else {
- // Otherwise, bitcast the dest pointer (for aggregates).
- DestField = Builder.CreateBitCast(DestField,
- PointerType::getUnqual(EltVal->getType()));
- }
- new StoreInst(EltVal, DestField, SI);
- }
-
- } else {
- ArrayType *ATy = cast<ArrayType>(AllocaEltTy);
- Type *ArrayEltTy = ATy->getElementType();
- uint64_t ElementOffset = DL.getTypeAllocSizeInBits(ArrayEltTy);
- uint64_t ElementSizeBits = DL.getTypeSizeInBits(ArrayEltTy);
-
- uint64_t Shift;
-
- if (DL.isBigEndian())
- Shift = AllocaSizeBits-ElementOffset;
- else
- Shift = 0;
-
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- // Ignore zero sized fields like {}, they obviously contain no data.
- if (ElementSizeBits == 0) continue;
-
- Value *EltVal = SrcVal;
- if (Shift) {
- Value *ShiftVal = ConstantInt::get(EltVal->getType(), Shift);
- EltVal = Builder.CreateLShr(EltVal, ShiftVal, "sroa.store.elt");
- }
-
- // Truncate down to an integer of the right size.
- if (ElementSizeBits != AllocaSizeBits)
- EltVal = Builder.CreateTrunc(EltVal,
- IntegerType::get(SI->getContext(),
- ElementSizeBits));
- Value *DestField = NewElts[i];
- if (EltVal->getType() == ArrayEltTy) {
- // Storing to an integer field of this size, just do it.
- } else if (ArrayEltTy->isFloatingPointTy() ||
- ArrayEltTy->isVectorTy()) {
- // Bitcast to the right element type (for fp/vector values).
- EltVal = Builder.CreateBitCast(EltVal, ArrayEltTy);
- } else {
- // Otherwise, bitcast the dest pointer (for aggregates).
- DestField = Builder.CreateBitCast(DestField,
- PointerType::getUnqual(EltVal->getType()));
- }
- new StoreInst(EltVal, DestField, SI);
-
- if (DL.isBigEndian())
- Shift -= ElementOffset;
- else
- Shift += ElementOffset;
- }
- }
-
- DeadInsts.push_back(SI);
-}
-
-/// RewriteLoadUserOfWholeAlloca - We found a load of the entire allocation to
-/// an integer. Load the individual pieces to form the aggregate value.
-void
-SROA::RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocaInst *AI,
- SmallVectorImpl<AllocaInst *> &NewElts) {
- // Extract each element out of the NewElts according to its structure offset
- // and form the result value.
- Type *AllocaEltTy = AI->getAllocatedType();
- const DataLayout &DL = LI->getModule()->getDataLayout();
- uint64_t AllocaSizeBits = DL.getTypeAllocSizeInBits(AllocaEltTy);
-
- DEBUG(dbgs() << "PROMOTING LOAD OF WHOLE ALLOCA: " << *AI << '\n' << *LI
- << '\n');
-
- // There are two forms here: AI could be an array or struct. Both cases
- // have different ways to compute the element offset.
- const StructLayout *Layout = nullptr;
- uint64_t ArrayEltBitOffset = 0;
- if (StructType *EltSTy = dyn_cast<StructType>(AllocaEltTy)) {
- Layout = DL.getStructLayout(EltSTy);
- } else {
- Type *ArrayEltTy = cast<ArrayType>(AllocaEltTy)->getElementType();
- ArrayEltBitOffset = DL.getTypeAllocSizeInBits(ArrayEltTy);
- }
-
- Value *ResultVal =
- Constant::getNullValue(IntegerType::get(LI->getContext(), AllocaSizeBits));
-
- for (unsigned i = 0, e = NewElts.size(); i != e; ++i) {
- // Load the value from the alloca. If the NewElt is an aggregate, cast
- // the pointer to an integer of the same size before doing the load.
- Value *SrcField = NewElts[i];
- Type *FieldTy =
- cast<PointerType>(SrcField->getType())->getElementType();
- uint64_t FieldSizeBits = DL.getTypeSizeInBits(FieldTy);
-
- // Ignore zero sized fields like {}, they obviously contain no data.
- if (FieldSizeBits == 0) continue;
-
- IntegerType *FieldIntTy = IntegerType::get(LI->getContext(),
- FieldSizeBits);
- if (!FieldTy->isIntegerTy() && !FieldTy->isFloatingPointTy() &&
- !FieldTy->isVectorTy())
- SrcField = new BitCastInst(SrcField,
- PointerType::getUnqual(FieldIntTy),
- "", LI);
- SrcField = new LoadInst(SrcField, "sroa.load.elt", LI);
-
- // If SrcField is a fp or vector of the right size but that isn't an
- // integer type, bitcast to an integer so we can shift it.
- if (SrcField->getType() != FieldIntTy)
- SrcField = new BitCastInst(SrcField, FieldIntTy, "", LI);
-
- // Zero extend the field to be the same size as the final alloca so that
- // we can shift and insert it.
- if (SrcField->getType() != ResultVal->getType())
- SrcField = new ZExtInst(SrcField, ResultVal->getType(), "", LI);
-
- // Determine the number of bits to shift SrcField.
- uint64_t Shift;
- if (Layout) // Struct case.
- Shift = Layout->getElementOffsetInBits(i);
- else // Array case.
- Shift = i*ArrayEltBitOffset;
-
- if (DL.isBigEndian())
- Shift = AllocaSizeBits-Shift-FieldIntTy->getBitWidth();
-
- if (Shift) {
- Value *ShiftVal = ConstantInt::get(SrcField->getType(), Shift);
- SrcField = BinaryOperator::CreateShl(SrcField, ShiftVal, "", LI);
- }
-
- // Don't create an 'or x, 0' on the first iteration.
- if (!isa<Constant>(ResultVal) ||
- !cast<Constant>(ResultVal)->isNullValue())
- ResultVal = BinaryOperator::CreateOr(SrcField, ResultVal, "", LI);
- else
- ResultVal = SrcField;
- }
-
- // Handle tail padding by truncating the result
- if (DL.getTypeSizeInBits(LI->getType()) != AllocaSizeBits)
- ResultVal = new TruncInst(ResultVal, LI->getType(), "", LI);
-
- LI->replaceAllUsesWith(ResultVal);
- DeadInsts.push_back(LI);
-}
-
-/// HasPadding - Return true if the specified type has any structure or
-/// alignment padding in between the elements that would be split apart
-/// by SROA; return false otherwise.
-static bool HasPadding(Type *Ty, const DataLayout &DL) {
- if (ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
- Ty = ATy->getElementType();
- return DL.getTypeSizeInBits(Ty) != DL.getTypeAllocSizeInBits(Ty);
- }
-
- // SROA currently handles only Arrays and Structs.
- StructType *STy = cast<StructType>(Ty);
- const StructLayout *SL = DL.getStructLayout(STy);
- unsigned PrevFieldBitOffset = 0;
- for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
- unsigned FieldBitOffset = SL->getElementOffsetInBits(i);
-
- // Check to see if there is any padding between this element and the
- // previous one.
- if (i) {
- unsigned PrevFieldEnd =
- PrevFieldBitOffset+DL.getTypeSizeInBits(STy->getElementType(i-1));
- if (PrevFieldEnd < FieldBitOffset)
- return true;
- }
- PrevFieldBitOffset = FieldBitOffset;
- }
- // Check for tail padding.
- if (unsigned EltCount = STy->getNumElements()) {
- unsigned PrevFieldEnd = PrevFieldBitOffset +
- DL.getTypeSizeInBits(STy->getElementType(EltCount-1));
- if (PrevFieldEnd < SL->getSizeInBits())
- return true;
- }
- return false;
-}
-
-/// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of
-/// an aggregate can be broken down into elements. Return 0 if not, 3 if safe,
-/// or 1 if safe after canonicalization has been performed.
-bool SROA::isSafeAllocaToScalarRepl(AllocaInst *AI) {
- // Loop over the use list of the alloca. We can only transform it if all of
- // the users are safe to transform.
- AllocaInfo Info(AI);
-
- isSafeForScalarRepl(AI, 0, Info);
- if (Info.isUnsafe) {
- DEBUG(dbgs() << "Cannot transform: " << *AI << '\n');
- return false;
- }
-
- const DataLayout &DL = AI->getModule()->getDataLayout();
-
- // Okay, we know all the users are promotable. If the aggregate is a memcpy
- // source and destination, we have to be careful. In particular, the memcpy
- // could be moving around elements that live in structure padding of the LLVM
- // types, but may actually be used. In these cases, we refuse to promote the
- // struct.
- if (Info.isMemCpySrc && Info.isMemCpyDst &&
- HasPadding(AI->getAllocatedType(), DL))
- return false;
-
- // If the alloca never has an access to just *part* of it, but is accessed
- // via loads and stores, then we should use ConvertToScalarInfo to promote
- // the alloca instead of promoting each piece at a time and inserting fission
- // and fusion code.
- if (!Info.hasSubelementAccess && Info.hasALoadOrStore) {
- // If the struct/array just has one element, use basic SRoA.
- if (StructType *ST = dyn_cast<StructType>(AI->getAllocatedType())) {
- if (ST->getNumElements() > 1) return false;
- } else {
- if (cast<ArrayType>(AI->getAllocatedType())->getNumElements() > 1)
- return false;
- }
- }
-
- return true;
-}
diff --git a/gnu/llvm/lib/Transforms/Utils/Makefile b/gnu/llvm/lib/Transforms/Utils/Makefile
deleted file mode 100644
index d1e9336d67f..00000000000
--- a/gnu/llvm/lib/Transforms/Utils/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/Utils/Makefile -----------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMTransformUtils
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-
diff --git a/gnu/llvm/lib/Transforms/Vectorize/Makefile b/gnu/llvm/lib/Transforms/Vectorize/Makefile
deleted file mode 100644
index 86c36585f23..00000000000
--- a/gnu/llvm/lib/Transforms/Vectorize/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-##===- lib/Transforms/Vectorize/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LIBRARYNAME = LLVMVectorize
-BUILD_ARCHIVE = 1
-
-include $(LEVEL)/Makefile.common
-