1 //===- Target.h - target specific details -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef FORTRAN_OPTMIZER_CODEGEN_TARGET_H
14 #define FORTRAN_OPTMIZER_CODEGEN_TARGET_H
15 
16 #include "flang/Optimizer/Support/KindMapping.h"
17 #include "mlir/IR/BuiltinTypes.h"
18 #include "llvm/ADT/Triple.h"
19 #include <memory>
20 #include <tuple>
21 #include <vector>
22 
23 namespace fir {
24 
25 namespace details {
26 /// Extra information about how to marshal an argument or return value that
27 /// modifies a signature per a particular ABI's calling convention.
28 /// Note: llvm::Attribute is not used directly, because its use depends on an
29 /// LLVMContext.
30 class Attributes {
31 public:
32   Attributes(unsigned short alignment = 0, bool byval = false,
33              bool sret = false, bool append = false)
34       : alignment{alignment}, byval{byval}, sret{sret}, append{append} {}
35 
getAlignment()36   unsigned getAlignment() const { return alignment; }
hasAlignment()37   bool hasAlignment() const { return alignment != 0; }
isByVal()38   bool isByVal() const { return byval; }
isSRet()39   bool isSRet() const { return sret; }
isAppend()40   bool isAppend() const { return append; }
41 
42 private:
43   unsigned short alignment{};
44   bool byval : 1;
45   bool sret : 1;
46   bool append : 1;
47 };
48 
49 } // namespace details
50 
51 /// Some details of how to represent certain features depend on the target and
52 /// ABI that is being used.  These specifics are captured here and guide the
53 /// lowering of FIR to LLVM-IR dialect.
54 class CodeGenSpecifics {
55 public:
56   using Attributes = details::Attributes;
57   using Marshalling = std::vector<std::tuple<mlir::Type, Attributes>>;
58 
59   static std::unique_ptr<CodeGenSpecifics>
60   get(mlir::MLIRContext *ctx, llvm::Triple &&trp, KindMapping &&kindMap);
61 
CodeGenSpecifics(mlir::MLIRContext * ctx,llvm::Triple && trp,KindMapping && kindMap)62   CodeGenSpecifics(mlir::MLIRContext *ctx, llvm::Triple &&trp,
63                    KindMapping &&kindMap)
64       : context{*ctx}, triple{std::move(trp)}, kindMap{std::move(kindMap)} {}
65   CodeGenSpecifics() = delete;
~CodeGenSpecifics()66   virtual ~CodeGenSpecifics() {}
67 
68   /// Type presentation of a `complex<ele>` type value in memory.
69   virtual mlir::Type complexMemoryType(mlir::Type eleTy) const = 0;
70 
71   /// Type representation of a `complex<eleTy>` type argument when passed by
72   /// value. An argument value may need to be passed as a (safe) reference
73   /// argument.
74   virtual Marshalling complexArgumentType(mlir::Location loc,
75                                           mlir::Type eleTy) const = 0;
76 
77   /// Type representation of a `complex<eleTy>` type return value. Such a return
78   /// value may need to be converted to a hidden reference argument.
79   virtual Marshalling complexReturnType(mlir::Location loc,
80                                         mlir::Type eleTy) const = 0;
81 
82   /// Type presentation of a `boxchar<n>` type value in memory.
83   virtual mlir::Type boxcharMemoryType(mlir::Type eleTy) const = 0;
84 
85   /// Type representation of a `boxchar<n>` type argument when passed by value.
86   /// An argument value may need to be passed as a (safe) reference argument.
87   ///
88   /// A function that returns a `boxchar<n>` type value must already have
89   /// converted that return value to a parameter decorated with the 'sret'
90   /// Attribute (https://llvm.org/docs/LangRef.html#parameter-attributes).
91   /// This requirement is in keeping with Fortran semantics, which require the
92   /// caller to allocate the space for the return CHARACTER value and pass
93   /// a pointer and the length of that space (a boxchar) to the called function.
94   virtual Marshalling boxcharArgumentType(mlir::Type eleTy,
95                                           bool sret = false) const = 0;
96 
97 protected:
98   mlir::MLIRContext &context;
99   llvm::Triple triple;
100   KindMapping kindMap;
101 };
102 
103 } // namespace fir
104 
105 #endif // FORTRAN_OPTMIZER_CODEGEN_TARGET_H
106