2021-12-22 02:21:41 +08:00
|
|
|
//===- bolt/Core/MCPlusBuilder.cpp - Interface for MCPlus -----------------===//
|
2018-03-10 01:45:13 +08:00
|
|
|
//
|
2021-03-16 09:04:18 +08: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-10 01:45:13 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2021-12-22 02:21:41 +08:00
|
|
|
// This file implements the MCPlusBuilder class.
|
2018-03-10 01:45:13 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2021-10-09 02:47:10 +08:00
|
|
|
#include "bolt/Core/MCPlusBuilder.h"
|
|
|
|
#include "bolt/Core/MCPlus.h"
|
2018-03-10 01:45:13 +08:00
|
|
|
#include "llvm/MC/MCInst.h"
|
2021-10-09 02:47:10 +08:00
|
|
|
#include "llvm/MC/MCInstrAnalysis.h"
|
2018-03-10 01:45:13 +08:00
|
|
|
#include "llvm/MC/MCInstrDesc.h"
|
|
|
|
#include "llvm/MC/MCInstrInfo.h"
|
|
|
|
#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-20 09:32:12 +08:00
|
|
|
using namespace MCPlus;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2018-04-13 01:07:11 +08: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-21 03:07:46 +08:00
|
|
|
for (unsigned Index = 0; Index < NumOperands; ++Index)
|
2018-04-13 01:07:11 +08: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-02 08:29:39 +08:00
|
|
|
} else if (A.isSFPImm()) {
|
|
|
|
if (!B.isSFPImm())
|
2018-04-13 01:07:11 +08:00
|
|
|
return false;
|
2020-12-02 08: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-13 01:07:11 +08: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-15 08:52:51 +08:00
|
|
|
llvm_unreachable("target-specific expressions are unsupported");
|
2018-04-13 01:07:11 +08:00
|
|
|
}
|
|
|
|
|
2021-07-30 08:28:51 +08: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;
|
|
|
|
}
|
|
|
|
|
[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-20 09:32:12 +08:00
|
|
|
Optional<MCLandingPad> MCPlusBuilder::getEHInfo(const MCInst &Inst) const {
|
|
|
|
if (!isCall(Inst))
|
|
|
|
return NoneType();
|
2021-04-08 15:19:26 +08:00
|
|
|
Optional<int64_t> LPSym =
|
|
|
|
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-20 09:32:12 +08:00
|
|
|
if (!LPSym)
|
|
|
|
return NoneType();
|
2021-04-08 15:19:26 +08:00
|
|
|
Optional<int64_t> Action =
|
|
|
|
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-20 09:32:12 +08:00
|
|
|
if (!Action)
|
|
|
|
return NoneType();
|
2018-03-10 01: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-20 09:32:12 +08:00
|
|
|
return std::make_pair(reinterpret_cast<const MCSymbol *>(*LPSym),
|
|
|
|
static_cast<uint64_t>(*Action));
|
2018-03-10 01: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-20 09:32:12 +08:00
|
|
|
void MCPlusBuilder::addEHInfo(MCInst &Inst, const MCLandingPad &LP) {
|
2018-03-10 01: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-20 09:32:12 +08: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-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int64_t MCPlusBuilder::getGnuArgsSize(const MCInst &Inst) const {
|
2021-04-08 15:19:26 +08:00
|
|
|
Optional<int64_t> Value =
|
|
|
|
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-20 09:32:12 +08:00
|
|
|
if (!Value)
|
|
|
|
return -1LL;
|
|
|
|
return *Value;
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
2019-07-12 22:25:50 +08:00
|
|
|
void MCPlusBuilder::addGnuArgsSize(MCInst &Inst, int64_t GnuArgsSize,
|
|
|
|
AllocatorIdTy AllocId) {
|
2018-03-10 01: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 22:25:50 +08:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kGnuArgsSize, GnuArgsSize, AllocId);
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
uint64_t MCPlusBuilder::getJumpTable(const MCInst &Inst) const {
|
2021-04-08 15:19:26 +08:00
|
|
|
Optional<int64_t> Value =
|
|
|
|
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-20 09:32:12 +08:00
|
|
|
if (!Value)
|
|
|
|
return 0;
|
|
|
|
return *Value;
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
2019-06-29 00:21:27 +08: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-20 09:32:12 +08:00
|
|
|
bool MCPlusBuilder::setJumpTable(MCInst &Inst, uint64_t Value,
|
2019-07-12 22:25:50 +08:00
|
|
|
uint16_t IndexReg, AllocatorIdTy AllocId) {
|
2018-03-10 01:45:13 +08:00
|
|
|
if (!isIndirectBranch(Inst))
|
|
|
|
return false;
|
2019-07-12 22:25:50 +08:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kJumpTable, Value, AllocId);
|
2019-08-03 02:20:13 +08:00
|
|
|
getOrCreateAnnotationAs<uint16_t>(Inst, "JTIndexReg", AllocId) = IndexReg;
|
2018-03-10 01:45:13 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-06-29 00:21:27 +08:00
|
|
|
bool MCPlusBuilder::unsetJumpTable(MCInst &Inst) {
|
|
|
|
if (!getJumpTable(Inst))
|
|
|
|
return false;
|
|
|
|
removeAnnotation(Inst, MCAnnotation::kJumpTable);
|
|
|
|
removeAnnotation(Inst, "JTIndexReg");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-10 01:45:13 +08:00
|
|
|
Optional<uint64_t>
|
|
|
|
MCPlusBuilder::getConditionalTailCall(const MCInst &Inst) const {
|
2021-04-08 15:19:26 +08:00
|
|
|
Optional<int64_t> Value =
|
|
|
|
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-20 09:32:12 +08:00
|
|
|
if (!Value)
|
|
|
|
return NoneType();
|
|
|
|
return static_cast<uint64_t>(*Value);
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
bool MCPlusBuilder::setConditionalTailCall(MCInst &Inst, uint64_t Dest) {
|
2018-03-10 01: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-20 09:32:12 +08:00
|
|
|
setAnnotationOpValue(Inst, MCAnnotation::kConditionalTailCall, Dest);
|
|
|
|
return true;
|
|
|
|
}
|
2018-03-10 01: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-20 09:32:12 +08:00
|
|
|
bool MCPlusBuilder::unsetConditionalTailCall(MCInst &Inst) {
|
|
|
|
if (!getConditionalTailCall(Inst))
|
|
|
|
return false;
|
2018-03-30 09:42:06 +08:00
|
|
|
removeAnnotation(Inst, MCAnnotation::kConditionalTailCall);
|
2018-03-10 01:45:13 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-03-30 09:42:06 +08:00
|
|
|
bool MCPlusBuilder::hasAnnotation(const MCInst &Inst, unsigned Index) const {
|
2021-04-08 15:19:26 +08: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-20 09:32:12 +08:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return false;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2018-03-30 09:42:06 +08:00
|
|
|
return (bool)getAnnotationOpValue(Inst, Index);
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
2018-03-30 09:42:06 +08:00
|
|
|
bool MCPlusBuilder::removeAnnotation(MCInst &Inst, unsigned Index) {
|
2021-04-08 15:19:26 +08: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-20 09:32:12 +08:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return false;
|
|
|
|
|
2018-03-30 09:42:06 +08:00
|
|
|
for (int I = AnnotationInst->getNumOperands() - 1; I >= 0; --I) {
|
2021-04-08 15:19:26 +08:00
|
|
|
int64_t ImmValue = AnnotationInst->getOperand(I).getImm();
|
2018-03-30 09:42:06 +08: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-20 09:32:12 +08:00
|
|
|
}
|
2018-03-30 09:42:06 +08:00
|
|
|
return false;
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
|
|
|
|
2020-12-02 08:29:39 +08:00
|
|
|
void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
|
2021-04-08 15:19:26 +08:00
|
|
|
MCInst *AnnotationInst = getAnnotationInst(Inst);
|
2019-02-01 03:23:02 +08:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return;
|
2020-12-02 08:29:39 +08:00
|
|
|
// Preserve TailCall annotation.
|
2021-07-30 08:28:51 +08:00
|
|
|
auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
|
2019-02-01 03:23:02 +08:00
|
|
|
|
|
|
|
Inst.erase(std::prev(Inst.end()));
|
2021-07-30 08:28:51 +08:00
|
|
|
if (KeepTC && IsTC)
|
|
|
|
setTailCall(Inst);
|
2019-02-01 03:23:02 +08:00
|
|
|
}
|
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
void MCPlusBuilder::printAnnotations(const MCInst &Inst,
|
|
|
|
raw_ostream &OS) const {
|
2021-04-08 15:19:26 +08: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-20 09:32:12 +08:00
|
|
|
if (!AnnotationInst)
|
|
|
|
return;
|
|
|
|
|
2018-03-30 09:42:06 +08:00
|
|
|
for (unsigned I = 0; I < AnnotationInst->getNumOperands(); ++I) {
|
2021-04-08 15:19:26 +08:00
|
|
|
const int64_t Imm = AnnotationInst->getOperand(I).getImm();
|
|
|
|
const unsigned Index = extractAnnotationIndex(Imm);
|
|
|
|
const int64_t Value = extractAnnotationValue(Imm);
|
2021-12-15 08:52:51 +08:00
|
|
|
const auto *Annotation = reinterpret_cast<const MCAnnotation *>(Value);
|
2018-03-30 09:42:06 +08:00
|
|
|
if (Index >= MCAnnotation::kGeneric) {
|
2021-12-15 08:52:51 +08:00
|
|
|
OS << " # " << AnnotationNames[Index - MCAnnotation::kGeneric] << ": ";
|
2018-03-30 09:42:06 +08:00
|
|
|
Annotation->print(OS);
|
|
|
|
}
|
2018-03-10 01: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-20 09:32:12 +08:00
|
|
|
bool MCPlusBuilder::evaluateBranch(const MCInst &Inst, uint64_t Addr,
|
|
|
|
uint64_t Size, uint64_t &Target) const {
|
|
|
|
return Analysis->evaluateBranch(Inst, Addr, Size, Target);
|
2019-07-25 08:54:14 +08:00
|
|
|
}
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
void MCPlusBuilder::getClobberedRegs(const MCInst &Inst,
|
|
|
|
BitVector &Regs) const {
|
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCPhysReg *ImplicitDefs = InstInfo.getImplicitDefs();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitDefs(); I != E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Regs |= getAliases(ImplicitDefs[I], /*OnlySmaller=*/false);
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumDefs(); I != E; ++I) {
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCOperand &Operand = Inst.getOperand(I);
|
2019-07-25 08:54:14 +08:00
|
|
|
assert(Operand.isReg());
|
|
|
|
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/false);
|
|
|
|
}
|
|
|
|
}
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
void MCPlusBuilder::getTouchedRegs(const MCInst &Inst, BitVector &Regs) const {
|
2019-07-25 08:54:14 +08:00
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCPhysReg *ImplicitDefs = InstInfo.getImplicitDefs();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitDefs(); I != E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Regs |= getAliases(ImplicitDefs[I], /*OnlySmaller=*/false);
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCPhysReg *ImplicitUses = InstInfo.getImplicitUses();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitUses(); I != E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Regs |= getAliases(ImplicitUses[I], /*OnlySmaller=*/false);
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08: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-10 01:45:13 +08:00
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
void MCPlusBuilder::getWrittenRegs(const MCInst &Inst, BitVector &Regs) const {
|
2019-07-25 08:54:14 +08:00
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCPhysReg *ImplicitDefs = InstInfo.getImplicitDefs();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitDefs(); I != E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Regs |= getAliases(ImplicitDefs[I], /*OnlySmaller=*/true);
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumDefs(); I != E; ++I) {
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCOperand &Operand = Inst.getOperand(I);
|
2019-07-25 08:54:14 +08:00
|
|
|
assert(Operand.isReg());
|
|
|
|
Regs |= getAliases(Operand.getReg(), /*OnlySmaller=*/true);
|
|
|
|
}
|
|
|
|
}
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
void MCPlusBuilder::getUsedRegs(const MCInst &Inst, BitVector &Regs) const {
|
|
|
|
if (isPrefix(Inst) || isCFI(Inst))
|
|
|
|
return;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCPhysReg *ImplicitUses = InstInfo.getImplicitUses();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitUses(); I != E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Regs |= getAliases(ImplicitUses[I], /*OnlySmaller=*/true);
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08: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-15 10:56:11 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
}
|
2019-02-01 03:23:02 +08:00
|
|
|
|
2021-08-11 01:02:32 +08: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-21 03:07:46 +08:00
|
|
|
if (isRep(Inst))
|
2021-08-11 01:02:32 +08:00
|
|
|
getRepRegs(Regs);
|
|
|
|
|
|
|
|
const MCInstrDesc &InstInfo = Info->get(Inst.getOpcode());
|
|
|
|
|
|
|
|
const MCPhysReg *ImplicitUses = InstInfo.getImplicitUses();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (unsigned I = 0, E = InstInfo.getNumImplicitUses(); I != E; ++I)
|
2021-08-11 01:02:32 +08:00
|
|
|
Regs |= getAliases(ImplicitUses[I], /*OnlySmaller=*/true);
|
|
|
|
|
|
|
|
for (unsigned I = InstInfo.getNumDefs(), E = InstInfo.getNumOperands();
|
|
|
|
I != E; ++I) {
|
|
|
|
if (!Inst.getOperand(I).isReg())
|
|
|
|
continue;
|
|
|
|
Regs |= getAliases(Inst.getOperand(I).getReg(), /*OnlySmaller=*/true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
bool MCPlusBuilder::hasDefOfPhysReg(const MCInst &MI, unsigned Reg) const {
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
|
2019-07-25 08:54:14 +08:00
|
|
|
return InstInfo.hasDefOfPhysReg(MI, Reg, *RegInfo);
|
|
|
|
}
|
2019-02-01 03:23:02 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
bool MCPlusBuilder::hasUseOfPhysReg(const MCInst &MI, unsigned Reg) const {
|
2021-04-08 15:19:26 +08:00
|
|
|
const MCInstrDesc &InstInfo = Info->get(MI.getOpcode());
|
2019-07-25 08:54:14 +08:00
|
|
|
for (int I = InstInfo.NumDefs; I < InstInfo.NumOperands; ++I)
|
|
|
|
if (MI.getOperand(I).isReg() &&
|
|
|
|
RegInfo->isSubRegisterEq(Reg, MI.getOperand(I).getReg()))
|
|
|
|
return true;
|
2021-12-21 03:07:46 +08:00
|
|
|
if (const uint16_t *ImpUses = InstInfo.ImplicitUses) {
|
2019-07-25 08:54:14 +08:00
|
|
|
for (; *ImpUses; ++ImpUses)
|
|
|
|
if (*ImpUses == Reg || RegInfo->isSubRegister(Reg, *ImpUses))
|
|
|
|
return true;
|
2021-12-21 03:07:46 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
return false;
|
|
|
|
}
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
const BitVector &MCPlusBuilder::getAliases(MCPhysReg Reg,
|
|
|
|
bool OnlySmaller) const {
|
2019-07-25 08:54:14 +08:00
|
|
|
// AliasMap caches a mapping of registers to the set of registers that
|
|
|
|
// alias (are sub or superregs of itself, including itself).
|
|
|
|
static std::vector<BitVector> AliasMap;
|
|
|
|
static std::vector<MCPhysReg> SuperReg;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
if (AliasMap.size() > 0) {
|
2019-06-15 10:56:11 +08:00
|
|
|
if (OnlySmaller)
|
|
|
|
return AliasMap[Reg];
|
|
|
|
return AliasMap[SuperReg[Reg]];
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
// Build alias map
|
|
|
|
for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
|
|
|
|
BitVector BV(RegInfo->getNumRegs(), false);
|
|
|
|
BV.set(I);
|
|
|
|
AliasMap.emplace_back(std::move(BV));
|
|
|
|
SuperReg.emplace_back(I);
|
|
|
|
}
|
|
|
|
std::queue<MCPhysReg> Worklist;
|
2020-12-02 08:29:39 +08:00
|
|
|
// Propagate alias info upwards. Skip reg 0 (mapped to NoRegister)
|
2021-12-21 03:07:46 +08:00
|
|
|
for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I < E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Worklist.push(I);
|
|
|
|
while (!Worklist.empty()) {
|
|
|
|
MCPhysReg I = Worklist.front();
|
|
|
|
Worklist.pop();
|
2021-12-21 03:07:46 +08:00
|
|
|
for (MCSubRegIterator SI(I, RegInfo); SI.isValid(); ++SI)
|
2019-07-25 08:54:14 +08:00
|
|
|
AliasMap[I] |= AliasMap[*SI];
|
2021-12-21 03:07:46 +08:00
|
|
|
for (MCSuperRegIterator SI(I, RegInfo); SI.isValid(); ++SI)
|
2019-07-25 08:54:14 +08:00
|
|
|
Worklist.push(*SI);
|
|
|
|
}
|
|
|
|
// Propagate parent reg downwards
|
2021-12-21 03:07:46 +08:00
|
|
|
for (MCPhysReg I = 1, E = RegInfo->getNumRegs(); I < E; ++I)
|
2019-07-25 08:54:14 +08:00
|
|
|
Worklist.push(I);
|
|
|
|
while (!Worklist.empty()) {
|
|
|
|
MCPhysReg I = Worklist.front();
|
|
|
|
Worklist.pop();
|
|
|
|
for (MCSubRegIterator SI(I, RegInfo); SI.isValid(); ++SI) {
|
|
|
|
SuperReg[*SI] = SuperReg[I];
|
|
|
|
Worklist.push(*SI);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-02 08:29:39 +08:00
|
|
|
LLVM_DEBUG({
|
2019-07-25 08:54:14 +08:00
|
|
|
dbgs() << "Dumping reg alias table:\n";
|
|
|
|
for (MCPhysReg I = 0, E = RegInfo->getNumRegs(); I != E; ++I) {
|
|
|
|
dbgs() << "Reg " << I << ": ";
|
|
|
|
const BitVector &BV = AliasMap[SuperReg[I]];
|
|
|
|
int Idx = BV.find_first();
|
|
|
|
while (Idx != -1) {
|
|
|
|
dbgs() << Idx << " ";
|
|
|
|
Idx = BV.find_next(Idx);
|
2019-06-15 10:56:11 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
dbgs() << "\n";
|
2018-03-10 01:45:13 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
if (OnlySmaller)
|
|
|
|
return AliasMap[Reg];
|
|
|
|
return AliasMap[SuperReg[Reg]];
|
|
|
|
}
|
|
|
|
|
2021-12-15 08:52:51 +08:00
|
|
|
uint8_t MCPlusBuilder::getRegSize(MCPhysReg Reg) const {
|
2019-07-25 08:54:14 +08:00
|
|
|
// SizeMap caches a mapping of registers to their sizes
|
|
|
|
static std::vector<uint8_t> SizeMap;
|
2018-03-10 01:45:13 +08:00
|
|
|
|
2019-07-25 08:54:14 +08:00
|
|
|
if (SizeMap.size() > 0) {
|
2019-06-15 10:56:11 +08:00
|
|
|
return SizeMap[Reg];
|
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
SizeMap = std::vector<uint8_t>(RegInfo->getNumRegs());
|
|
|
|
// Build size map
|
|
|
|
for (auto I = RegInfo->regclass_begin(), E = RegInfo->regclass_end(); I != E;
|
|
|
|
++I) {
|
2021-12-21 03:07:46 +08:00
|
|
|
for (MCPhysReg Reg : *I)
|
2020-12-02 08:29:39 +08:00
|
|
|
SizeMap[Reg] = I->getSizeInBits() / 8;
|
2018-07-04 02:57:46 +08:00
|
|
|
}
|
2019-07-25 08:54:14 +08:00
|
|
|
|
|
|
|
return SizeMap[Reg];
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|