Skip to content

Commit

Permalink
[RFC][RISCV] Support the large code model.
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Kuan-Lin Chen authored and tclin914 committed Oct 26, 2023
1 parent ec6da06 commit 5cd0e50
Show file tree
Hide file tree
Showing 10 changed files with 1,798 additions and 13 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_public_tablegen_target(RISCVCommonTableGen)
add_llvm_target(RISCVCodeGen
RISCVAsmPrinter.cpp
RISCVCodeGenPrepare.cpp
RISCVConstantPoolValue.cpp
RISCVDeadRegisterDefinitions.cpp
RISCVMakeCompressible.cpp
RISCVExpandAtomicPseudoInsts.cpp
Expand Down
35 changes: 35 additions & 0 deletions llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "MCTargetDesc/RISCVMCExpr.h"
#include "MCTargetDesc/RISCVTargetStreamer.h"
#include "RISCV.h"
#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVTargetMachine.h"
#include "TargetInfo/RISCVTargetInfo.h"
Expand Down Expand Up @@ -75,6 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter {

void emitInstruction(const MachineInstr *MI) override;

void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;

bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
const char *ExtraCode, raw_ostream &OS) override;
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
Expand Down Expand Up @@ -981,3 +984,35 @@ bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
}
return false;
}

static MCSymbolRefExpr::VariantKind
getModifierVariantKind(RISCVCP::RISCVCPModifier Modifier) {
switch (Modifier) {
case RISCVCP::None:
return MCSymbolRefExpr::VK_None;
}
llvm_unreachable("Invalid RISCVCPModifier!");
}

void RISCVAsmPrinter::emitMachineConstantPoolValue(
MachineConstantPoolValue *MCPV) {
auto *RCPV = static_cast<RISCVConstantPoolValue *>(MCPV);
MCSymbol *MCSym;

if (RCPV->isGlobalValue()) {
auto GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
MCSym = getSymbol(GV);
} else if (RCPV->isBlockAddress()) {
auto BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
MCSym = GetBlockAddressSymbol(BA);
} else {
assert(RCPV->isExtSymbol() && "unrecognized constant pool value");
auto Sym = cast<RISCVConstantPoolSymbol>(RCPV)->getSymbol();
MCSym = GetExternalSymbolSymbol(Sym);
}

const MCExpr *Expr = MCSymbolRefExpr::create(
MCSym, getModifierVariantKind(RCPV->getModifier()), OutContext);
uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
OutStreamer->emitValue(Expr, Size);
}
114 changes: 114 additions & 0 deletions llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
//===------- RISCVConstantPoolValue.cpp - RISC-V constantpool value -------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the RISC-V specific constantpool value class.
//
//===----------------------------------------------------------------------===//

#include "RISCVConstantPoolValue.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

RISCVConstantPoolValue::RISCVConstantPoolValue(
LLVMContext &C, RISCVCP::RISCVCPKind Kind,
RISCVCP::RISCVCPModifier Modifier)
: MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind),
Modifier(Modifier) {}

RISCVConstantPoolValue::RISCVConstantPoolValue(
Type *Ty, RISCVCP::RISCVCPKind Kind, RISCVCP::RISCVCPModifier Modifier)
: MachineConstantPoolValue(Ty), Kind(Kind), Modifier(Modifier) {}

int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) {
llvm_unreachable("Shouldn't be calling this directly!");
}

StringRef RISCVConstantPoolValue::getModifierText() const {
switch (Modifier) {
case RISCVCP::None:
return "";
}
llvm_unreachable("Unknown modifier!");
}

void RISCVConstantPoolValue::print(raw_ostream &O) const {
if (hasModifier())
O << "@" << getModifierText();
}

RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
const Constant *GV,
RISCVCP::RISCVCPKind Kind)
: RISCVConstantPoolValue(Ty, Kind, RISCVCP::None), CVal(GV) {}

RISCVConstantPoolConstant *
RISCVConstantPoolConstant::Create(const GlobalValue *GV,
RISCVCP::RISCVCPKind Kind) {
return new RISCVConstantPoolConstant(GV->getType(), GV, Kind);
}

RISCVConstantPoolConstant *
RISCVConstantPoolConstant::Create(const Constant *C,
RISCVCP::RISCVCPKind Kind) {
return new RISCVConstantPoolConstant(C->getType(), C, Kind);
}

int RISCVConstantPoolConstant::getExistingMachineCPValue(
MachineConstantPool *CP, Align Alignment) {
return getExistingMachineCPValueImpl<RISCVConstantPoolConstant>(CP,
Alignment);
}

void RISCVConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
ID.AddPointer(CVal);
}

