Skip to content

Commit 5cd0e50

Browse files
Kuan-Lin Chentclin914
authored andcommitted
[RFC][RISCV] Support the large code model.
Implement large code model for GlobalAddressSDNode, BlockAddressSDNode and ExternalSymbolSDNode. See discussion on riscv-non-isa/riscv-elf-psabi-doc#388. co-authored by: Kuan-Lin Chen <[email protected]>
1 parent ec6da06 commit 5cd0e50

10 files changed

+1798
-13
lines changed

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ add_public_tablegen_target(RISCVCommonTableGen)
2929
add_llvm_target(RISCVCodeGen
3030
RISCVAsmPrinter.cpp
3131
RISCVCodeGenPrepare.cpp
32+
RISCVConstantPoolValue.cpp
3233
RISCVDeadRegisterDefinitions.cpp
3334
RISCVMakeCompressible.cpp
3435
RISCVExpandAtomicPseudoInsts.cpp

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "MCTargetDesc/RISCVMCExpr.h"
1717
#include "MCTargetDesc/RISCVTargetStreamer.h"
1818
#include "RISCV.h"
19+
#include "RISCVConstantPoolValue.h"
1920
#include "RISCVMachineFunctionInfo.h"
2021
#include "RISCVTargetMachine.h"
2122
#include "TargetInfo/RISCVTargetInfo.h"
@@ -75,6 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter {
7576

7677
void emitInstruction(const MachineInstr *MI) override;
7778

79+
void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
80+
7881
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
7982
const char *ExtraCode, raw_ostream &OS) override;
8083
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
@@ -981,3 +984,35 @@ bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
981984
}
982985
return false;
983986
}
987+
988+
static MCSymbolRefExpr::VariantKind
989+
getModifierVariantKind(RISCVCP::RISCVCPModifier Modifier) {
990+
switch (Modifier) {
991+
case RISCVCP::None:
992+
return MCSymbolRefExpr::VK_None;
993+
}
994+
llvm_unreachable("Invalid RISCVCPModifier!");
995+
}
996+
997+
void RISCVAsmPrinter::emitMachineConstantPoolValue(
998+
MachineConstantPoolValue *MCPV) {
999+
auto *RCPV = static_cast<RISCVConstantPoolValue *>(MCPV);
1000+
MCSymbol *MCSym;
1001+
1002+
if (RCPV->isGlobalValue()) {
1003+
auto GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
1004+
MCSym = getSymbol(GV);
1005+
} else if (RCPV->isBlockAddress()) {
1006+
auto BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
1007+
MCSym = GetBlockAddressSymbol(BA);
1008+
} else {
1009+
assert(RCPV->isExtSymbol() && "unrecognized constant pool value");
1010+
auto Sym = cast<RISCVConstantPoolSymbol>(RCPV)->getSymbol();
1011+
MCSym = GetExternalSymbolSymbol(Sym);
1012+
}
1013+
1014+
const MCExpr *Expr = MCSymbolRefExpr::create(
1015+
MCSym, getModifierVariantKind(RCPV->getModifier()), OutContext);
1016+
uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
1017+
OutStreamer->emitValue(Expr, Size);
1018+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
//===------- RISCVConstantPoolValue.cpp - RISC-V constantpool value -------===//
2+
//
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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements the RISC-V specific constantpool value class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "RISCVConstantPoolValue.h"
14+
#include "llvm/ADT/FoldingSet.h"
15+
#include "llvm/IR/Constants.h"
16+
#include "llvm/IR/DerivedTypes.h"
17+
#include "llvm/IR/GlobalValue.h"
18+
#include "llvm/IR/Type.h"
19+
#include "llvm/Support/Casting.h"
20+
#include "llvm/Support/raw_ostream.h"
21+
22+
using namespace llvm;
23+
24+
RISCVConstantPoolValue::RISCVConstantPoolValue(
25+
LLVMContext &C, RISCVCP::RISCVCPKind Kind,
26+
RISCVCP::RISCVCPModifier Modifier)
27+
: MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind),
28+
Modifier(Modifier) {}
29+
30+
RISCVConstantPoolValue::RISCVConstantPoolValue(
31+
Type *Ty, RISCVCP::RISCVCPKind Kind, RISCVCP::RISCVCPModifier Modifier)
32+
: MachineConstantPoolValue(Ty), Kind(Kind), Modifier(Modifier) {}
33+
34+
int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
35+
Align Alignment) {
36+
llvm_unreachable("Shouldn't be calling this directly!");
37+
}
38+
39+
StringRef RISCVConstantPoolValue::getModifierText() const {
40+
switch (Modifier) {
41+
case RISCVCP::None:
42+
return "";
43+
}
44+
llvm_unreachable("Unknown modifier!");
45+
}
46+
47+
void RISCVConstantPoolValue::print(raw_ostream &O) const {
48+
if (hasModifier())
49+
O << "@" << getModifierText();
50+
}
51+
52+
RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
53+
const Constant *GV,
54+
RISCVCP::RISCVCPKind Kind)
55+
: RISCVConstantPoolValue(Ty, Kind, RISCVCP::None), CVal(GV) {}
56+
57+
RISCVConstantPoolConstant *
58+
RISCVConstantPoolConstant::Create(const GlobalValue *GV,
59+
RISCVCP::RISCVCPKind Kind) {
60+
return new RISCVConstantPoolConstant(GV->getType(), GV, Kind);
61+
}
62+
63+
RISCVConstantPoolConstant *
64+
RISCVConstantPoolConstant::Create(const Constant *C,
65+
RISCVCP::RISCVCPKind Kind) {
66+
return new RISCVConstantPoolConstant(C->getType(), C, Kind);
67+
}
68+
69+
int RISCVConstantPoolConstant::getExistingMachineCPValue(
70+
MachineConstantPool *CP, Align Alignment) {
71+
return getExistingMachineCPValueImpl<RISCVConstantPoolConstant>(CP,
72+
Alignment);
73+
}
74+
75+
void RISCVConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
76+
ID.AddPointer(CVal);
77+
}
78+
79+
void RISCVConstantPoolConstant::print(raw_ostream &O) const {
80+
O << CVal->getName();
81+
RISCVConstantPoolValue::print(O);
82+
}
83+
84+
const GlobalValue *RISCVConstantPoolConstant::getGlobalValue() const {
85+
return dyn_cast_or_null<GlobalValue>(CVal);
86+
}
87+
88+
const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
89+
return dyn_cast_or_null<BlockAddress>(CVal);
90+
}
91+
92+
RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
93+
LLVMContext &C, StringRef s, RISCVCP::RISCVCPModifier Modifier)
94+
: RISCVConstantPoolValue(C, RISCVCP::ExtSymbol, Modifier), S(s) {}
95+
96+
RISCVConstantPoolSymbol *
97+
RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s,
98+
RISCVCP::RISCVCPModifier Modifier) {
99+
return new RISCVConstantPoolSymbol(C, s, Modifier);
100+
}
101+
102+
int RISCVConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
103+
Align Alignment) {
104+
return getExistingMachineCPValueImpl<RISCVConstantPoolSymbol>(CP, Alignment);
105+
}
106+
107+
void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
108+
ID.AddString(S);
109+
}
110+
111+
void RISCVConstantPoolSymbol::print(raw_ostream &O) const {
112+
O << S;
113+
RISCVConstantPoolValue::print(O);
114+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
//===--- RISCVConstantPoolValue.h - RISC-V constantpool value ---*- C++ -*-===//
2+
//
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
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file implements the RISC-V specific constantpool value class.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
14+
#define LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
15+
16+
#include "llvm/CodeGen/MachineConstantPool.h"
17+
#include "llvm/Support/Casting.h"
18+
#include "llvm/Support/ErrorHandling.h"
19+
20+
namespace llvm {
21+
22+
class LLVMContext;
23+
class GlobalValue;
24+
class BlockAddress;
25+
26+
namespace RISCVCP {
27+
28+
enum RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };
29+
30+
enum RISCVCPModifier {
31+
None,
32+
};
33+
} // end namespace RISCVCP
34+
35+
/// A RISCV-specific constant pool value.
36+
class RISCVConstantPoolValue : public MachineConstantPoolValue {
37+
RISCVCP::RISCVCPKind Kind;
38+
RISCVCP::RISCVCPModifier Modifier;
39+
40+
protected:
41+
RISCVConstantPoolValue(LLVMContext &C, RISCVCP::RISCVCPKind Kind,
42+
RISCVCP::RISCVCPModifier Modifier);
43+
44+
RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind,
45+
RISCVCP::RISCVCPModifier Modifier);
46+
47+
template <typename Derived>
48+
int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
49+
const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
50+
for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
51+
if (Constants[i].isMachineConstantPoolEntry() &&
52+
Constants[i].getAlign() >= Alignment) {
53+
auto *CPV = static_cast<RISCVConstantPoolValue *>(
54+
Constants[i].Val.MachineCPVal);
55+
if (Derived *APC = dyn_cast<Derived>(CPV))
56+
if (cast<Derived>(this)->equals(APC))
57+
return i;
58+
}
59+
}
60+
61+
return -1;
62+
}
63+
64+
public:
65+
~RISCVConstantPoolValue() = default;
66+
67+
RISCVCP::RISCVCPModifier getModifier() const { return Modifier; }
68+
StringRef getModifierText() const;
69+
bool hasModifier() const { return Modifier != RISCVCP::None; }
70+
71+
bool isExtSymbol() const { return Kind == RISCVCP::ExtSymbol; }
72+
bool isGlobalValue() const { return Kind == RISCVCP::GlobalValue; }
73+
bool isBlockAddress() const { return Kind == RISCVCP::BlockAddress; }
74+
75+
int getExistingMachineCPValue(MachineConstantPool *CP,
76+
Align Alignment) override;
77+
78+
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override {}
79+
80+
bool equals(const RISCVConstantPoolValue *A) const {
81+
return this->Modifier == A->Modifier;
82+
}
83+
84+
void print(raw_ostream &O) const override;
85+
};
86+
87+
class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
88+
const Constant *CVal;
89+
90+
RISCVConstantPoolConstant(Type *Ty, const Constant *GV,
91+
RISCVCP::RISCVCPKind Kind);
92+
93+
public:
94+
static RISCVConstantPoolConstant *Create(const GlobalValue *GV,
95+
RISCVCP::RISCVCPKind Kind);
96+
static RISCVConstantPoolConstant *Create(const Constant *C,
97+
RISCVCP::RISCVCPKind Kind);
98+
99+
const GlobalValue *getGlobalValue() const;
100+
const BlockAddress *getBlockAddress() const;
101+
102+
int getExistingMachineCPValue(MachineConstantPool *CP,
103+
Align Alignment) override;
104+
105+
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
106+
107+
void print(raw_ostream &O) const override;
108+
109+
bool equals(const RISCVConstantPoolConstant *A) const {
110+
return CVal == A->CVal && RISCVConstantPoolValue::equals(A);
111+
}
112+
113+
static bool classof(const RISCVConstantPoolValue *RCPV) {
114+
return RCPV->isGlobalValue() || RCPV->isBlockAddress();
115+
}
116+
};
117+
118+
class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
119+
const std::string S;
120+
121+
RISCVConstantPoolSymbol(LLVMContext &C, StringRef s,
122+
RISCVCP::RISCVCPModifier Modifier);
123+
124+
public:
125+
static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s,
126+
RISCVCP ::RISCVCPModifier Modifier);
127+
128+
std::string getSymbol() const { return S; }
129+
130+
int getExistingMachineCPValue(MachineConstantPool *CP,
131+
Align Alignment) override;
132+
133+
void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
134+
135+
void print(raw_ostream &O) const override;
136+
137+
bool equals(const RISCVConstantPoolSymbol *A) const {
138+
return S == A->S && RISCVConstantPoolValue::equals(A);
139+
}
140+
static bool classof(const RISCVConstantPoolValue *RCPV) {
141+
return RCPV->isExtSymbol();
142+
}
143+
};
144+
145+
} // end namespace llvm
146+
147+
#endif

0 commit comments

Comments
 (0)