summaryrefslogtreecommitdiff
path: root/gnu/llvm
diff options
context:
space:
mode:
authorPatrick Wildt <patrick@cvs.openbsd.org>2017-01-14 19:56:06 +0000
committerPatrick Wildt <patrick@cvs.openbsd.org>2017-01-14 19:56:06 +0000
commit58d2a1455eaf2a25cbbbfd698204928abfcc2ab8 (patch)
tree76057e4ec1b75d230181ddb6c54b4eff5aca6cd6 /gnu/llvm
parentf9281bea671e07297b2f4b4c82b3e0f876fae560 (diff)
Import LLVM 3.9.1 including clang and lld.
Diffstat (limited to 'gnu/llvm')
-rw-r--r--gnu/llvm/include/llvm/Support/CodeGenCWrappers.h18
-rw-r--r--gnu/llvm/include/llvm/Transforms/GCOVProfiler.h2
-rw-r--r--gnu/llvm/include/llvm/Transforms/InstrProfiling.h59
-rw-r--r--gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h43
-rw-r--r--gnu/llvm/include/llvm/Transforms/SampleProfile.h21
-rw-r--r--gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h2
-rw-r--r--gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp102
-rw-r--r--gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp13
-rw-r--r--gnu/llvm/tools/lld/ELF/Strings.cpp82
-rw-r--r--gnu/llvm/tools/lld/ELF/Strings.h64
10 files changed, 159 insertions, 247 deletions
diff --git a/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h b/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h
index 47971e80cef..6db4433a435 100644
--- a/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h
+++ b/gnu/llvm/include/llvm/Support/CodeGenCWrappers.h
@@ -17,20 +17,17 @@
#define LLVM_SUPPORT_CODEGENCWRAPPERS_H
#include "llvm-c/TargetMachine.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/ErrorHandling.h"
namespace llvm {
-inline Optional<CodeModel::Model> unwrap(LLVMCodeModel Model, bool &JIT) {
- JIT = false;
+inline CodeModel::Model unwrap(LLVMCodeModel Model) {
switch (Model) {
- case LLVMCodeModelJITDefault:
- JIT = true;
- LLVM_FALLTHROUGH;
case LLVMCodeModelDefault:
- return None;
+ return CodeModel::Default;
+ case LLVMCodeModelJITDefault:
+ return CodeModel::JITDefault;
case LLVMCodeModelSmall:
return CodeModel::Small;
case LLVMCodeModelKernel:
@@ -40,11 +37,15 @@ inline Optional<CodeModel::Model> unwrap(LLVMCodeModel Model, bool &JIT) {
case LLVMCodeModelLarge:
return CodeModel::Large;
}
- return CodeModel::Small;
+ return CodeModel::Default;
}
inline LLVMCodeModel wrap(CodeModel::Model Model) {
switch (Model) {
+ case CodeModel::Default:
+ return LLVMCodeModelDefault;
+ case CodeModel::JITDefault:
+ return LLVMCodeModelJITDefault;
case CodeModel::Small:
return LLVMCodeModelSmall;
case CodeModel::Kernel:
@@ -60,3 +61,4 @@ inline LLVMCodeModel wrap(CodeModel::Model Model) {
} // end llvm namespace
#endif
+
diff --git a/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h b/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h
index 66bd75c88e2..f6521901a33 100644
--- a/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h
+++ b/gnu/llvm/include/llvm/Transforms/GCOVProfiler.h
@@ -21,7 +21,7 @@ namespace llvm {
class GCOVProfilerPass : public PassInfoMixin<GCOVProfilerPass> {
public:
GCOVProfilerPass(const GCOVOptions &Options = GCOVOptions::getDefault()) : GCOVOpts(Options) { }
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
private:
GCOVOptions GCOVOpts;
diff --git a/gnu/llvm/include/llvm/Transforms/InstrProfiling.h b/gnu/llvm/include/llvm/Transforms/InstrProfiling.h
index 0fe6ad5eeac..9ac6d63b96a 100644
--- a/gnu/llvm/include/llvm/Transforms/InstrProfiling.h
+++ b/gnu/llvm/include/llvm/Transforms/InstrProfiling.h
@@ -1,4 +1,4 @@
-//===- Transforms/InstrProfiling.h - Instrumentation passes -----*- C++ -*-===//
+//===- Transforms/InstrProfiling.h - Instrumentation passes ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,72 +14,54 @@
#ifndef LLVM_TRANSFORMS_INSTRPROFILING_H
#define LLVM_TRANSFORMS_INSTRPROFILING_H
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/StringRef.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PassManager.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Transforms/Instrumentation.h"
-#include <cstddef>
-#include <cstdint>
-#include <cstring>
-#include <vector>
namespace llvm {
-class TargetLibraryInfo;
-using LoadStorePair = std::pair<Instruction *, Instruction *>;
-
-/// Instrumentation based profiling lowering pass. This pass lowers
+/// Instrumenation based profiling lowering pass. This pass lowers
/// the profile instrumented code generated by FE or the IR based
/// instrumentation pass.
class InstrProfiling : public PassInfoMixin<InstrProfiling> {
public:
- InstrProfiling() = default;
+ InstrProfiling() {}
InstrProfiling(const InstrProfOptions &Options) : Options(Options) {}
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
- bool run(Module &M, const TargetLibraryInfo &TLI);
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
+ bool run(Module &M);
private:
InstrProfOptions Options;
Module *M;
- Triple TT;
- const TargetLibraryInfo *TLI;
struct PerFunctionProfileData {
uint32_t NumValueSites[IPVK_Last + 1];
- GlobalVariable *RegionCounters = nullptr;
- GlobalVariable *DataVar = nullptr;
-
- PerFunctionProfileData() {
+ GlobalVariable *RegionCounters;
+ GlobalVariable *DataVar;
+ PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) {
memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last + 1));
}
};
DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
- std::vector<GlobalValue *> UsedVars;
+ std::vector<Value *> UsedVars;
std::vector<GlobalVariable *> ReferencedNames;
GlobalVariable *NamesVar;
size_t NamesSize;
- // vector of counter load/store pairs to be register promoted.
- std::vector<LoadStorePair> PromotionCandidates;
+ bool isMachO() const;
- // The start value of precise value profile range for memory intrinsic sizes.
- int64_t MemOPSizeRangeStart;
- // The end value of precise value profile range for memory intrinsic sizes.
- int64_t MemOPSizeRangeLast;
+ /// Get the section name for the counter variables.
+ StringRef getCountersSection() const;
- int64_t TotalCountersPromoted = 0;
+ /// Get the section name for the name variables.
+ StringRef getNameSection() const;
- /// Lower instrumentation intrinsics in the function. Returns true if there
- /// any lowering.
- bool lowerIntrinsics(Function *F);
+ /// Get the section name for the profile data variables.
+ StringRef getDataSection() const;
- /// Register-promote counter loads and stores in loops.
- void promoteCounterLoadStores(Function *F);
-
- /// Returns true if profile counter update register promotion is enabled.
- bool isCounterPromotionEnabled() const;
+ /// Get the section name for the coverage mapping data.
+ StringRef getCoverageSection() const;
/// Count the number of instrumented value sites for the function.
void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins);
@@ -119,6 +101,5 @@ private:
void emitInitialization();
};
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_INSTRPROFILING_H
+} // End llvm namespace
+#endif
diff --git a/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h b/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h
index c2cc76c422d..f6b5639e5aa 100644
--- a/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h
+++ b/gnu/llvm/include/llvm/Transforms/PGOInstrumentation.h
@@ -1,4 +1,4 @@
-//===- Transforms/PGOInstrumentation.h - PGO gen/use passes -----*- C++ -*-===//
+//===- Transforms/PGOInstrumentation.h - PGO gen/use passes ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,40 +6,31 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
/// \file
/// This file provides the interface for IR based instrumentation passes (
/// (profile-gen, and profile-use).
-//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
#define LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/PassManager.h"
-#include <cstdint>
-#include <string>
+#include "llvm/Transforms/Instrumentation.h"
namespace llvm {
-class Function;
-class Instruction;
-class Module;
-
/// The instrumentation (profile-instr-gen) pass for IR based PGO.
class PGOInstrumentationGen : public PassInfoMixin<PGOInstrumentationGen> {
public:
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
};
/// The profile annotation (profile-instr-use) pass for IR based PGO.
class PGOInstrumentationUse : public PassInfoMixin<PGOInstrumentationUse> {
public:
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
PGOInstrumentationUse(std::string Filename = "");
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-
private:
std::string ProfileFileName;
};
@@ -47,29 +38,11 @@ private:
/// The indirect function call promotion pass.
class PGOIndirectCallPromotion : public PassInfoMixin<PGOIndirectCallPromotion> {
public:
- PGOIndirectCallPromotion(bool IsInLTO = false, bool SamplePGO = false)
- : InLTO(IsInLTO), SamplePGO(SamplePGO) {}
-
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-
+ PGOIndirectCallPromotion(bool IsInLTO = false) : InLTO(IsInLTO) {}
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
private:
bool InLTO;
- bool SamplePGO;
};
-/// The profile size based optimization pass for memory intrinsics.
-class PGOMemOPSizeOpt : public PassInfoMixin<PGOMemOPSizeOpt> {
-public:
- PGOMemOPSizeOpt() = default;
-
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-void setProfMetadata(Module *M, Instruction *TI, ArrayRef<uint64_t> EdgeCounts,
- uint64_t MaxCount);
-
-void setIrrLoopHeaderMetadata(Module *M, Instruction *TI, uint64_t Count);
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_PGOINSTRUMENTATION_H
+} // End llvm namespace
+#endif
diff --git a/gnu/llvm/include/llvm/Transforms/SampleProfile.h b/gnu/llvm/include/llvm/Transforms/SampleProfile.h
index f5a8590e14a..0fdfa2f85e5 100644
--- a/gnu/llvm/include/llvm/Transforms/SampleProfile.h
+++ b/gnu/llvm/include/llvm/Transforms/SampleProfile.h
@@ -1,4 +1,4 @@
-//===- Transforms/SampleProfile.h - SamplePGO pass --------------*- C++ -*-===//
+//===- Transforms/SampleProfile.h - SamplePGO pass--------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -6,35 +6,22 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
-//
/// \file
/// This file provides the interface for the sampled PGO loader pass.
-//
//===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SAMPLEPROFILE_H
#define LLVM_TRANSFORMS_SAMPLEPROFILE_H
#include "llvm/IR/PassManager.h"
-#include <string>
namespace llvm {
-class Module;
-
/// The sample profiler data loader pass.
class SampleProfileLoaderPass : public PassInfoMixin<SampleProfileLoaderPass> {
public:
- SampleProfileLoaderPass(std::string File = "", bool IsThinLTOPreLink = false)
- : ProfileFileName(File), IsThinLTOPreLink(IsThinLTOPreLink) {}
-
- PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-
-private:
- std::string ProfileFileName;
- bool IsThinLTOPreLink;
+ PreservedAnalyses run(Module &M, AnalysisManager<Module> &AM);
};
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_SAMPLEPROFILE_H
+} // End llvm namespace
+#endif
diff --git a/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h b/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h
index 3f838611626..ea491dc5058 100644
--- a/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h
+++ b/gnu/llvm/include/llvm/Transforms/Utils/SimplifyInstructions.h
@@ -24,7 +24,7 @@ namespace llvm {
/// This pass removes redundant instructions.
class InstSimplifierPass : public PassInfoMixin<InstSimplifierPass> {
public:
- PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);
};
} // end namespace llvm
diff --git a/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp b/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
index da67c1bcea9..10022ba6068 100644
--- a/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
+++ b/gnu/llvm/lib/Target/Mips/MipsHazardSchedule.cpp
@@ -1,4 +1,4 @@
-//===- MipsHazardSchedule.cpp - Workaround pipeline hazards ---------------===//
+//===-- MipsHazardSchedule.cpp - Workaround pipeline hazards --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
/// \file
-/// This pass is used to workaround certain pipeline hazards. For now, this
-/// covers compact branch hazards. In future this pass can be extended to other
-/// pipeline hazards, such as various MIPS1 hazards, processor errata that
-/// require instruction reorganization, etc.
+/// This pass is used to workaround certain pipeline hazards. For now, this covers
+/// compact branch hazards. In future this pass can be extended to other pipeline
+/// hazards, such as various MIPS1 hazards, processor errata that require
+/// instruction reorganization, etc.
///
/// This pass has to run after the delay slot filler as that pass can introduce
/// pipeline hazards, hence the existing hazard recognizer is not suitable.
@@ -18,8 +18,8 @@
/// Hazards handled: forbidden slots for MIPSR6.
///
/// A forbidden slot hazard occurs when a compact branch instruction is executed
-/// and the adjacent instruction in memory is a control transfer instruction
-/// such as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE.
+/// and the adjacent instruction in memory is a control transfer instruction such
+/// as a branch or jump, ERET, ERETNC, DERET, WAIT and PAUSE.
///
/// For example:
///
@@ -36,7 +36,7 @@
///
/// A) A previous pass has created a compact branch directly.
/// B) Transforming a delay slot branch into compact branch. This case can be
-/// difficult to process as lookahead for hazards is insufficient, as
+/// difficult to process as lookahead for hazards is insufficent, as
/// backwards delay slot fillling can also produce hazards in previously
/// processed instuctions.
///
@@ -44,15 +44,15 @@
#include "Mips.h"
#include "MipsInstrInfo.h"
-#include "MipsSubtarget.h"
+#include "MipsSEInstrInfo.h"
+#include "MipsTargetMachine.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include <algorithm>
-#include <iterator>
-#include <utility>
+#include "llvm/IR/Function.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
@@ -62,73 +62,49 @@ STATISTIC(NumInsertedNops, "Number of nops inserted");
namespace {
-using Iter = MachineBasicBlock::iterator;
-using ReverseIter = MachineBasicBlock::reverse_iterator;
+typedef MachineBasicBlock::iterator Iter;
+typedef MachineBasicBlock::reverse_iterator ReverseIter;
class MipsHazardSchedule : public MachineFunctionPass {
+
public:
MipsHazardSchedule() : MachineFunctionPass(ID) {}
- StringRef getPassName() const override { return "Mips Hazard Schedule"; }
+ const char *getPassName() const override { return "Mips Hazard Schedule"; }
bool runOnMachineFunction(MachineFunction &F) override;
MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set(
- MachineFunctionProperties::Property::NoVRegs);
+ MachineFunctionProperties::Property::AllVRegsAllocated);
}
private:
static char ID;
};
-} // end of anonymous namespace
-
char MipsHazardSchedule::ID = 0;
+} // end of anonymous namespace
/// Returns a pass that clears pipeline hazards.
FunctionPass *llvm::createMipsHazardSchedule() {
return new MipsHazardSchedule();
}
-// Find the next real instruction from the current position in current basic
-// block.
-static Iter getNextMachineInstrInBB(Iter Position) {
+// Find the next real instruction from the current position.
+static Iter getNextMachineInstr(Iter Position) {
Iter I = Position, E = Position->getParent()->end();
- I = std::find_if_not(I, E,
- [](const Iter &Insn) { return Insn->isTransient(); });
-
+ I = std::find_if_not(I, E, [](const Iter &Insn) { return Insn->isTransient(); });
+ assert(I != E);
return I;
}
-// Find the next real instruction from the current position, looking through
-// basic block boundaries.
-static std::pair<Iter, bool> getNextMachineInstr(Iter Position, MachineBasicBlock * Parent) {
- if (Position == Parent->end()) {
- do {
- MachineBasicBlock *Succ = Parent->getNextNode();
- if (Succ != nullptr && Parent->isSuccessor(Succ)) {
- Position = Succ->begin();
- Parent = Succ;
- } else {
- return std::make_pair(Position, true);
- }
- } while (Parent->empty());
- }
-
- Iter Instr = getNextMachineInstrInBB(Position);
- if (Instr == Parent->end()) {
- return getNextMachineInstr(Instr, Parent);
- }
- return std::make_pair(Instr, false);
-}
-
bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) {
const MipsSubtarget *STI =
&static_cast<const MipsSubtarget &>(MF.getSubtarget());
- // Forbidden slot hazards are only defined for MIPSR6 but not microMIPSR6.
+ // Forbidden slot hazards are only defined for MIPSR6.
if (!STI->hasMips32r6() || STI->inMicroMipsMode())
return false;
@@ -142,19 +118,27 @@ bool MipsHazardSchedule::runOnMachineFunction(MachineFunction &MF) {
if (!TII->HasForbiddenSlot(*I))
continue;
- Iter Inst;
- bool LastInstInFunction =
- std::next(I) == FI->end() && std::next(FI) == MF.end();
- if (!LastInstInFunction) {
- std::pair<Iter, bool> Res = getNextMachineInstr(std::next(I), &*FI);
- LastInstInFunction |= Res.second;
- Inst = Res.first;
+ bool InsertNop = false;
+ // Next instruction in the basic block.
+ if (std::next(I) != FI->end() &&
+ !TII->SafeInForbiddenSlot(*getNextMachineInstr(std::next(I)))) {
+ InsertNop = true;
+ } else {
+ // Next instruction in the physical successor basic block.
+ for (auto *Succ : FI->successors()) {
+ if (FI->isLayoutSuccessor(Succ) &&
+ getNextMachineInstr(Succ->begin()) != Succ->end() &&
+ !TII->SafeInForbiddenSlot(*getNextMachineInstr(Succ->begin()))) {
+ InsertNop = true;
+ break;
+ }
+ }
}
- if (LastInstInFunction || !TII->SafeInForbiddenSlot(*Inst)) {
+ if (InsertNop) {
Changed = true;
- MIBundleBuilder(&*I)
- .append(BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP)));
+ MIBundleBuilder(&*I).append(
+ BuildMI(MF, I->getDebugLoc(), TII->get(Mips::NOP)));
NumInsertedNops++;
}
}
diff --git a/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp b/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp
index 2921f3ead50..012f63a48ad 100644
--- a/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp
+++ b/gnu/llvm/tools/clang/unittests/AST/PostOrderASTVisitor.cpp
@@ -34,11 +34,6 @@ namespace {
bool shouldTraversePostOrder() const { return VisitPostOrder; }
- bool VisitUnaryOperator(UnaryOperator *Op) {
- VisitedNodes.push_back(Op->getOpcodeStr(Op->getOpcode()));
- return true;
- }
-
bool VisitBinaryOperator(BinaryOperator *Op) {
VisitedNodes.push_back(Op->getOpcodeStr());
return true;
@@ -81,7 +76,7 @@ TEST(RecursiveASTVisitor, PostOrderTraversal) {
auto ASTUnit = tooling::buildASTFromCode(
"class A {"
" class B {"
- " int foo() { while(4) { int i = 9; int j = -5; } return (1 + 3) + 2; }"
+ " int foo() { while(4) { int i = 9; } return (1 + 3) + 2; }"
" };"
"};"
);
@@ -91,9 +86,9 @@ TEST(RecursiveASTVisitor, PostOrderTraversal) {
RecordingVisitor Visitor(true);
Visitor.TraverseTranslationUnitDecl(TU);
- std::vector<std::string> expected = {"4", "9", "i", "5", "-",
- "j", "1", "3", "+", "2",
- "+", "return", "A::B::foo", "A::B", "A"};
+ std::vector<std::string> expected = {
+ "4", "9", "i", "1", "3", "+", "2", "+", "return", "A::B::foo", "A::B", "A"
+ };
// Compare the list of actually visited nodes
// with the expected list of visited nodes.
ASSERT_EQ(expected.size(), Visitor.VisitedNodes.size());
diff --git a/gnu/llvm/tools/lld/ELF/Strings.cpp b/gnu/llvm/tools/lld/ELF/Strings.cpp
index 0ef33a14bc3..0c21e8819d6 100644
--- a/gnu/llvm/tools/lld/ELF/Strings.cpp
+++ b/gnu/llvm/tools/lld/ELF/Strings.cpp
@@ -8,36 +8,44 @@
//===----------------------------------------------------------------------===//
#include "Strings.h"
-#include "Config.h"
-#include "lld/Common/ErrorHandler.h"
-#include "llvm/ADT/ArrayRef.h"
+#include "Error.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/Demangle/Demangle.h"
+#include "llvm/Config/config.h"
#include <algorithm>
-#include <cstring>
+
+#ifdef HAVE_CXXABI_H
+#include <cxxabi.h>
+#endif
using namespace llvm;
using namespace lld;
using namespace lld::elf;
-StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
- for (StringRef S : Pat) {
- Expected<GlobPattern> Pat = GlobPattern::create(S);
- if (!Pat)
- error(toString(Pat.takeError()));
- else
- Patterns.push_back(*Pat);
+// Returns true if S matches T. S can contain glob meta-characters.
+// The asterisk ('*') matches zero or more characters, and the question
+// mark ('?') matches one character.
+bool elf::globMatch(StringRef S, StringRef T) {
+ for (;;) {
+ if (S.empty())
+ return T.empty();
+ if (S[0] == '*') {
+ S = S.substr(1);
+ if (S.empty())
+ // Fast path. If a pattern is '*', it matches anything.
+ return true;
+ for (size_t I = 0, E = T.size(); I < E; ++I)
+ if (globMatch(S, T.substr(I)))
+ return true;
+ return false;
+ }
+ if (T.empty() || (S[0] != T[0] && S[0] != '?'))
+ return false;
+ S = S.substr(1);
+ T = T.substr(1);
}
}
-bool StringMatcher::match(StringRef S) const {
- for (const GlobPattern &Pat : Patterns)
- if (Pat.match(S))
- return true;
- return false;
-}
-
// Converts a hex string (e.g. "deadbeef") to a vector.
std::vector<uint8_t> elf::parseHex(StringRef S) {
std::vector<uint8_t> Hex;
@@ -45,7 +53,7 @@ std::vector<uint8_t> elf::parseHex(StringRef S) {
StringRef B = S.substr(0, 2);
S = S.substr(2);
uint8_t H;
- if (!to_integer(B, H, 16)) {
+ if (B.getAsInteger(16, H)) {
error("not a hexadecimal value: " + B);
return {};
}
@@ -54,9 +62,37 @@ std::vector<uint8_t> elf::parseHex(StringRef S) {
return Hex;
}
+static bool isAlpha(char C) {
+ return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
+}
+
+static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }
+
// Returns true if S is valid as a C language identifier.
bool elf::isValidCIdentifier(StringRef S) {
- return !S.empty() && (isAlpha(S[0]) || S[0] == '_') &&
- std::all_of(S.begin() + 1, S.end(),
- [](char C) { return C == '_' || isAlnum(C); });
+ return !S.empty() && isAlpha(S[0]) &&
+ std::all_of(S.begin() + 1, S.end(), isAlnum);
+}
+
+// Returns the demangled C++ symbol name for Name.
+std::string elf::demangle(StringRef Name) {
+#if !defined(HAVE_CXXABI_H)
+ return Name;
+#else
+ // __cxa_demangle can be used to demangle strings other than symbol
+ // names which do not necessarily start with "_Z". Name can be
+ // either a C or C++ symbol. Don't call __cxa_demangle if the name
+ // does not look like a C++ symbol name to avoid getting unexpected
+ // result for a C symbol that happens to match a mangled type name.
+ if (!Name.startswith("_Z"))
+ return Name;
+
+ char *Buf =
+ abi::__cxa_demangle(Name.str().c_str(), nullptr, nullptr, nullptr);
+ if (!Buf)
+ return Name;
+ std::string S(Buf);
+ free(Buf);
+ return S;
+#endif
}
diff --git a/gnu/llvm/tools/lld/ELF/Strings.h b/gnu/llvm/tools/lld/ELF/Strings.h
index 5009df65f4c..4948e9dbd56 100644
--- a/gnu/llvm/tools/lld/ELF/Strings.h
+++ b/gnu/llvm/tools/lld/ELF/Strings.h
@@ -7,69 +7,23 @@
//
//===----------------------------------------------------------------------===//
-#ifndef LLD_ELF_STRINGS_H
-#define LLD_ELF_STRINGS_H
+#ifndef LLD_COFF_STRINGS_H
+#define LLD_COFF_STRINGS_H
-#include "lld/Common/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/GlobPattern.h"
+#include "lld/Core/LLVM.h"
#include <vector>
namespace lld {
namespace elf {
-
+bool globMatch(StringRef S, StringRef T);
std::vector<uint8_t> parseHex(StringRef S);
bool isValidCIdentifier(StringRef S);
-// This is a lazy version of StringRef. String size is computed lazily
-// when it is needed. It is more efficient than StringRef to instantiate
-// if you have a string whose size is unknown.
-//
-// ELF string tables contain a lot of null-terminated strings.
-// Most of them are not necessary for the linker because they are names
-// of local symbols and the linker doesn't use local symbol names for
-// name resolution. So, we use this class to represents strings read
-// from string tables.
-class StringRefZ {
-public:
- StringRefZ() : Start(nullptr), Size(0) {}
- StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {}
-
- /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {}
-
- /*implicit*/ StringRefZ(llvm::StringRef S)
- : Start(S.data()), Size(S.size()) {}
-
- operator llvm::StringRef() const {
- if (Size == (size_t)-1)
- Size = strlen(Start);
- return {Start, Size};
- }
-
-private:
- const char *Start;
- mutable size_t Size;
-};
-
-// This class represents multiple glob patterns.
-class StringMatcher {
-public:
- StringMatcher() = default;
- explicit StringMatcher(ArrayRef<StringRef> Pat);
-
- bool match(StringRef S) const;
-
-private:
- std::vector<llvm::GlobPattern> Patterns;
-};
-
-inline ArrayRef<uint8_t> toArrayRef(StringRef S) {
- return {(const uint8_t *)S.data(), S.size()};
+// Returns a demangled C++ symbol name. If Name is not a mangled
+// name or the system does not provide __cxa_demangle function,
+// it returns an unmodified string.
+std::string demangle(StringRef Name);
+}
}
-} // namespace elf
-} // namespace lld
#endif