void RISCVConstantPoolConstant::print(raw_ostream &O) const {
O << CVal->getName();
RISCVConstantPoolValue::print(O);
}

const GlobalValue *RISCVConstantPoolConstant::getGlobalValue() const {
return dyn_cast_or_null<GlobalValue>(CVal);
}

const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
return dyn_cast_or_null<BlockAddress>(CVal);
}

RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
LLVMContext &C, StringRef s, RISCVCP::RISCVCPModifier Modifier)
: RISCVConstantPoolValue(C, RISCVCP::ExtSymbol, Modifier), S(s) {}

RISCVConstantPoolSymbol *
RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s,
RISCVCP::RISCVCPModifier Modifier) {
return new RISCVConstantPoolSymbol(C, s, Modifier);
}

int RISCVConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) {
return getExistingMachineCPValueImpl<RISCVConstantPoolSymbol>(CP, Alignment);
}

void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
ID.AddString(S);
}

void RISCVConstantPoolSymbol::print(raw_ostream &O) const {
O << S;
RISCVConstantPoolValue::print(O);
}
147 changes: 147 additions & 0 deletions llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
//===--- RISCVConstantPoolValue.h - RISC-V constantpool value ---*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the RISC-V specific constantpool value class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
#define LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H

#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"

namespace llvm {

class LLVMContext;
class GlobalValue;
class BlockAddress;

namespace RISCVCP {

enum RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };

enum RISCVCPModifier {
None,
};
} // end namespace RISCVCP

/// A RISCV-specific constant pool value.
class RISCVConstantPoolValue : public MachineConstantPoolValue {
RISCVCP::RISCVCPKind Kind;
RISCVCP::RISCVCPModifier Modifier;

protected:
RISCVConstantPoolValue(LLVMContext &C, RISCVCP::RISCVCPKind Kind,
RISCVCP::RISCVCPModifier Modifier);

RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind,
RISCVCP::RISCVCPModifier Modifier);

template <typename Derived>
int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
if (Constants[i].isMachineConstantPoolEntry() &&
Constants[i].getAlign() >= Alignment) {
auto *CPV = static_cast<RISCVConstantPoolValue *>(
Constants[i].Val.MachineCPVal);
if (Derived *APC = dyn_cast<Derived>(CPV))
if (cast<Derived>(this)->equals(APC))
return i;
}
}

return -1;
}

public:
~RISCVConstantPoolValue() = default;

RISCVCP::RISCVCPModifier getModifier() const { return Modifier; }
StringRef getModifierText() const;
bool hasModifier() const { return Modifier != RISCVCP::None; }

bool isExtSymbol() const { return Kind == RISCVCP::ExtSymbol; }
bool isGlobalValue() const { return Kind == RISCVCP::GlobalValue; }
bool isBlockAddress() const { return Kind == RISCVCP::BlockAddress; }

int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;

void addSelectionDAGCSEId(FoldingSetNodeID &ID) override {}

bool equals(const RISCVConstantPoolValue *A) const {
return this->Modifier == A->Modifier;
}

void print(raw_ostream &O) const override;
};

class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
const Constant *CVal;

RISCVConstantPoolConstant(Type *Ty, const Constant *GV,
RISCVCP::RISCVCPKind Kind);

public:
static RISCVConstantPoolConstant *Create(const GlobalValue *GV,
RISCVCP::RISCVCPKind Kind);
static RISCVConstantPoolConstant *Create(const Constant *C,
RISCVCP::RISCVCPKind Kind);

const GlobalValue *getGlobalValue() const;
const BlockAddress *getBlockAddress() const;

int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;

void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;

void print(raw_ostream &O) const override;

bool equals(const RISCVConstantPoolConstant *A) const {
return CVal == A->CVal && RISCVConstantPoolValue::equals(A);
}

static bool classof(const RISCVConstantPoolValue *RCPV) {
return RCPV->isGlobalValue() || RCPV->isBlockAddress();
}
};

class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
const std::string S;

RISCVConstantPoolSymbol(LLVMContext &C, StringRef s,
RISCVCP::RISCVCPModifier Modifier);

public:
static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s,
RISCVCP ::RISCVCPModifier Modifier);

std::string getSymbol() const { return S; }

int getExistingMachineCPValue(MachineConstantPool *CP,
Align Alignment) override;

void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;

void print(raw_ostream &O) const override;

bool equals(const RISCVConstantPoolSymbol *A) const {
return S == A->S && RISCVConstantPoolValue::equals(A);
}
static bool classof(const RISCVConstantPoolValue *RCPV) {
return RCPV->isExtSymbol();
}
};

} // end namespace llvm

#endif
Loading

0 comments on commit 5cd0e50

Please sign in to comment.