Skip to content

Commit

Permalink
CodeGen: plumb header search down to the IAS
Browse files Browse the repository at this point in the history
inline assembly may use the `.include` directive to include other
content into the file.  Without the integrated assembler, the `-I` group
gets passed to the assembler.  Emulate this by collecting the header
search paths and passing them to the IAS.

Resolves PR24811!

llvm-svn: 291123
  • Loading branch information
compnerd committed Jan 5, 2017
1 parent bca02f9 commit 888e289
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 20 deletions.
4 changes: 3 additions & 1 deletion clang/include/clang/CodeGen/BackendUtil.h
Expand Up @@ -21,6 +21,7 @@ namespace llvm {

namespace clang {
class DiagnosticsEngine;
class HeaderSearchOptions;
class CodeGenOptions;
class TargetOptions;
class LangOptions;
Expand All @@ -34,7 +35,8 @@ namespace clang {
Backend_EmitObj ///< Emit native object files
};

void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts,
void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &,
const CodeGenOptions &CGOpts,
const TargetOptions &TOpts, const LangOptions &LOpts,
const llvm::DataLayout &TDesc, llvm::Module *M,
BackendAction Action,
Expand Down
30 changes: 22 additions & 8 deletions clang/lib/CodeGen/BackendUtil.cpp
Expand Up @@ -14,6 +14,7 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Frontend/Utils.h"
#include "clang/Lex/HeaderSearchOptions.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
Expand All @@ -32,6 +33,7 @@
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Verifier.h"
#include "llvm/LTO/LTOBackend.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
#include "llvm/Passes/PassBuilder.h"
Expand Down Expand Up @@ -61,6 +63,7 @@ namespace {

class EmitAssemblyHelper {
DiagnosticsEngine &Diags;
const HeaderSearchOptions &HSOpts;
const CodeGenOptions &CodeGenOpts;
const clang::TargetOptions &TargetOpts;
const LangOptions &LangOpts;
Expand Down Expand Up @@ -100,11 +103,14 @@ class EmitAssemblyHelper {
raw_pwrite_stream &OS);

public:
EmitAssemblyHelper(DiagnosticsEngine &_Diags, const CodeGenOptions &CGOpts,
EmitAssemblyHelper(DiagnosticsEngine &_Diags,
const HeaderSearchOptions &HeaderSearchOpts,
const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts,
const LangOptions &LOpts, Module *M)
: Diags(_Diags), CodeGenOpts(CGOpts), TargetOpts(TOpts), LangOpts(LOpts),
TheModule(M), CodeGenerationTime("codegen", "Code Generation Time") {}
: Diags(_Diags), HSOpts(HeaderSearchOpts), CodeGenOpts(CGOpts),
TargetOpts(TOpts), LangOpts(LOpts), TheModule(M),
CodeGenerationTime("codegen", "Code Generation Time") {}

~EmitAssemblyHelper() {
if (CodeGenOpts.DisableFree)
Expand Down Expand Up @@ -584,12 +590,18 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Options.MCOptions.MCNoExecStack = CodeGenOpts.NoExecStack;
Options.MCOptions.MCIncrementalLinkerCompatible =
CodeGenOpts.IncrementalLinkerCompatible;
Options.MCOptions.MCPIECopyRelocations =
CodeGenOpts.PIECopyRelocations;
Options.MCOptions.MCPIECopyRelocations = CodeGenOpts.PIECopyRelocations;
Options.MCOptions.MCFatalWarnings = CodeGenOpts.FatalWarnings;
Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose;
Options.MCOptions.PreserveAsmComments = CodeGenOpts.PreserveAsmComments;
Options.MCOptions.ABIName = TargetOpts.ABI;
for (const auto &Entry : HSOpts.UserEntries)
if (!Entry.IsFramework &&
(Entry.Group == frontend::IncludeDirGroup::Quoted ||
Entry.Group == frontend::IncludeDirGroup::Angled ||
Entry.Group == frontend::IncludeDirGroup::System))
Options.MCOptions.IASSearchPaths.push_back(
Entry.IgnoreSysRoot ? Entry.Path : HSOpts.Sysroot + Entry.Path);

TM.reset(TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr,
Options, RM, CM, OptLevel));
Expand Down Expand Up @@ -929,17 +941,19 @@ static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
}

void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
const HeaderSearchOptions &HeaderOpts,
const CodeGenOptions &CGOpts,
const clang::TargetOptions &TOpts,
const LangOptions &LOpts, const llvm::DataLayout &TDesc,
Module *M, BackendAction Action,
const LangOptions &LOpts,
const llvm::DataLayout &TDesc, Module *M,
BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS) {
if (!CGOpts.ThinLTOIndexFile.empty()) {
runThinLTOBackend(CGOpts, M, std::move(OS));
return;
}

EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
EmitAssemblyHelper AsmHelper(Diags, HeaderOpts, CGOpts, TOpts, LOpts, M);

if (CGOpts.ExperimentalNewPassManager)
AsmHelper.EmitAssemblyWithNewPassManager(Action, std::move(OS));
Expand Down
16 changes: 9 additions & 7 deletions clang/lib/CodeGen/CodeGenAction.cpp
Expand Up @@ -44,6 +44,7 @@ namespace clang {
virtual void anchor();
DiagnosticsEngine &Diags;
BackendAction Action;
const HeaderSearchOptions &HeaderSearchOpts;
const CodeGenOptions &CodeGenOpts;
const TargetOptions &TargetOpts;
const LangOptions &LangOpts;
Expand Down Expand Up @@ -77,8 +78,8 @@ namespace clang {
const SmallVectorImpl<std::pair<unsigned, llvm::Module *>> &LinkModules,
std::unique_ptr<raw_pwrite_stream> OS, LLVMContext &C,
CoverageSourceInfo *CoverageInfo = nullptr)
: Diags(Diags), Action(Action), CodeGenOpts(CodeGenOpts),
TargetOpts(TargetOpts), LangOpts(LangOpts),
: Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts),
CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts),
AsmOutStream(std::move(OS)), Context(nullptr),
LLVMIRGeneration("irgen", "LLVM IR Generation Time"),
LLVMIRGenerationRefCount(0),
Expand Down Expand Up @@ -225,8 +226,8 @@ namespace clang {

EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef());

EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
C.getTargetInfo().getDataLayout(),
EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
LangOpts, C.getTargetInfo().getDataLayout(),
getModule(), Action, std::move(AsmOutStream));

Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
Expand Down Expand Up @@ -898,9 +899,10 @@ void CodeGenAction::ExecuteAction() {
Ctx.setInlineAsmDiagnosticHandler(BitcodeInlineAsmDiagHandler,
&CI.getDiagnostics());

EmitBackendOutput(CI.getDiagnostics(), CI.getCodeGenOpts(), TargetOpts,
CI.getLangOpts(), CI.getTarget().getDataLayout(),
TheModule.get(), BA, std::move(OS));
EmitBackendOutput(CI.getDiagnostics(), CI.getHeaderSearchOpts(),
CI.getCodeGenOpts(), TargetOpts, CI.getLangOpts(),
CI.getTarget().getDataLayout(), TheModule.get(), BA,
std::move(OS));
return;
}

Expand Down
9 changes: 5 additions & 4 deletions clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
Expand Up @@ -282,17 +282,18 @@ class PCHContainerGenerator : public ASTConsumer {
// Print the IR for the PCH container to the debug output.
llvm::SmallString<0> Buffer;
clang::EmitBackendOutput(
Diags, CodeGenOpts, TargetOpts, LangOpts,
Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
Ctx.getTargetInfo().getDataLayout(), M.get(),
BackendAction::Backend_EmitLL,
llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
llvm::dbgs() << Buffer;
});

// Use the LLVM backend to emit the pch container.
clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
Ctx.getTargetInfo().getDataLayout(), M.get(),
BackendAction::Backend_EmitObj, std::move(OS));
clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
LangOpts, Ctx.getTargetInfo().getDataLayout(),
M.get(), BackendAction::Backend_EmitObj,
std::move(OS));

// Free the memory for the temporary buffer.
llvm::SmallVector<char, 0> Empty;
Expand Down
1 change: 1 addition & 0 deletions clang/test/CodeGen/include/function.x
@@ -0,0 +1 @@
FUNCTION = 1
1 change: 1 addition & 0 deletions clang/test/CodeGen/include/module.x
@@ -0,0 +1 @@
MODULE = 1
10 changes: 10 additions & 0 deletions clang/test/CodeGen/inline-asm-inclusion.c
@@ -0,0 +1,10 @@
// RUN: %clang_cc1 -I %p/include -S -o - %s | FileCheck %s

__asm__(".include \"module.x\"");
void function(void) {
__asm__(".include \"function.x\"");
}

// CHECK: MODULE = 1
// CHECK: FUNCTION = 1

0 comments on commit 888e289

Please sign in to comment.