2021-12-21 10:21:41 -08:00
|
|
|
//===- bolt/Core/MCPlusBuilder.cpp - Interface for MCPlus -----------------===//
|
2018-03-09 09:45:13 -08:00
|
|
|
//
|
2021-03-15 18:04:18 -07:00
|
|
|
// 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
|
2018-03-09 09:45:13 -08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2021-12-21 10:21:41 -08:00
|
|
|
// This file implements the MCPlusBuilder class.
|
2018-03-09 09:45:13 -08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2021-10-08 11:47:10 -07:00
|
|
|
#include "bolt/Core/MCPlusBuilder.h"
|
|
|
|
#include "bolt/Core/MCPlus.h"
|
2018-03-09 09:45:13 -08:00
|
|
|
#include "llvm/MC/MCInst.h"
|
2021-10-08 11:47:10 -07:00
|
|
|
#include "llvm/MC/MCInstrAnalysis.h"
|
2018-03-09 09:45:13 -08:00
|
|
|
#include "llvm/MC/MCInstrDesc.h"
|
|
|
|
#include "llvm/MC/MCInstrInfo.h"
|
2022-02-09 08:26:30 -05:00
|
|
|
#include "llvm/MC/MCRegisterInfo.h"
|
2018-03-09 09:45:13 -08:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include <cstdint>
|
|
|
|
#include <queue>
|
|
|
|
|
|
|
|
#define DEBUG_TYPE "mcplus"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace bolt;
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
using namespace MCPlus;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2018-04-12 10:07:11 -07:00
|
|
|
bool MCPlusBuilder::equals(const MCInst &A, const MCInst &B,
|
|
|
|
CompFuncTy Comp) const {
|
|
|
|
if (A.getOpcode() != B.getOpcode())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned NumOperands = MCPlus::getNumPrimeOperands(A);
|
|
|
|
if (NumOperands != MCPlus::getNumPrimeOperands(B))
|
|
|
|
return false;
|
|
|
|
|
2021-12-20 11:07:46 -08:00
|
|
|
for (unsigned Index = 0; Index < NumOperands; ++Index)
|
2018-04-12 10:07:11 -07:00
|
|
|
if (!equals(A.getOperand(Index), B.getOperand(Index), Comp))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::equals(const MCOperand &A, const MCOperand &B,
|
|
|
|
CompFuncTy Comp) const {
|
|
|
|
if (A.isReg()) {
|
|
|
|
if (!B.isReg())
|
|
|
|
return false;
|
|
|
|
return A.getReg() == B.getReg();
|
|
|
|
} else if (A.isImm()) {
|
|
|
|
if (!B.isImm())
|
|
|
|
return false;
|
|
|
|
return A.getImm() == B.getImm();
|
2020-12-01 16:29:39 -08:00
|
|
|
} else if (A.isSFPImm()) {
|
|
|
|
if (!B.isSFPImm())
|
2018-04-12 10:07:11 -07:00
|
|
|
return false;
|
2020-12-01 16:29:39 -08:00
|
|
|
return A.getSFPImm() == B.getSFPImm();
|
|
|
|
} else if (A.isDFPImm()) {
|
|
|
|
if (!B.isDFPImm())
|
|
|
|
return false;
|
|
|
|
return A.getDFPImm() == B.getDFPImm();
|
2018-04-12 10:07:11 -07:00
|
|
|
} else if (A.isExpr()) {
|
|
|
|
if (!B.isExpr())
|
|
|
|
return false;
|
|
|
|
return equals(*A.getExpr(), *B.getExpr(), Comp);
|
|
|
|
} else {
|
|
|
|
llvm_unreachable("unexpected operand kind");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::equals(const MCExpr &A, const MCExpr &B,
|
|
|
|
CompFuncTy Comp) const {
|
|
|
|
if (A.getKind() != B.getKind())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (A.getKind()) {
|
|
|
|
case MCExpr::Constant: {
|
|
|
|
const auto &ConstA = cast<MCConstantExpr>(A);
|
|
|
|
const auto &ConstB = cast<MCConstantExpr>(B);
|
|
|
|
return ConstA.getValue() == ConstB.getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
case MCExpr::SymbolRef: {
|
|
|
|
const MCSymbolRefExpr &SymbolA = cast<MCSymbolRefExpr>(A);
|
|
|
|
const MCSymbolRefExpr &SymbolB = cast<MCSymbolRefExpr>(B);
|
|
|
|
return SymbolA.getKind() == SymbolB.getKind() &&
|
|
|
|
Comp(&SymbolA.getSymbol(), &SymbolB.getSymbol());
|
|
|
|
}
|
|
|
|
|
|
|
|
case MCExpr::Unary: {
|
|
|
|
const auto &UnaryA = cast<MCUnaryExpr>(A);
|
|
|
|
const auto &UnaryB = cast<MCUnaryExpr>(B);
|
|
|
|
return UnaryA.getOpcode() == UnaryB.getOpcode() &&
|
|
|
|
equals(*UnaryA.getSubExpr(), *UnaryB.getSubExpr(), Comp);
|
|
|
|
}
|
|
|
|
|
|
|
|
case MCExpr::Binary: {
|
|
|
|
const auto &BinaryA = cast<MCBinaryExpr>(A);
|
|
|
|
const auto &BinaryB = cast<MCBinaryExpr>(B);
|
|
|
|
return BinaryA.getOpcode() == BinaryB.getOpcode() &&
|
|
|
|
equals(*BinaryA.getLHS(), *BinaryB.getLHS(), Comp) &&
|
|
|
|
equals(*BinaryA.getRHS(), *BinaryB.getRHS(), Comp);
|
|
|
|
}
|
|
|
|
|
|
|
|
case MCExpr::Target: {
|
|
|
|
const auto &TargetExprA = cast<MCTargetExpr>(A);
|
|
|
|
const auto &TargetExprB = cast<MCTargetExpr>(B);
|
|
|
|
return equals(TargetExprA, TargetExprB, Comp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid expression kind!");
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::equals(const MCTargetExpr &A, const MCTargetExpr &B,
|
|
|
|
CompFuncTy Comp) const {
|
2021-12-14 16:52:51 -08:00
|
|
|
llvm_unreachable("target-specific expressions are unsupported");
|
2018-04-12 10:07:11 -07:00
|
|
|
}
|
|
|
|
|
2021-07-29 17:28:51 -07:00
|
|
|
void MCPlusBuilder::setTailCall(MCInst &Inst) {
|
|
|
|
assert(!hasAnnotation(Inst, MCAnnotation::kTailCall));
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kTailCall, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::isTailCall(const MCInst &Inst) const {
|
|
|
|
if (hasAnnotation(Inst, MCAnnotation::kTailCall))
|
|
|
|
return true;
|
|
|
|
if (getConditionalTailCall(Inst))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!isCall(Inst))
|
2022-12-02 23:12:38 -08:00
|
|
|
return std::nullopt;
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<int64_t> LPSym =
|
2021-04-08 00:19:26 -07:00
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!LPSym)
|
2022-12-02 23:12:38 -08:00
|
|
|
return std::nullopt;
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<int64_t> Action =
|
2021-04-08 00:19:26 -07:00
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kEHAction);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!Action)
|
2022-12-02 23:12:38 -08:00
|
|
|
return std::nullopt;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
return std::make_pair(reinterpret_cast<const MCSymbol *>(*LPSym),
|
|
|
|
static_cast<uint64_t>(*Action));
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) {
|
2018-03-09 09:45:13 -08:00
|
|
|
if (isCall(Inst)) {
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
assert(!getEHInfo(Inst));
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,
|
|
|
|
reinterpret_cast<int64_t>(LP.first));
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kEHAction,
|
|
|
|
static_cast<int64_t>(LP.second));
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-10 12:08:57 -08:00
|
|
|
bool MCPlusBuilder::updateEHInfo(MCInst &Inst, const MCLandingPad &LP) {
|
|
|
|
if (!isInvoke(Inst))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kEHLandingPad,
|
|
|
|
reinterpret_cast<int64_t>(LP.first));
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kEHAction,
|
|
|
|
static_cast<int64_t>(LP.second));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-09 09:45:13 -08:00
|
|
|
int64_t MCPlusBuilder::getGnuArgsSize(const MCInst &Inst) const {
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<int64_t> Value =
|
2021-04-08 00:19:26 -07:00
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!Value)
|
|
|
|
return -1LL;
|
|
|
|
return *Value;
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
2019-07-12 07:25:50 -07:00
|
|
|
void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize,
|
|
|
|
AllocatorIdTy AllocId) {
|
2018-03-09 09:45:13 -08:00
|
|
|
assert(GnuArgsSize >= 0 && "cannot set GNU_args_size to negative value");
|
|
|
|
assert(getGnuArgsSize(Inst) == -1LL && "GNU_args_size already set");
|
|
|
|
assert(isInvoke(Inst) && "GNU_args_size can only be set for invoke");
|
|
|
|
|
2019-07-12 07:25:50 -07:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize, AllocId);
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t MCPlusBuilder::getJumpTable(const MCInst &Inst) const {
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<int64_t> Value =
|
2021-04-08 00:19:26 -07:00
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kJumpTable);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!Value)
|
|
|
|
return 0;
|
|
|
|
return *Value;
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
2019-06-28 09:21:27 -07:00
|
|
|
uint16_t MCPlusBuilder::getJumpTableIndexReg(const MCInst &Inst) const {
|
|
|
|
return getAnnotationAs<uint16_t>(Inst, "JTIndexReg");
|
|
|
|
}
|
|
|
|
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
bool MCPlusBuilder::setJumpTable(MCInst &Inst, uint64_t Value,
|
2019-07-12 07:25:50 -07:00
|
|
|
uint16_t IndexReg, AllocatorIdTy AllocId) {
|
2018-03-09 09:45:13 -08:00
|
|
|
if (!isIndirectBranch(Inst))
|
|
|
|
return false;
|
2019-07-12 07:25:50 -07:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value, AllocId);
|
2019-08-02 11:20:13 -07:00
|
|
|
getOrCreateAnnotationAs<uint16_t>(Inst, "JTIndexReg", AllocId) = IndexReg;
|
2018-03-09 09:45:13 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-06-28 09:21:27 -07:00
|
|
|
bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) {
|
|
|
|
if (!getJumpTable(Inst))
|
|
|
|
return false;
|
|
|
|
removeAnnotation(Inst, MCAnnotation::kJumpTable);
|
|
|
|
removeAnnotation(Inst, "JTIndexReg");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<uint64_t>
|
2018-03-09 09:45:13 -08:00
|
|
|
MCPlusBuilder::getConditionalTailCall(const MCInst &Inst) const {
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<int64_t> Value =
|
2021-04-08 00:19:26 -07:00
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!Value)
|
2022-12-02 23:12:38 -08:00
|
|
|
return std::nullopt;
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
return static_cast<uint64_t>(*Value);
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
2021-12-14 16:52:51 -08:00
|
|
|
bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) {
|
2018-03-09 09:45:13 -08:00
|
|
|
if (!isConditionalBranch(Inst))
|
|
|
|
return false;
|
|
|
|
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall, Dest);
|
|
|
|
return true;
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) {
|
|
|
|
if (!getConditionalTailCall(Inst))
|
|
|
|
return false;
|
2018-03-29 18:42:06 -07:00
|
|
|
removeAnnotation(Inst, MCAnnotation::kConditionalTailCall);
|
2018-03-09 09:45:13 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-12-06 14:15:54 -08:00
|
|
|
std::optional<uint32_t> MCPlusBuilder::getOffset(const MCInst &Inst) const {
|
|
|
|
std::optional<int64_t> Value =
|
|
|
|
getAnnotationOpValue(Inst, MCAnnotation::kOffset);
|
2021-08-03 17:53:32 -07:00
|
|
|
if (!Value)
|
2022-12-02 23:12:38 -08:00
|
|
|
return std::nullopt;
|
2021-08-03 17:53:32 -07:00
|
|
|
return static_cast<uint32_t>(*Value);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t MCPlusBuilder::getOffsetWithDefault(const MCInst &Inst,
|
|
|
|
uint32_t Default) const {
|
2022-12-06 14:15:54 -08:00
|
|
|
if (std::optional<uint32_t> Offset = getOffset(Inst))
|
2021-08-03 17:53:32 -07:00
|
|
|
return *Offset;
|
|
|
|
return Default;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::setOffset(MCInst &Inst, uint32_t Offset,
|
|
|
|
AllocatorIdTy AllocatorId) {
|
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kOffset, Offset, AllocatorId);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::clearOffset(MCInst &Inst) {
|
|
|
|
if (!hasAnnotation(Inst, MCAnnotation::kOffset))
|
|
|
|
return false;
|
|
|
|
removeAnnotation(Inst, MCAnnotation::kOffset);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-29 18:42:06 -07:00
|
|
|
bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInst *AnnotationInst = getAnnotationInst(Inst);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return false;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2018-03-29 18:42:06 -07:00
|
|
|
return (bool)getAnnotationOpValue(Inst, Index);
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
2018-03-29 18:42:06 -07:00
|
|
|
bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) {
|
2021-04-08 00:19:26 -07:00
|
|
|
MCInst *AnnotationInst = getAnnotationInst(Inst);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return false;
|
|
|
|
|
2018-03-29 18:42:06 -07:00
|
|
|
for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
|
2021-04-08 00:19:26 -07:00
|
|
|
int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
|
2018-03-29 18:42:06 -07:00
|
|
|
if (extractAnnotationIndex(ImmValue) == Index) {
|
|
|
|
AnnotationInst->erase(AnnotationInst->begin() + I);
|
|
|
|
return true;
|
|
|
|
}
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
}
|
2018-03-29 18:42:06 -07:00
|
|
|
return false;
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
|
2020-12-01 16:29:39 -08:00
|
|
|
void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
|
2021-04-08 00:19:26 -07:00
|
|
|
MCInst *AnnotationInst = getAnnotationInst(Inst);
|
2019-01-31 11:23:02 -08:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return;
|
2020-12-01 16:29:39 -08:00
|
|
|
// Preserve TailCall annotation.
|
2021-07-29 17:28:51 -07:00
|
|
|
auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
|
2019-01-31 11:23:02 -08:00
|
|
|
|
2023-02-25 18:23:53 -08:00
|
|
|
removeAnnotationInst(Inst);
|
|
|
|
|
2021-07-29 17:28:51 -07:00
|
|
|
if (KeepTC && IsTC)
|
|
|
|
setTailCall(Inst);
|
2019-01-31 11:23:02 -08:00
|
|
|
}
|
|
|
|
|
2021-12-14 16:52:51 -08:00
|
|
|
void MCPlusBuilder::printAnnotations(const MCInst &Inst,
|
|
|
|
raw_ostream &OS) const {
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInst *AnnotationInst = getAnnotationInst(Inst);
|
[BOLT][Refactoring] Isolate changes to MC layer
Summary:
Changes that we made to MCInst, MCOperand, MCExpr, etc. are now all
moved into tools/llvm-bolt. That required a change to the way we handle
annotations and any extra operands for MCInst.
Any MCPlus information is now attached via an extra operand of type
MCInst with an opcode ANNOTATION_LABEL. Since this operand is MCInst, we
attach extra info as operands to this instruction. For first-level
annotations use functions to access the information, such as
getConditionalTailCall() or getEHInfo(), etc. For the rest, optional or
second-class annotations, use a general named-annotation interface such
as getAnnotationAs<uint64_t>(Inst, "Count").
I did a test on HHVM binary, and a memory consumption went down a little
bit while the runtime remained the same.
(cherry picked from FBD7405412)
2018-03-19 18:32:12 -07:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return;
|
|
|
|
|
2018-03-29 18:42:06 -07:00
|
|
|
for (unsigned I = 0; I < AnnotationInst->getNumOperands(); ++I) {
|
2021-04-08 00:19:26 -07:00
|
|
|
const int64_t Imm = AnnotationInst->getOperand(I).getImm();
|
|
|
|
const unsigned Index = extractAnnotationIndex(Imm);
|
|
|
|
const int64_t Value = extractAnnotationValue(Imm);
|
2021-12-14 16:52:51 -08:00
|
|
|
const auto *Annotation = reinterpret_cast<const MCAnnotation *>(Value);
|
2018-03-29 18:42:06 -07:00
|
|
|
if (Index >= MCAnnotation::kGeneric) {
|
2021-12-14 16:52:51 -08:00
|
|
|
OS << " # " << AnnotationNames[Index - MCAnnotation::kGeneric] << ": ";
|
2018-03-29 18:42:06 -07:00
|
|
|
Annotation->print(OS);
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
void MCPlusBuilder::getClobberedRegs(const MCInst &Inst,
|
|
|
|
BitVector &Regs) const {
|
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
|
|
|
|
Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-05-17 21:51:33 -07:00
|
|
|
for (const MCOperand &Operand : defOperands(Inst)) {
|
2019-07-24 17:54:14 -07:00
|
|
|
assert(Operand.isReg());
|
|
|
|
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/false);
|
|
|
|
}
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-12-14 16:52:51 -08:00
|
|
|
void MCPlusBuilder::getTouchedRegs(const MCInst &Inst, BitVector &Regs) const {
|
2019-07-24 17:54:14 -07:00
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
|
|
|
|
Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/false);
|
|
|
|
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
|
|
|
|
Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/false);
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
|
|
|
|
if (!Inst.getOperand(I).isReg())
|
|
|
|
continue;
|
|
|
|
Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/false);
|
|
|
|
}
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-12-14 16:52:51 -08:00
|
|
|
void MCPlusBuilder::getWrittenRegs(const MCInst &Inst, BitVector &Regs) const {
|
2019-07-24 17:54:14 -07:00
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitDef : InstInfo.implicit_defs())
|
|
|
|
Regs |= getAliases(ImplicitDef, /*OnlySmaller=*/true);
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-05-17 21:51:33 -07:00
|
|
|
for (const MCOperand &Operand : defOperands(Inst)) {
|
2019-07-24 17:54:14 -07:00
|
|
|
assert(Operand.isReg());
|
|
|
|
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
|
|
|
|
}
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {
|
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
|
|
|
|
Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
for (unsigned I = 0, E = Inst.getNumOperands(); I != E; ++I) {
|
|
|
|
if (!Inst.getOperand(I).isReg())
|
|
|
|
continue;
|
|
|
|
Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true);
|
2019-06-14 19:56:11 -07:00
|
|
|
}
|
2019-07-24 17:54:14 -07:00
|
|
|
}
|
2019-01-31 11:23:02 -08:00
|
|
|
|
2021-08-10 10:02:32 -07:00
|
|
|
void MCPlusBuilder::getSrcRegs(const MCInst &Inst, BitVector &Regs) const {
|
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (isCall(Inst)) {
|
|
|
|
BitVector CallRegs = BitVector(Regs.size(), false);
|
|
|
|
getCalleeSavedRegs(CallRegs);
|
|
|
|
CallRegs.flip();
|
|
|
|
Regs |= CallRegs;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isReturn(Inst)) {
|
|
|
|
getDefaultLiveOut(Regs);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-12-20 11:07:46 -08:00
|
|
|
if (isRep(Inst))
|
2021-08-10 10:02:32 -07:00
|
|
|
getRepRegs(Regs);
|
|
|
|
|
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
|
|
|
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses())
|
|
|
|
Regs |= getAliases(ImplicitUse, /*OnlySmaller=*/true);
|
2021-08-10 10:02:32 -07:00
|
|
|
|
2023-05-17 21:51:33 -07:00
|
|
|
for (const MCOperand &Operand : useOperands(Inst))
|
|
|
|
if (Operand.isReg())
|
|
|
|
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
|
2021-08-10 10:02:32 -07:00
|
|
|
}
|
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
bool MCPlusBuilder::hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const {
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
|
2019-07-24 17:54:14 -07:00
|
|
|
return InstInfo.hasDefOfPhysReg(MI, Reg, *RegInfo);
|
|
|
|
}
|
2019-01-31 11:23:02 -08:00
|
|
|
|
2019-07-24 17:54:14 -07:00
|
|
|
bool MCPlusBuilder::hasUseOfPhysReg(const MCInst &MI, unsigned Reg) const {
|
2021-04-08 00:19:26 -07:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
|
2019-07-24 17:54:14 -07:00
|
|
|
for (int I = InstInfo.NumDefs; I < InstInfo.NumOperands; ++I)
|
2023-05-24 07:12:53 +03:00
|
|
|
if (MI.getOperand(I).isReg() && MI.getOperand(I).getReg() &&
|
2019-07-24 17:54:14 -07:00
|
|
|
RegInfo->isSubRegisterEq(Reg, MI.getOperand(I).getReg()))
|
|
|
|
return true;
|
2023-01-24 23:11:23 +01:00
|
|
|
for (MCPhysReg ImplicitUse : InstInfo.implicit_uses()) {
|
|
|
|
if (ImplicitUse == Reg || RegInfo->isSubRegister(Reg, ImplicitUse))
|
|
|
|
return true;
|
2021-12-20 11:07:46 -08:00
|
|
|
}
|
2019-07-24 17:54:14 -07:00
|
|
|
return false;
|
|
|
|
}
|
2018-03-09 09:45:13 -08:00
|
|
|
|
2021-12-14 16:52:51 -08:00
|
|
|
const BitVector &MCPlusBuilder::getAliases(MCPhysReg Reg,
|
|
|
|
bool OnlySmaller) const {
|
2022-05-04 11:42:14 -07:00
|
|
|
if (OnlySmaller)
|
|
|
|
return SmallerAliasMap[Reg];
|
|
|
|
return AliasMap[Reg];
|
|
|
|
}
|
2022-01-28 01:04:31 +03:00
|
|
|
|
2022-05-04 11:42:14 -07:00
|
|
|
void MCPlusBuilder::initAliases() {
|
|
|
|
assert(AliasMap.size() == 0 && SmallerAliasMap.size() == 0);
|
2019-07-24 17:54:14 -07:00
|
|
|
// Build alias map
|
|
|
|
for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
|
|
|
|
BitVector BV(RegInfo->getNumRegs(), false);
|
|
|
|
BV.set(I);
|
2022-01-28 01:04:31 +03:00
|
|
|
AliasMap.emplace_back(BV);
|
|
|
|
SmallerAliasMap.emplace_back(BV);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cache all aliases for each register
|
|
|
|
for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I != E; ++I) {
|
|
|
|
for (MCRegAliasIterator AI(I, RegInfo, true); AI.isValid(); ++AI)
|
|
|
|
AliasMap[I].set(*AI);
|
2019-07-24 17:54:14 -07:00
|
|
|
}
|
2022-01-28 01:04:31 +03:00
|
|
|
|
|
|
|
// Propagate smaller alias info upwards. Skip reg 0 (mapped to NoRegister)
|
2021-12-20 11:07:46 -08:00
|
|
|
for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I < E; ++I)
|
|
|
|
for (MCSubRegIterator SI(I, RegInfo); SI.isValid(); ++SI)
|
2022-01-28 01:04:31 +03:00
|
|
|
SmallerAliasMap[I] |= SmallerAliasMap[*SI];
|
2019-07-24 17:54:14 -07:00
|
|
|
|
2020-12-01 16:29:39 -08:00
|
|
|
LLVM_DEBUG({
|
2019-07-24 17:54:14 -07:00
|
|
|
dbgs() << "Dumping reg alias table:\n";
|
|
|
|
for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
|
|
|
|
dbgs() << "Reg " << I << ": ";
|
2022-01-28 01:04:31 +03:00
|
|
|
const BitVector &BV = AliasMap[I];
|
2019-07-24 17:54:14 -07:00
|
|
|
int Idx = BV.find_first();
|
|
|
|
while (Idx != -1) {
|
|
|
|
dbgs() << Idx << " ";
|
|
|
|
Idx = BV.find_next(Idx);
|
2019-06-14 19:56:11 -07:00
|
|
|
}
|
2019-07-24 17:54:14 -07:00
|
|
|
dbgs() << "\n";
|
2018-03-09 09:45:13 -08:00
|
|
|
}
|
2019-07-24 17:54:14 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-03-14 17:26:21 -07:00
|
|
|
void MCPlusBuilder::initSizeMap() {
|
|
|
|
SizeMap.resize(RegInfo->getNumRegs());
|
2019-07-24 17:54:14 -07:00
|
|
|
// Build size map
|
2023-03-14 17:26:21 -07:00
|
|
|
for (auto RC : RegInfo->regclasses())
|
|
|
|
for (MCPhysReg Reg : RC)
|
|
|
|
SizeMap[Reg] = RC.getSizeInBits() / 8;
|
2019-07-24 17:54:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
bool MCPlusBuilder::setOperandToSymbolRef(MCInst &Inst, int OpNum,
|
|
|
|
const MCSymbol *Symbol,
|
|
|
|
int64_t Addend, MCContext *Ctx,
|
|
|
|
uint64_t RelType) const {
|
|
|
|
MCOperand Operand;
|
|
|
|
if (!Addend) {
|
|
|
|
Operand = MCOperand::createExpr(getTargetExprFor(
|
|
|
|
Inst, MCSymbolRefExpr::create(Symbol, *Ctx), *Ctx, RelType));
|
|
|
|
} else {
|
|
|
|
Operand = MCOperand::createExpr(getTargetExprFor(
|
|
|
|
Inst,
|
|
|
|
MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, *Ctx),
|
|
|
|
MCConstantExpr::create(Addend, *Ctx), *Ctx),
|
|
|
|
*Ctx, RelType));
|
|
|
|
}
|
|
|
|
Inst.getOperand(OpNum) = Operand;
|
|
|
|
return true;
|
|
|
|
}
|