| //===- bolt/Utils/Utils.cpp - Common helper functions ---------------------===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Common helper functions. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "bolt/Utils/Utils.h" |
| #include "llvm/BinaryFormat/Dwarf.h" |
| #include "llvm/MC/MCDwarf.h" |
| #include "llvm/Support/LEB128.h" |
| #include "llvm/Support/raw_ostream.h" |
| |
| namespace llvm { |
| namespace bolt { |
| |
| void report_error(StringRef Message, std::error_code EC) { |
| assert(EC); |
| errs() << "BOLT-ERROR: '" << Message << "': " << EC.message() << ".\n"; |
| exit(1); |
| } |
| |
| void report_error(StringRef Message, Error E) { |
| assert(E); |
| errs() << "BOLT-ERROR: '" << Message << "': " << toString(std::move(E)) |
| << ".\n"; |
| exit(1); |
| } |
| |
| void check_error(std::error_code EC, StringRef Message) { |
| if (!EC) |
| return; |
| report_error(Message, EC); |
| } |
| |
| void check_error(Error E, Twine Message) { |
| if (!E) |
| return; |
| handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EIB) { |
| llvm::errs() << "BOLT-ERROR: '" << Message << "': " << EIB.message() |
| << '\n'; |
| exit(1); |
| }); |
| } |
| |
| std::string getEscapedName(const StringRef &Name) { |
| std::string Output = Name.str(); |
| for (size_t I = 0; I < Output.size(); ++I) |
| if (Output[I] == ' ' || Output[I] == '\\') |
| Output.insert(I++, 1, '\\'); |
| |
| return Output; |
| } |
| |
| std::string getUnescapedName(const StringRef &Name) { |
| std::string Output = Name.str(); |
| for (size_t I = 0; I < Output.size(); ++I) |
| if (Output[I] == '\\') |
| Output.erase(I++, 1); |
| |
| return Output; |
| } |
| |
| std::optional<StringRef> getCommonName(const StringRef Name, bool KeepSuffix, |
| ArrayRef<StringRef> Suffixes) { |
| for (StringRef Suffix : Suffixes) { |
| size_t LTOSuffixPos = Name.find(Suffix); |
| if (LTOSuffixPos != StringRef::npos) |
| return Name.substr(0, LTOSuffixPos + (KeepSuffix ? Suffix.size() : 0)); |
| } |
| return std::nullopt; |
| } |
| |
| std::optional<StringRef> getLTOCommonName(const StringRef Name) { |
| return getCommonName(Name, true, |
| {".__uniq.", ".lto_priv.", ".constprop.", ".llvm."}); |
| } |
| |
| std::optional<uint8_t> readDWARFExpressionTargetReg(StringRef ExprBytes) { |
| uint8_t Opcode = ExprBytes[0]; |
| if (Opcode == dwarf::DW_CFA_def_cfa_expression) |
| return std::nullopt; |
| assert((Opcode == dwarf::DW_CFA_expression || |
| Opcode == dwarf::DW_CFA_val_expression) && |
| "invalid DWARF expression CFI"); |
| assert(ExprBytes.size() > 1 && "DWARF expression CFI is too short"); |
| const uint8_t *const Start = |
| reinterpret_cast<const uint8_t *>(ExprBytes.drop_front(1).data()); |
| const uint8_t *const End = |
| reinterpret_cast<const uint8_t *>(Start + ExprBytes.size() - 1); |
| uint8_t Reg = decodeULEB128(Start, nullptr, End); |
| return Reg; |
| } |
| |
| } // namespace bolt |
| |
| bool operator==(const llvm::MCCFIInstruction &L, |
| const llvm::MCCFIInstruction &R) { |
| if (L.getOperation() != R.getOperation()) |
| return false; |
| switch (L.getOperation()) { |
| case MCCFIInstruction::OpRestore: |
| case MCCFIInstruction::OpSameValue: |
| case MCCFIInstruction::OpUndefined: |
| case MCCFIInstruction::OpDefCfaRegister: |
| return L.getRegister() == R.getRegister(); |
| case MCCFIInstruction::OpRegister: |
| return L.getRegister() == R.getRegister() && |
| L.getRegister2() == R.getRegister2(); |
| case MCCFIInstruction::OpOffset: |
| case MCCFIInstruction::OpRelOffset: |
| case MCCFIInstruction::OpDefCfa: |
| return L.getRegister() == R.getRegister() && L.getOffset() == R.getOffset(); |
| case MCCFIInstruction::OpEscape: |
| return L.getValues() == R.getValues(); |
| case MCCFIInstruction::OpRememberState: |
| case MCCFIInstruction::OpRestoreState: |
| return true; |
| case MCCFIInstruction::OpDefCfaOffset: |
| case MCCFIInstruction::OpAdjustCfaOffset: |
| return L.getOffset() == R.getOffset(); |
| default: |
| return false; |
| } |
| } |
| |
| } // namespace llvm |