Skip to content
Draft
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion driver/cl_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ cl::opt<unsigned>
cl::desc("Warn for stack size bigger than the given number"),
cl::value_desc("threshold"));

#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX
#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64
cl::list<std::string>
dcomputeTargets("mdcompute-targets", cl::CommaSeparated,
cl::desc("Generates code for the specified DCompute target"
Expand Down
2 changes: 1 addition & 1 deletion driver/cl_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ extern cl::opt<std::string> saveOptimizationRecord;

extern cl::opt<unsigned> fWarnStackSize;

#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX
#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64
extern cl::list<std::string> dcomputeTargets;
extern cl::opt<std::string> dcomputeFilePrefix;
#endif
Expand Down
13 changes: 11 additions & 2 deletions driver/dcomputecodegenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <string>
#include <algorithm>

#if !(LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX)
#if !(LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64)

DComputeCodeGenManager::DComputeCodeGenManager(llvm::LLVMContext &c) : ctx(c) {}
void DComputeCodeGenManager::emit(Module *) {}
Expand All @@ -43,6 +43,14 @@ DComputeCodeGenManager::createComputeTarget(const std::string &s) {
#endif
}

if (s.substr(0, 6) == "air64-") {
#if LDC_LLVM_SUPPORTED_TARGET_AArch64 //&& LDC_LLVM_VER >= 2100
return createMetalTarget(ctx, 64);
#else
error(Loc(), "LDC was not built with Apple Metal Dcompute support!");
#endif
}

if (s.substr(0, 5) == "cuda-") {
#if LDC_LLVM_SUPPORTED_TARGET_NVPTX
#define CUDA_VALID_VER_INIT 100, 110, 120, 130, 200, 210, 300, 350, 370,\
Expand All @@ -59,6 +67,7 @@ DComputeCodeGenManager::createComputeTarget(const std::string &s) {
#endif
}


Comment thread
thewilsonator marked this conversation as resolved.
Outdated
#define STR(...) #__VA_ARGS__
#define XSTR(x) STR(x)

Expand Down Expand Up @@ -106,4 +115,4 @@ DComputeCodeGenManager::~DComputeCodeGenManager() {
gTargetMachine = oldGTargetMachine;
}

#endif // LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX
#endif // LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64
2 changes: 1 addition & 1 deletion driver/dcomputecodegenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace llvm {
class DComputeCodeGenManager {

llvm::LLVMContext &ctx;
llvm::SmallVector<DComputeTarget *, 2> targets;
llvm::SmallVector<DComputeTarget *, 3> targets;
DComputeTarget *createComputeTarget(const std::string &s);
IRState *oldGIR = nullptr;
llvm::TargetMachine *oldGTargetMachine = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion driver/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ void registerPredefinedVersions() {
VersionCondition::addPredefinedGlobalIdent("all");
VersionCondition::addPredefinedGlobalIdent("D_Version2");

#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX
#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64
if (dcomputeTargets.size() != 0) {
VersionCondition::addPredefinedGlobalIdent("LDC_DCompute");
}
Expand Down
10 changes: 7 additions & 3 deletions gen/abi/abi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@

#include "dmd/argtypes.h"
#include "dmd/expression.h"
#include "dmd/id.h"
#include "dmd/identifier.h"
#include "dmd/target.h"
#include "gen/abi/targets.h"
#include "gen/abi/generic.h"
Expand All @@ -24,7 +22,6 @@
#include "gen/tollvm.h"
#include "ir/irfunction.h"
#include "ir/irfuncty.h"
#include <algorithm>

using namespace dmd;

Expand Down Expand Up @@ -286,6 +283,13 @@ TargetABI *TargetABI::getTarget() {
case llvm::Triple::wasm32:
case llvm::Triple::wasm64:
return getWasmTargetABI();

case llvm::Triple::UnknownArch:
if (global.params.targetTriple->getArchName() == "air64") {
return createMetalABI();
}
// fallthrough

default:
warning(Loc(),
"unknown target ABI, falling back to generic implementation. C/C++ "
Expand Down
61 changes: 61 additions & 0 deletions gen/abi/metal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//===-- gen/abi-metal.cpp ---------------------------------------*- C++ -*-===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//

#include "gen/abi/abi.h"
#include "gen/dcompute/druntime.h"
#include "gen/dcompute/abi-rewrites.h"
#include "ir/irfuncty.h"
#include "dmd/mtype.h"
#include <optional>


using namespace dmd;

struct MetalABI : TargetABI {
DComputePointerRewrite pointerRewite;
DcomputeMetalScalarRewrite metalScalarRewrite;

auto returnInArg(TypeFunction *tf, bool needsThis) -> bool override {
return false;
}

auto passByVal(TypeFunction *tf, Type*t) -> bool override {
return false;
}

void rewriteFunctionType(IrFuncTy &fty) override {
for (auto arg : fty.args) {
if (!arg->byref) {
rewriteArgument(fty, *arg);
}
}
}

void rewriteArgument(IrFuncTy &fty, IrFuncTyArg &arg) override {
TargetABI::rewriteArgument(fty, arg);

if (arg.rewrite) {
return;
}

Type *ty = arg.type->toBasetype();
std::optional<DcomputePointer> ptr;

if (ty->ty == TY::Tstruct &&
(ptr = toDcomputePointer(static_cast<TypeStruct *>(ty)->sym))) {
pointerRewite.applyTo(arg);
}

if (ty->isScalar()) {
metalScalarRewrite.applyTo(arg);
}
}
};

TargetABI* createMetalABI() { return new MetalABI(); }
2 changes: 2 additions & 0 deletions gen/abi/targets.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ TargetABI *getX86TargetABI();
TargetABI *getLoongArch64TargetABI();

TargetABI *getWasmTargetABI();

TargetABI* createMetalABI();
17 changes: 17 additions & 0 deletions gen/dcompute/abi-rewrites.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#pragma once

#include "gen/abi/generic.h"
#include "gen/dcompute/druntime.h"
Comment thread
thewilsonator marked this conversation as resolved.
Outdated

struct DComputePointerRewrite : ABIRewrite {
LLValue *put(DValue *v, bool isLValueExp, bool) override {
Expand All @@ -32,3 +33,19 @@ struct DComputePointerRewrite : ABIRewrite {
return ptr->toLLVMType(true);
}
};

struct DcomputeMetalScalarRewrite : ABIRewrite {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this now unused?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it still used in abi/metal.cpp file:

struct MetalABI : TargetABI {
    DComputePointerRewrite pointerRewite;
    DcomputeMetalScalarRewrite metalScalarRewrite;
.....

It is used to make scalar objects turn into a pointer in constant memory address space. Although it turns out scalars can also be stored in device level address space which will be Global in the dcompute term as I understand

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scalar arguments to kernels are just passed as parameters

LLType *type(Type* t) override {
// XXXX: Scalar variables are stored in the constant memory space for Metal GPU
return llvm::PointerType::get(gIR->context(), 2/*Constant Memory space*/);
}

LLValue *getLVal(Type *dty, LLValue *v) override {
return v;
}

LLValue *put(DValue *v, bool isLValueExp, bool) override {
auto value = DtoRVal(v);
return value;
}
};
2 changes: 1 addition & 1 deletion gen/dcompute/target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//
//===----------------------------------------------------------------------===//

#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX
#if LDC_LLVM_SUPPORTED_TARGET_SPIRV || LDC_LLVM_SUPPORTED_TARGET_NVPTX || LDC_LLVM_SUPPORTED_TARGET_AArch64

#include "dmd/dsymbol.h"
#include "dmd/errors.h"
Expand Down
6 changes: 5 additions & 1 deletion gen/dcompute/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class DComputeTarget {
public:
llvm::LLVMContext &ctx;
int tversion; // OpenCL or CUDA CC version:major*100 + minor*10
enum class ID { Host = 0, OpenCL = 1, CUDA = 2 };
enum class ID { Host = 0, OpenCL = 1, CUDA = 2, Metal = 3 };
ID target; // ID for codegen time conditional compilation.
const char *short_name;
const char *binSuffix;
Expand Down Expand Up @@ -58,6 +58,10 @@ class DComputeTarget {
DComputeTarget *createCUDATarget(llvm::LLVMContext &c, int sm);
#endif

#if LDC_LLVM_SUPPORTED_TARGET_AArch64
DComputeTarget* createMetalTarget(llvm::LLVMContext &c, int version);
#endif

#if LDC_LLVM_SUPPORTED_TARGET_SPIRV
DComputeTarget *createOCLTarget(llvm::LLVMContext &c, int oclver);
#endif
Loading
Loading