1 //===- bolt/Utils/Utils.cpp - Common helper functions ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // Common helper functions.
11 //===----------------------------------------------------------------------===//
13 #include "bolt/Utils/Utils.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/MC/MCDwarf.h"
16 #include "llvm/Support/LEB128.h"
17 #include "llvm/Support/raw_ostream.h"
22 void report_error(StringRef Message
, std::error_code EC
) {
24 errs() << "BOLT-ERROR: '" << Message
<< "': " << EC
.message() << ".\n";
28 void report_error(StringRef Message
, Error E
) {
30 errs() << "BOLT-ERROR: '" << Message
<< "': " << toString(std::move(E
))
35 void check_error(std::error_code EC
, StringRef Message
) {
38 report_error(Message
, EC
);
41 void check_error(Error E
, Twine Message
) {
44 handleAllErrors(std::move(E
), [&](const llvm::ErrorInfoBase
&EIB
) {
45 llvm::errs() << "BOLT-ERROR: '" << Message
<< "': " << EIB
.message()
51 std::string
getEscapedName(const StringRef
&Name
) {
52 std::string Output
= Name
.str();
53 for (size_t I
= 0; I
< Output
.size(); ++I
)
54 if (Output
[I
] == ' ' || Output
[I
] == '\\')
55 Output
.insert(I
++, 1, '\\');
60 std::string
getUnescapedName(const StringRef
&Name
) {
61 std::string Output
= Name
.str();
62 for (size_t I
= 0; I
< Output
.size(); ++I
)
63 if (Output
[I
] == '\\')
69 std::optional
<StringRef
> getLTOCommonName(const StringRef Name
) {
70 for (StringRef Suffix
: {".__uniq.", ".lto_priv.", ".constprop.", ".llvm."}) {
71 size_t LTOSuffixPos
= Name
.find(Suffix
);
72 if (LTOSuffixPos
!= StringRef::npos
)
73 return Name
.substr(0, LTOSuffixPos
+ Suffix
.size());
78 std::optional
<uint8_t> readDWARFExpressionTargetReg(StringRef ExprBytes
) {
79 uint8_t Opcode
= ExprBytes
[0];
80 if (Opcode
== dwarf::DW_CFA_def_cfa_expression
)
82 assert((Opcode
== dwarf::DW_CFA_expression
||
83 Opcode
== dwarf::DW_CFA_val_expression
) &&
84 "invalid DWARF expression CFI");
85 assert(ExprBytes
.size() > 1 && "DWARF expression CFI is too short");
86 const uint8_t *const Start
=
87 reinterpret_cast<const uint8_t *>(ExprBytes
.drop_front(1).data());
88 const uint8_t *const End
=
89 reinterpret_cast<const uint8_t *>(Start
+ ExprBytes
.size() - 1);
90 uint8_t Reg
= decodeULEB128(Start
, nullptr, End
);
96 bool operator==(const llvm::MCCFIInstruction
&L
,
97 const llvm::MCCFIInstruction
&R
) {
98 if (L
.getOperation() != R
.getOperation())
100 switch (L
.getOperation()) {
101 case MCCFIInstruction::OpRestore
:
102 case MCCFIInstruction::OpSameValue
:
103 case MCCFIInstruction::OpUndefined
:
104 case MCCFIInstruction::OpDefCfaRegister
:
105 return L
.getRegister() == R
.getRegister();
106 case MCCFIInstruction::OpRegister
:
107 return L
.getRegister() == R
.getRegister() &&
108 L
.getRegister2() == R
.getRegister2();
109 case MCCFIInstruction::OpOffset
:
110 case MCCFIInstruction::OpRelOffset
:
111 case MCCFIInstruction::OpDefCfa
:
112 return L
.getRegister() == R
.getRegister() && L
.getOffset() == R
.getOffset();
113 case MCCFIInstruction::OpEscape
:
114 return L
.getValues() == R
.getValues();
115 case MCCFIInstruction::OpRememberState
:
116 case MCCFIInstruction::OpRestoreState
:
118 case MCCFIInstruction::OpDefCfaOffset
:
119 case MCCFIInstruction::OpAdjustCfaOffset
:
120 return L
.getOffset() == R
.getOffset();