Skip to content

Commit

Permalink
Move string literal generation to ConstantGen.
Browse files Browse the repository at this point in the history
  • Loading branch information
deadalnix committed Jan 3, 2024
1 parent 38d56b2 commit 39f39ba
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 39 deletions.
37 changes: 2 additions & 35 deletions src/d/llvm/codegen.d
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ final class CodeGen {
import d.llvm.runtime;
RuntimeData runtimeData;

private LLVMValueRef[string] stringLiterals;
import d.llvm.constant;
ConstantData constantData;

import d.llvm.statement;
StatementGenData statementGenData;
Expand Down Expand Up @@ -136,40 +137,6 @@ final class CodeGen {
return m;
}

private auto buildStringConstant(string str)
in(str.length <= uint.max, "string length must be < uint.max") {
return stringLiterals.get(str, stringLiterals[str] = {
auto charArray =
LLVMConstStringInContext(llvmCtx, str.ptr,
cast(uint) str.length, true);

auto type = LLVMTypeOf(charArray);
auto globalVar = LLVMAddGlobal(dmodule, type, ".str");
LLVMSetInitializer(globalVar, charArray);
LLVMSetLinkage(globalVar, LLVMLinkage.Private);
LLVMSetGlobalConstant(globalVar, true);
LLVMSetUnnamedAddr(globalVar, true);

auto zero = LLVMConstInt(i32, 0, true);
LLVMValueRef[2] indices = [zero, zero];
return LLVMConstInBoundsGEP2(type, globalVar, indices.ptr,
indices.length);
}());
}

auto buildCString(string str) {
import std.string;
auto cstr = str.toStringz()[0 .. str.length + 1];
return buildStringConstant(cstr);
}

auto buildDString(string str) {
LLVMValueRef[2] slice =
[LLVMConstInt(i64, str.length, false), buildStringConstant(str)];
return
LLVMConstStructInContext(llvmCtx, slice.ptr, slice.length, false);
}

auto checkModule() {
char* errorPtr;
if (!LLVMVerifyModule(dmodule, LLVMVerifierFailureAction.ReturnStatus,
Expand Down
47 changes: 47 additions & 0 deletions src/d/llvm/constant.d
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import util.visitor;

import llvm.c.core;

struct ConstantData {
private:
LLVMValueRef[string] stringLiterals;
}

struct ConstantGen {
private CodeGen pass;
alias pass this;
Expand All @@ -17,6 +22,14 @@ struct ConstantGen {
this.pass = pass;
}

// XXX: lack of multiple alias this, so we do it automanually.
private {
@property
ref LLVMValueRef[string] stringLiterals() {
return pass.constantData.stringLiterals;
}
}

LLVMValueRef visit(Constant c) {
return this.dispatch(c);
}
Expand Down Expand Up @@ -59,6 +72,40 @@ struct ConstantGen {
return buildCString(cs.value);
}

private auto buildStringConstant(string str)
in(str.length <= uint.max, "string length must be < uint.max") {
return stringLiterals.get(str, stringLiterals[str] = {
auto charArray =
LLVMConstStringInContext(llvmCtx, str.ptr,
cast(uint) str.length, true);

auto type = LLVMTypeOf(charArray);
auto globalVar = LLVMAddGlobal(dmodule, type, ".str");
LLVMSetInitializer(globalVar, charArray);
LLVMSetLinkage(globalVar, LLVMLinkage.Private);
LLVMSetGlobalConstant(globalVar, true);
LLVMSetUnnamedAddr(globalVar, true);

auto zero = LLVMConstInt(i32, 0, true);
LLVMValueRef[2] indices = [zero, zero];
return LLVMConstInBoundsGEP2(type, globalVar, indices.ptr,
indices.length);
}());
}

auto buildCString(string str) {
import std.string;
auto cstr = str.toStringz()[0 .. str.length + 1];
return buildStringConstant(cstr);
}

auto buildDString(string str) {
LLVMValueRef[2] slice =
[LLVMConstInt(i64, str.length, false), buildStringConstant(str)];
return
LLVMConstStructInContext(llvmCtx, slice.ptr, slice.length, false);
}

// XXX: This should be removed at some point, but to ease transition.
LLVMValueRef visit(Expression e) {
if (auto ce = cast(CompileTimeExpression) e) {
Expand Down
12 changes: 8 additions & 4 deletions src/d/llvm/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,11 @@ struct RuntimeGen {
auto genHalt(Location location, LLVMValueRef message) {
auto floc = location.getFullLocation(context);

import d.llvm.constant;
auto str = ConstantGen(pass.pass)
.buildDString(floc.getSource().getFileName().toString());
LLVMValueRef[3] args =
[message, buildDString(floc.getSource().getFileName().toString()),
LLVMConstInt(i32, floc.getStartLineNumber(), false), ];
[message, str, LLVMConstInt(i32, floc.getStartLineNumber(), false)];

return message
? ExpressionGen(pass).callGlobal(getAssertFailMsgFunction(), args)
Expand All @@ -155,9 +157,11 @@ struct RuntimeGen {
auto genArrayOutOfBounds(Location location) {
auto floc = location.getFullLocation(context);

import d.llvm.constant;
auto str = ConstantGen(pass.pass)
.buildDString(floc.getSource().getFileName().toString());
LLVMValueRef[2] args =
[buildDString(floc.getSource().getFileName().toString()),
LLVMConstInt(i32, floc.getStartLineNumber(), false), ];
[str, LLVMConstInt(i32, floc.getStartLineNumber(), false)];

return
ExpressionGen(pass).callGlobal(getArrayOutOfBoundsFunction(), args);
Expand Down

0 comments on commit 39f39ba

Please sign in to comment.