Skip to content

Commit e4215bc

Browse files
Allow passing LLVM downstream args to LLVMBuilder (#9491)
This allows the user to directly set LLVM backend options, e.g. `-Xllvm... -unroll-count=0 -vectorize-loops=false -X.`. These parameters are the ones you can set with `-mllvm` in Clang, i.e. the LLVM backend parameters instead of Clang frontend parameters. (I'm trying to get Slang's LLVM emitter to produce object code that I can run on the Raspberry Pi Pico 2's Cortex M33 and need access to these options for that purpose, but I think these will also be useful for debugging the LLVM optimization passes later on.) --------- Co-authored-by: Ellie Hermaszewska <ellieh@nvidia.com>
1 parent 0528cdf commit e4215bc

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

source/slang-llvm/slang-llvm-builder.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "slang-llvm-jit-shared-library.h"
55

66
#include "llvm/AsmParser/Parser.h"
7+
#include "llvm/CodeGen/CommandFlags.h"
78
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
89
#include "llvm/IR/BasicBlock.h"
910
#include "llvm/IR/Constants.h"
@@ -39,6 +40,10 @@ namespace slang_llvm
3940

4041
using namespace Slang;
4142

43+
// This instance needs to exist so that we gain access to codegen flags in the
44+
// downstream arguments.
45+
static llvm::codegen::RegisterCodeGenFlags CGF;
46+
4247
// There doesn't appear to be an LLVM output stream for writing into a memory
4348
// buffer. This implementation saves all written data directly into Slang's List
4449
// type.
@@ -502,6 +507,30 @@ LLVMBuilder::LLVMBuilder(LLVMBuilderOptions options, IArtifact** outErrorArtifac
502507

503508
byteType = llvmBuilder->getInt8Ty();
504509

510+
// ParseCommandLineOptions below assumes that the first parameter is the
511+
// name of the executable, but we do this cute trick to make it complain
512+
// about parameters forwarded to LLVM instead:
513+
std::vector<const char*> llvmArgs = {"-Xllvm"};
514+
for (TerminatedCharSlice arg : options.llvmArguments)
515+
llvmArgs.push_back(arg.data);
516+
517+
// Parse LLVM options. These can be used to adjust the behavior of various
518+
// LLVM passes.
519+
llvm::raw_string_ostream errorStream(error);
520+
if (!llvm::cl::ParseCommandLineOptions(
521+
llvmArgs.size(),
522+
llvmArgs.data(),
523+
"slangc",
524+
&errorStream))
525+
{
526+
ArtifactDiagnostic diagnostic;
527+
diagnostic.severity = ArtifactDiagnostic::Severity::Error;
528+
diagnostic.stage = ArtifactDiagnostic::Stage::Link;
529+
diagnostic.text = TerminatedCharSlice(error.c_str(), error.length());
530+
*outErrorArtifact = createErrorArtifact(diagnostic);
531+
return;
532+
}
533+
505534
if (options.debugLevel != SLANG_DEBUG_INFO_LEVEL_NONE)
506535
{
507536
llvmModule->addModuleFlag(
@@ -2244,7 +2273,7 @@ SlangResult LLVMBuilder::generateJITLibrary(IArtifact** outArtifact)
22442273

22452274
} // namespace slang_llvm
22462275

2247-
extern "C" SLANG_DLL_EXPORT SlangResult createLLVMBuilder_V1(
2276+
extern "C" SLANG_DLL_EXPORT SlangResult createLLVMBuilder_V2(
22482277
const SlangUUID& intfGuid,
22492278
Slang::ILLVMBuilder** out,
22502279
Slang::LLVMBuilderOptions options,

source/slang-llvm/slang-llvm-builder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ struct LLVMBuilderOptions
7070
SlangFpDenormalMode fp32DenormalMode;
7171
SlangFpDenormalMode fp64DenormalMode;
7272
SlangFloatingPointMode fpMode;
73+
Slice<TerminatedCharSlice> llvmArguments;
7374
};
7475

7576
enum LLVMAttribute : uint32_t

source/slang/slang-emit-llvm.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -789,13 +789,13 @@ struct LLVMEmitter
789789
return SLANG_FAIL;
790790
}
791791

792-
using BuilderFuncV1 = SlangResult (*)(
792+
using BuilderFuncV2 = SlangResult (*)(
793793
const SlangUUID& intfGuid,
794794
Slang::ILLVMBuilder** out,
795795
Slang::LLVMBuilderOptions options,
796796
Slang::IArtifact** outErrorArtifact);
797797

798-
auto builderFunc = (BuilderFuncV1)library->findFuncByName("createLLVMBuilder_V1");
798+
auto builderFunc = (BuilderFuncV2)library->findFuncByName("createLLVMBuilder_V2");
799799
if (!builderFunc)
800800
return SLANG_FAIL;
801801

@@ -828,6 +828,12 @@ struct LLVMEmitter
828828
builderOpt.fp64DenormalMode = (SlangFpDenormalMode)getOptions().getDenormalModeFp64();
829829
builderOpt.fpMode = (SlangFloatingPointMode)getOptions().getFloatingPointMode();
830830

831+
List<TerminatedCharSlice> llvmArguments;
832+
List<String> downstreamArgs = getOptions().getDownstreamArgs("llvm");
833+
for (const auto& arg : downstreamArgs)
834+
llvmArguments.add(TerminatedCharSlice(arg.getBuffer()));
835+
builderOpt.llvmArguments = Slice(llvmArguments.begin(), llvmArguments.getCount());
836+
831837
ComPtr<IArtifact> errorArtifact;
832838
SLANG_RETURN_ON_FAIL(builderFunc(
833839
ILLVMBuilder::getTypeGuid(),

0 commit comments

Comments
 (0)