Skip to content

Commit

Permalink
[Flang][Driver]Add datalayout before doing LLVM-IR transformation
Browse files Browse the repository at this point in the history
The earlier available datalyaout allows MLIR to LLVM-IR transformation
to use the datalayout for decisions, such as comparing sizes for
different types of integers.

This should solve #57230

Reviewed By: awarzynski, vzakhari

Differential Revision: https://reviews.llvm.org/D133568
  • Loading branch information
Leporacanthicus committed Nov 3, 2022
1 parent 691774d commit 8118108
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 13 deletions.
2 changes: 1 addition & 1 deletion flang/include/flang/Frontend/FrontendActions.h
Expand Up @@ -199,7 +199,7 @@ class CodeGenAction : public FrontendAction {
void executeAction() override;
/// Runs prescan, parsing, sema and lowers to MLIR.
bool beginSourceFileAction() override;
/// Sets up LLVM's TargetMachine, configures llvmModule accordingly.
/// Sets up LLVM's TargetMachine.
void setUpTargetMachine();
/// Runs the optimization (aka middle-end) pipeline on the LLVM module
/// associated with this action.
Expand Down
2 changes: 1 addition & 1 deletion flang/include/flang/Optimizer/Support/InitFIR.h
Expand Up @@ -32,7 +32,7 @@ namespace fir::support {
mlir::scf::SCFDialect, mlir::arith::ArithDialect, \
mlir::cf::ControlFlowDialect, mlir::func::FuncDialect, \
mlir::vector::VectorDialect, mlir::math::MathDialect, \
mlir::complex::ComplexDialect
mlir::complex::ComplexDialect, mlir::DLTIDialect

// The definitive list of dialects used by flang.
#define FLANG_DIALECT_LIST \
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Frontend/CMakeLists.txt
Expand Up @@ -36,6 +36,7 @@ add_flang_library(flangFrontend
MLIRTransforms
MLIRLLVMToLLVMIRTranslation
MLIRSCFToControlFlow
MLIRTargetLLVMIRImport
${dialect_libs}

LINK_COMPONENTS
Expand Down
47 changes: 37 additions & 10 deletions flang/lib/Frontend/FrontendActions.cpp
Expand Up @@ -34,6 +34,8 @@
#include "mlir/IR/Dialect.h"
#include "mlir/Parser/Parser.h"
#include "mlir/Pass/PassManager.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Target/LLVMIR/Import.h"
#include "mlir/Target/LLVMIR/ModuleTranslation.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticFrontend.h"
Expand Down Expand Up @@ -79,6 +81,16 @@ bool PrescanAndSemaDebugAction::beginSourceFileAction() {
(generateRtTypeTables() || true);
}

static void setMLIRDataLayout(mlir::ModuleOp &mlirModule,
const llvm::DataLayout &dl) {
mlir::MLIRContext *context = mlirModule.getContext();
mlirModule->setAttr(
mlir::LLVM::LLVMDialect::getDataLayoutAttrName(),
mlir::StringAttr::get(context, dl.getStringRepresentation()));
mlir::DataLayoutSpecInterface dlSpec = mlir::translateDataLayout(dl, context);
mlirModule->setAttr(mlir::DLTIDialect::kDataLayoutAttrName, dlSpec);
}

bool CodeGenAction::beginSourceFileAction() {
llvmCtx = std::make_unique<llvm::LLVMContext>();
CompilerInstance &ci = this->getInstance();
Expand Down Expand Up @@ -123,6 +135,9 @@ bool CodeGenAction::beginSourceFileAction() {
}

mlirModule = std::make_unique<mlir::ModuleOp>(module.release());
setUpTargetMachine();
const llvm::DataLayout &dl = tm->createDataLayout();
setMLIRDataLayout(*mlirModule, dl);
return true;
}

Expand Down Expand Up @@ -152,10 +167,15 @@ bool CodeGenAction::beginSourceFileAction() {
kindMap, ci.getInvocation().getLoweringOpts(),
ci.getInvocation().getFrontendOpts().envDefaults);

// Fetch module from lb, so we can set
mlirModule = std::make_unique<mlir::ModuleOp>(lb.getModule());
setUpTargetMachine();
const llvm::DataLayout &dl = tm->createDataLayout();
setMLIRDataLayout(*mlirModule, dl);

// Create a parse tree and lower it to FIR
Fortran::parser::Program &parseTree{*ci.getParsing().parseTree()};
lb.lower(parseTree, ci.getInvocation().getSemanticsContext());
mlirModule = std::make_unique<mlir::ModuleOp>(lb.getModule());

// run the default passes.
mlir::PassManager pm(mlirCtx.get(), mlir::OpPassManager::Nesting::Implicit);
Expand Down Expand Up @@ -565,13 +585,7 @@ getCGOptLevel(const Fortran::frontend::CodeGenOptions &opts) {
void CodeGenAction::setUpTargetMachine() {
CompilerInstance &ci = this->getInstance();

// Set the triple based on the CompilerInvocation set-up
const std::string &theTriple = ci.getInvocation().getTargetOpts().triple;
if (llvmModule->getTargetTriple() != theTriple) {
ci.getDiagnostics().Report(clang::diag::warn_fe_override_module)
<< theTriple;
llvmModule->setTargetTriple(theTriple);
}

// Create `Target`
std::string error;
Expand Down Expand Up @@ -735,6 +749,22 @@ void CodeGenAction::executeAction() {
if (!llvmModule)
generateLLVMIR();

// Set the triple based on the targetmachine (this comes compiler invocation
// and the command-line target option if specified, or the default if not
// given on the command-line).
setUpTargetMachine();
const std::string &theTriple = tm->getTargetTriple().str();

if (llvmModule->getTargetTriple() != theTriple) {
ci.getDiagnostics().Report(clang::diag::warn_fe_override_module)
<< theTriple;
}
// Always set the triple and data layout, to make sure they match and are set.
// Note that this overwrites any datalayout stored in the LLVM-IR. This avoids
// an assert for incompatible data layout when the code-generation happens.
llvmModule->setTargetTriple(theTriple);
llvmModule->setDataLayout(tm->createDataLayout());

// Run LLVM's middle-end (i.e. the optimizer).
runOptimizationPipeline(*os);

Expand All @@ -744,9 +774,6 @@ void CodeGenAction::executeAction() {
return;
}

setUpTargetMachine();
llvmModule->setDataLayout(tm->createDataLayout());

if (action == BackendActionTy::Backend_EmitBC) {
// This action has effectively been completed in runOptimizationPipeline.
return;
Expand Down
1 change: 1 addition & 0 deletions flang/test/Driver/emit-llvm.f90
Expand Up @@ -6,6 +6,7 @@
! RUN: %flang_fc1 -emit-llvm %s -o - | FileCheck %s

! CHECK: ; ModuleID = 'FIRModule'
! CHECK: target datalayout =
! CHECK: define void @_QQmain()
! CHECK-NEXT: ret void
! CHECK-NEXT: }
Expand Down
2 changes: 2 additions & 0 deletions flang/test/Driver/emit-mlir.f90
Expand Up @@ -10,6 +10,8 @@
! RUN: %flang_fc1 -emit-mlir emit-mlir.f90 && ls emit-mlir.mlir

! CHECK: module attributes {
! CHECK-SAME: dlti.dl_spec =
! CHECK-SAME: llvm.data_layout =
! CHECK-LABEL: func @_QQmain() {
! CHECK-NEXT: return
! CHECK-NEXT: }
Expand Down
2 changes: 1 addition & 1 deletion flang/test/Driver/pic-flags.f90
@@ -1,3 +1,4 @@
! REQUIRES: aarch64-registered-target && x86-registered-target && arm-registered-target
! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu -fno-pie 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-STATIC,CHECK-STATIC-IR

! RUN: %flang -v -S -emit-llvm -o - %s --target=aarch64-linux-gnu 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-PIE-LEVEL2,CHECK-PIE-LEVEL2-IR
Expand All @@ -14,7 +15,6 @@
! RUN: %flang -v -### -o - %s --target=arm-none-eabi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-RWPI
! RUN: %flang -v -### -o - %s --target=arm-none-eabi -fropi -frwpi 2>&1 | FileCheck %s --check-prefixes=CHECK,CHECK-ROPI-RWPI


! CHECK: -fc1


Expand Down
5 changes: 5 additions & 0 deletions flang/unittests/Frontend/FrontendActionTest.cpp
Expand Up @@ -178,6 +178,11 @@ TEST_F(FrontendActionTest, EmitLLVM) {
compInst.getInvocation().getTargetOpts().triple =
llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple());

// Initialise LLVM backend
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmPrinters();

// Set-up the output stream. We are using output buffer wrapped as an output
// stream, as opposed to an actual file (or a file descriptor).
llvm::SmallVector<char> outputFileBuffer;
Expand Down

0 comments on commit 8118108

Please sign in to comment.