[VENTUS][RISCV] Add vararg support
Because ventus riscv is designed specially for OpenCL language, we originally add or remove some language features mainly for serving OpenCL, but we now need to add customized `printf` function which is expected to be written in C, so we need also to add support for C language features in current ventus Signed-off-by: zhoujingya <jing.zhou@terapines.com>
This commit is contained in:
parent
0642d65513
commit
8ba248d102
|
@ -19,7 +19,9 @@ Download all the repositories firstly
|
|||
|
||||
### 2: Build all the programs
|
||||
|
||||
Assume you have already installed essential build tools such as cmake, clang, ninja etc.
|
||||
> You can refer to [official website](https://llvm.org/docs/GettingStarted.html) for llvm building guidance, if you see package missing information, just install the missing packages.
|
||||
|
||||
Assume you have already installed essential build tools such as cmake, clang, ninja, ccache etc.
|
||||
|
||||
Run `./build-ventus.sh` to automatically build all the programs, but we need to run firstly
|
||||
* `export POCL_DIR=<path-to-pocl-dir>`, default folder path will be set to be **`<llvm-ventus-parentFolder>`/pocl**
|
||||
|
|
|
@ -44,6 +44,28 @@ const LangASMap RISCVTargetInfo::VentusAddrSpaceMap = {
|
|||
Generic, // hlsl_groupshared
|
||||
};
|
||||
|
||||
void RISCVTargetInfo::adjust(DiagnosticsEngine &Diags, LangOptions &Opts) {
|
||||
TargetInfo::adjust(Diags, Opts);
|
||||
llvm::Triple Triple = getTriple();
|
||||
bool isRV32 = Triple.isRISCV32();
|
||||
// Only OpenCL language needs special address mapping
|
||||
if(Opts.OpenCL) {
|
||||
UseAddrSpaceMapMangling = true;
|
||||
AddrSpaceMap = &VentusAddrSpaceMap;
|
||||
if(isRV32)
|
||||
resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128-A5-G1");
|
||||
else
|
||||
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128-A5-G1");
|
||||
}
|
||||
// Not OpenCL language, we no not need special data layout
|
||||
// just follow the official way
|
||||
else {
|
||||
if(isRV32)
|
||||
resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128");
|
||||
else
|
||||
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128");
|
||||
}
|
||||
}
|
||||
|
||||
ArrayRef<const char *> RISCVTargetInfo::getGCCRegNames() const {
|
||||
static const char *const GCCRegNames[] = {
|
||||
|
|
|
@ -53,8 +53,7 @@ public:
|
|||
HasRISCVVTypes = true;
|
||||
MCountName = "_mcount";
|
||||
HasFloat16 = true;
|
||||
UseAddrSpaceMapMangling = true;
|
||||
AddrSpaceMap = &VentusAddrSpaceMap;
|
||||
|
||||
}
|
||||
|
||||
bool setCPU(const std::string &Name) override {
|
||||
|
@ -64,6 +63,8 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override;
|
||||
|
||||
StringRef getABI() const override { return ABI; }
|
||||
void getTargetDefines(const LangOptions &Opts,
|
||||
MacroBuilder &Builder) const override;
|
||||
|
@ -191,7 +192,6 @@ public:
|
|||
//HasFloat16 = true;
|
||||
//resetDataLayout("e-m:e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256"
|
||||
// "-v256:256-v512:512-v1024:1024-n32:64-S128-A5-G1");
|
||||
resetDataLayout("e-m:e-p:32:32-i64:64-n32-S128-A5-G1");
|
||||
}
|
||||
|
||||
bool setABI(const std::string &Name) override {
|
||||
|
@ -215,7 +215,6 @@ public:
|
|||
: RISCVTargetInfo(Triple, Opts) {
|
||||
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
|
||||
IntMaxType = Int64Type = SignedLong;
|
||||
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n32:64-S128-A5-G1");
|
||||
}
|
||||
|
||||
bool setABI(const std::string &Name) override {
|
||||
|
|
|
@ -11341,9 +11341,27 @@ void VentusRISCVABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
|||
}
|
||||
}
|
||||
|
||||
// OpenCL do not support varargs when try to define customized functions
|
||||
// but here we need to add support for C language IR code generation
|
||||
Address VentusRISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
||||
QualType Ty) const {
|
||||
llvm_unreachable("TODO: Support varargs in ventus!");
|
||||
CharUnits SlotSize = CharUnits::fromQuantity(XLen / 8);
|
||||
|
||||
// Empty records are ignored for parameter passing purposes.
|
||||
if (isEmptyRecord(getContext(), Ty, true)) {
|
||||
Address Addr = Address(CGF.Builder.CreateLoad(VAListAddr),
|
||||
getVAListElementType(CGF), SlotSize);
|
||||
Addr = CGF.Builder.CreateElementBitCast(Addr, CGF.ConvertTypeForMem(Ty));
|
||||
return Addr;
|
||||
}
|
||||
|
||||
auto TInfo = getContext().getTypeInfoInChars(Ty);
|
||||
|
||||
// Arguments bigger than 2*Xlen bytes are passed indirectly.
|
||||
bool IsIndirect = TInfo.Width > 2 * SlotSize;
|
||||
|
||||
return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo,
|
||||
SlotSize, /*AllowHigherAlign=*/true);
|
||||
}
|
||||
|
||||
ABIArgInfo VentusRISCVABIInfo::classifyReturnType(QualType RetTy) const {
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py
|
||||
// RUN: %clang_cc1 -triple riscv32 -S -emit-llvm -mllvm -riscv-common-data-layout \
|
||||
// RUN: %s -o - | FileCheck --check-prefix=CHECK-RV32 %s
|
||||
|
||||
// CHECK-RV32-LABEL: @test_vararg(
|
||||
// CHECK-RV32-NEXT: entry:
|
||||
// CHECK-RV32-NEXT: [[FMT_ADDR:%.*]] = alloca ptr, align 4
|
||||
// CHECK-RV32-NEXT: [[VA:%.*]] = alloca ptr, align 4
|
||||
// CHECK-RV32-NEXT: [[RETVAL1:%.*]] = alloca i32, align 4
|
||||
// CHECK-RV32-NEXT: store ptr [[FMT:%.*]], ptr [[FMT_ADDR]], align 4
|
||||
// CHECK-RV32-NEXT: call void @llvm.va_start(ptr [[VA]])
|
||||
// CHECK-RV32-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[VA]], align 4
|
||||
// CHECK-RV32-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i32 4
|
||||
// CHECK-RV32-NEXT: store ptr [[ARGP_NEXT]], ptr [[VA]], align 4
|
||||
// CHECK-RV32-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARGP_CUR]], align 4
|
||||
// CHECK-RV32-NEXT: store i32 [[TMP0]], ptr [[RETVAL1]], align 4
|
||||
// CHECK-RV32-NEXT: call void @llvm.va_end(ptr [[VA]])
|
||||
// CHECK-RV32-NEXT: [[TMP1:%.*]] = load i32, ptr [[RETVAL1]], align 4
|
||||
// CHECK-RV32-NEXT: ret i32 [[TMP1]]
|
||||
//
|
||||
int test_vararg(char *fmt,...) {
|
||||
__builtin_va_list va;
|
||||
__builtin_va_start(va, fmt);
|
||||
int retval = __builtin_va_arg(va, int);
|
||||
__builtin_va_end(va);
|
||||
return retval;
|
||||
}
|
|
@ -115,7 +115,8 @@ void RISCVAsmPrinter::emitInstruction(const MachineInstr *MI) {
|
|||
return;
|
||||
}
|
||||
if (RISCVII::IsVecImm12MemInstr(MI->getDesc().TSFlags)) {
|
||||
if (MI->getOperand(2).getReg() == RISCV::X0) {
|
||||
|
||||
if (MI->getOperand(2).isReg() && MI->getOperand(2).getReg() == RISCV::X0) {
|
||||
OutStreamer->emitInstruction(MCInstBuilder(MI->getOpcode())
|
||||
.addReg(MI->getOperand(0).getReg())
|
||||
.addReg(MI->getOperand(1).getReg())
|
||||
|
|
|
@ -54,6 +54,11 @@ static cl::opt<bool>
|
|||
cl::desc("Enable the machine combiner pass"),
|
||||
cl::init(true), cl::Hidden);
|
||||
|
||||
static cl::opt<bool> EnableCommonDataLayout(
|
||||
"riscv-common-data-layout",
|
||||
cl::desc("Enable the common data layout for other language(not OpenCL)"),
|
||||
cl::init(false), cl::Hidden);
|
||||
|
||||
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVTarget() {
|
||||
RegisterTargetMachine<RISCVTargetMachine> X(getTheRISCV32Target());
|
||||
RegisterTargetMachine<RISCVTargetMachine> Y(getTheRISCV64Target());
|
||||
|
@ -71,8 +76,14 @@ static StringRef computeDataLayout(const Triple &TT, StringRef CPU) {
|
|||
// if (CPU == "ventus-gpgpu")
|
||||
// return "e-m:e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256"
|
||||
// "-v256:256-v512:512-v1024:1024-n32:64-S128-A5-G1";
|
||||
|
||||
if (TT.isArch64Bit())
|
||||
bool IsRV32 = TT.isRISCV32();
|
||||
if (EnableCommonDataLayout) {
|
||||
if(IsRV32)
|
||||
return "e-m:e-p:32:32-i64:64-n32-S128";
|
||||
else
|
||||
return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128";
|
||||
}
|
||||
if(!IsRV32)
|
||||
return "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128-A5-G1";
|
||||
assert(TT.isArch32Bit() && "only RV32 and RV64 are currently supported");
|
||||
return "e-m:e-p:32:32-i64:64-n32-S128-A5-G1";
|
||||
|
@ -94,7 +105,6 @@ RISCVTargetMachine::RISCVTargetMachine(const Target &T, const Triple &TT,
|
|||
getEffectiveCodeModel(CM, CodeModel::Small), OL),
|
||||
TLOF(std::make_unique<RISCVELFTargetObjectFile>()) {
|
||||
initAsmInfo();
|
||||
|
||||
// RISC-V supports the MachineOutliner.
|
||||
setMachineOutliner(true);
|
||||
setSupportsDefaultOutlining(true);
|
||||
|
@ -129,7 +139,8 @@ RISCVTargetMachine::getSubtargetImpl(const Function &F) const {
|
|||
}
|
||||
ABIName = ModuleTargetABI->getString();
|
||||
}
|
||||
I = std::make_unique<RISCVSubtarget>(TargetTriple, CPU, TuneCPU, FS, ABIName, *this);
|
||||
I = std::make_unique<RISCVSubtarget>(TargetTriple, CPU, TuneCPU, FS,
|
||||
ABIName, *this);
|
||||
}
|
||||
return I.get();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue