Skip to content

Commit b19c39c

Browse files
committed
Merge commit 'd6ec7c82f383ae4268f350f4d2e267af45fae8c0' into users/meinersbur/flang_runtime_move-files
2 parents 956a58c + d6ec7c8 commit b19c39c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1394
-164
lines changed

clang/include/clang/Basic/Diagnostic.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,8 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
560560
ArgToStringFnTy ArgToStringFn;
561561

562562
/// Whether the diagnostic should be suppressed in FilePath.
563-
llvm::unique_function<bool(diag::kind, StringRef /*FilePath*/) const>
563+
llvm::unique_function<bool(diag::kind, SourceLocation /*DiagLoc*/,
564+
const SourceManager &) const>
564565
DiagSuppressionMapping;
565566

566567
public:
@@ -972,7 +973,7 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> {
972973
/// These take presumed locations into account, and can still be overriden by
973974
/// clang-diagnostics pragmas.
974975
void setDiagSuppressionMapping(llvm::MemoryBuffer &Input);
975-
bool isSuppressedViaMapping(diag::kind DiagId, StringRef FilePath) const;
976+
bool isSuppressedViaMapping(diag::kind DiagId, SourceLocation DiagLoc) const;
976977

977978
/// Issue the message to the client.
978979
///

clang/include/clang/CIR/Dialect/IR/CIROps.td

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_CIR_DIALECT_IR_CIROPS
1616

1717
include "clang/CIR/Dialect/IR/CIRDialect.td"
18+
include "clang/CIR/Dialect/IR/CIRTypes.td"
1819

1920
include "mlir/IR/BuiltinAttributeInterfaces.td"
2021
include "mlir/IR/EnumAttr.td"
@@ -74,6 +75,35 @@ class LLVMLoweringInfo {
7475
class CIR_Op<string mnemonic, list<Trait> traits = []> :
7576
Op<CIR_Dialect, mnemonic, traits>, LLVMLoweringInfo;
7677

78+
//===----------------------------------------------------------------------===//
79+
// GlobalOp
80+
//===----------------------------------------------------------------------===//
81+
82+
// TODO(CIR): For starters, cir.global has only name and type. The other
83+
// properties of a global variable will be added over time as more of ClangIR
84+
// is upstreamed.
85+
86+
def GlobalOp : CIR_Op<"global"> {
87+
let summary = "Declare or define a global variable";
88+
let description = [{
89+
The `cir.global` operation declares or defines a named global variable.
90+
91+
The backing memory for the variable is allocated statically and is
92+
described by the type of the variable.
93+
}];
94+
95+
let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type);
96+
97+
let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }];
98+
99+
let skipDefaultBuilders = 1;
100+
101+
let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name,
102+
"mlir::Type":$sym_type)>];
103+
104+
let hasVerifier = 1;
105+
}
106+
77107
//===----------------------------------------------------------------------===//
78108
// FuncOp
79109
//===----------------------------------------------------------------------===//
@@ -85,14 +115,15 @@ class CIR_Op<string mnemonic, list<Trait> traits = []> :
85115
def FuncOp : CIR_Op<"func"> {
86116
let summary = "Declare or define a function";
87117
let description = [{
88-
... lots of text to be added later ...
118+
The `cir.func` operation defines a function, similar to the `mlir::FuncOp`
119+
built-in.
89120
}];
90121

91122
let arguments = (ins SymbolNameAttr:$sym_name);
92123

93124
let skipDefaultBuilders = 1;
94125

95-
let builders = [OpBuilder<(ins "llvm::StringRef":$name)>];
126+
let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>];
96127

97128
let hasCustomAssemblyFormat = 1;
98129
let hasVerifier = 1;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//===----------------------------------------------------------------------===//
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+
// This file declares the types in the CIR dialect.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef MLIR_DIALECT_CIR_IR_CIRTYPES_H_
14+
#define MLIR_DIALECT_CIR_IR_CIRTYPES_H_
15+
16+
#include "mlir/IR/BuiltinAttributes.h"
17+
#include "mlir/IR/Types.h"
18+
#include "mlir/Interfaces/DataLayoutInterfaces.h"
19+
20+
//===----------------------------------------------------------------------===//
21+
// CIR Dialect Tablegen'd Types
22+
//===----------------------------------------------------------------------===//
23+
24+
#define GET_TYPEDEF_CLASSES
25+
#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc"
26+
27+
#endif // MLIR_DIALECT_CIR_IR_CIRTYPES_H_
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
//===- CIRTypes.td - CIR dialect types ---------------------*- tablegen -*-===//
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+
// This file declares the CIR dialect types.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef MLIR_CIR_DIALECT_CIR_TYPES
14+
#define MLIR_CIR_DIALECT_CIR_TYPES
15+
16+
include "clang/CIR/Dialect/IR/CIRDialect.td"
17+
include "mlir/Interfaces/DataLayoutInterfaces.td"
18+
include "mlir/IR/AttrTypeBase.td"
19+
20+
//===----------------------------------------------------------------------===//
21+
// CIR Types
22+
//===----------------------------------------------------------------------===//
23+
24+
class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
25+
string baseCppClass = "::mlir::Type">
26+
: TypeDef<CIR_Dialect, name, traits, baseCppClass> {
27+
let mnemonic = typeMnemonic;
28+
}
29+
30+
//===----------------------------------------------------------------------===//
31+
// IntType
32+
//===----------------------------------------------------------------------===//
33+
34+
def CIR_IntType : CIR_Type<"Int", "int",
35+
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
36+
let summary = "Integer type with arbitrary precision up to a fixed limit";
37+
let description = [{
38+
CIR type that represents integer types with arbitrary precision, including
39+
standard integral types such as `int` and `long`, extended integral types
40+
such as `__int128`, and arbitrary width types such as `_BitInt(n)`.
41+
42+
Those integer types that are directly available in C/C++ standard are called
43+
primitive integer types. Said types are: `signed char`, `short`, `int`,
44+
`long`, `long long`, and their unsigned variations.
45+
}];
46+
let parameters = (ins "unsigned":$width, "bool":$isSigned);
47+
let hasCustomAssemblyFormat = 1;
48+
let extraClassDeclaration = [{
49+
/// Return true if this is a signed integer type.
50+
bool isSigned() const { return getIsSigned(); }
51+
/// Return true if this is an unsigned integer type.
52+
bool isUnsigned() const { return !getIsSigned(); }
53+
/// Return type alias.
54+
std::string getAlias() const {
55+
return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i';
56+
}
57+
/// Return true if this is a primitive integer type (i.e. signed or unsigned
58+
/// integer types whose bit width is 8, 16, 32, or 64).
59+
bool isPrimitive() const {
60+
return isValidPrimitiveIntBitwidth(getWidth());
61+
}
62+
bool isSignedPrimitive() const {
63+
return isPrimitive() && isSigned();
64+
}
65+
66+
/// Returns a minimum bitwidth of cir::IntType
67+
static unsigned minBitwidth() { return 1; }
68+
/// Returns a maximum bitwidth of cir::IntType
69+
static unsigned maxBitwidth() { return 128; }
70+
71+
/// Returns true if cir::IntType that represents a primitive integer type
72+
/// can be constructed from the provided bitwidth.
73+
static bool isValidPrimitiveIntBitwidth(unsigned width) {
74+
return width == 8 || width == 16 || width == 32 || width == 64;
75+
}
76+
}];
77+
let genVerifyDecl = 1;
78+
}
79+
80+
// Constraints
81+
82+
// Unsigned integer type of a specific width.
83+
class UInt<int width>
84+
: Type<And<[
85+
CPred<"::mlir::isa<::cir::IntType>($_self)">,
86+
CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">,
87+
CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
88+
]>, width # "-bit unsigned integer", "::cir::IntType">,
89+
BuildableType<
90+
"cir::IntType::get($_builder.getContext(), "
91+
# width # ", /*isSigned=*/false)"> {
92+
int bitwidth = width;
93+
}
94+
95+
def UInt1 : UInt<1>;
96+
def UInt8 : UInt<8>;
97+
def UInt16 : UInt<16>;
98+
def UInt32 : UInt<32>;
99+
def UInt64 : UInt<64>;
100+
101+
// Signed integer type of a specific width.
102+
class SInt<int width>
103+
: Type<And<[
104+
CPred<"::mlir::isa<::cir::IntType>($_self)">,
105+
CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">,
106+
CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width>
107+
]>, width # "-bit signed integer", "::cir::IntType">,
108+
BuildableType<
109+
"cir::IntType::get($_builder.getContext(), "
110+
# width # ", /*isSigned=*/true)"> {
111+
int bitwidth = width;
112+
}
113+
114+
def SInt1 : SInt<1>;
115+
def SInt8 : SInt<8>;
116+
def SInt16 : SInt<16>;
117+
def SInt32 : SInt<32>;
118+
def SInt64 : SInt<64>;
119+
120+
def PrimitiveUInt
121+
: AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int",
122+
"::cir::IntType">;
123+
124+
def PrimitiveSInt
125+
: AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int",
126+
"::cir::IntType">;
127+
128+
def PrimitiveInt
129+
: AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64],
130+
"primitive int", "::cir::IntType">;
131+
132+
#endif // MLIR_CIR_DIALECT_CIR_TYPES

clang/lib/AST/ByteCode/BitcastBuffer.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88
#include "BitcastBuffer.h"
9+
#include "llvm/ADT/STLExtras.h"
910

1011
using namespace clang;
1112
using namespace clang::interp;
@@ -60,6 +61,56 @@ BitcastBuffer::copyBits(Bits BitOffset, Bits BitWidth, Bits FullBitWidth,
6061
return Out;
6162
}
6263

64+
bool BitcastBuffer::allInitialized() const {
65+
Bits Sum;
66+
for (BitRange BR : InitializedBits)
67+
Sum += BR.size();
68+
69+
return Sum == FinalBitSize;
70+
}
71+
72+
void BitcastBuffer::markInitialized(Bits Offset, Bits Length) {
73+
if (Length.isZero())
74+
return;
75+
76+
BitRange Element(Offset, Offset + Length - Bits(1));
77+
if (InitializedBits.empty()) {
78+
InitializedBits.push_back(Element);
79+
return;
80+
}
81+
82+
assert(InitializedBits.size() >= 1);
83+
// Common case of just appending.
84+
Bits End = InitializedBits.back().End;
85+
if (End <= Offset) {
86+
// Merge this range with the last one.
87+
// In the best-case scenario, this means we only ever have
88+
// one single bit range covering all bits.
89+
if (End == (Offset - Bits(1))) {
90+
InitializedBits.back().End = Element.End;
91+
return;
92+
}
93+
94+
// Otherwise, we can simply append.
95+
InitializedBits.push_back(Element);
96+
} else {
97+
// Insert sorted.
98+
auto It = std::upper_bound(InitializedBits.begin(), InitializedBits.end(),
99+
Element);
100+
InitializedBits.insert(It, Element);
101+
}
102+
103+
#ifndef NDEBUG
104+
// Ensure ranges are sorted and non-overlapping.
105+
assert(llvm::is_sorted(InitializedBits));
106+
for (unsigned I = 1; I != InitializedBits.size(); ++I) {
107+
[[maybe_unused]] auto Prev = InitializedBits[I - 1];
108+
[[maybe_unused]] auto Cur = InitializedBits[I];
109+
assert(Prev.End.N < Cur.Start.N);
110+
}
111+
#endif
112+
}
113+
63114
#if 0
64115
template<typename T>
65116
static std::string hex(T t) {

clang/lib/AST/ByteCode/BitcastBuffer.h

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#ifndef LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
99
#define LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H
1010

11+
#include "llvm/ADT/SmallVector.h"
1112
#include <cassert>
1213
#include <cstddef>
1314
#include <memory>
@@ -30,14 +31,20 @@ struct Bits {
3031
bool nonZero() const { return N != 0; }
3132
bool isZero() const { return N == 0; }
3233

33-
Bits operator-(Bits Other) { return Bits(N - Other.N); }
34-
Bits operator+(Bits Other) { return Bits(N + Other.N); }
34+
Bits operator-(Bits Other) const { return Bits(N - Other.N); }
35+
Bits operator+(Bits Other) const { return Bits(N + Other.N); }
3536
Bits operator+=(size_t O) {
3637
N += O;
3738
return *this;
3839
}
40+
Bits operator+=(Bits O) {
41+
N += O.N;
42+
return *this;
43+
}
3944

40-
bool operator>=(Bits Other) { return N >= Other.N; }
45+
bool operator>=(Bits Other) const { return N >= Other.N; }
46+
bool operator<=(Bits Other) const { return N <= Other.N; }
47+
bool operator==(Bits Other) const { return N == Other.N; }
4148
};
4249

4350
/// A quantity in bytes.
@@ -48,11 +55,21 @@ struct Bytes {
4855
Bits toBits() const { return Bits(N * 8); }
4956
};
5057

58+
struct BitRange {
59+
Bits Start;
60+
Bits End;
61+
62+
BitRange(Bits Start, Bits End) : Start(Start), End(End) {}
63+
Bits size() const { return End - Start + Bits(1); }
64+
bool operator<(BitRange Other) const { return Start.N < Other.Start.N; }
65+
};
66+
5167
/// Track what bits have been initialized to known values and which ones
5268
/// have indeterminate value.
5369
struct BitcastBuffer {
5470
Bits FinalBitSize;
5571
std::unique_ptr<std::byte[]> Data;
72+
llvm::SmallVector<BitRange> InitializedBits;
5673

5774
BitcastBuffer(Bits FinalBitSize) : FinalBitSize(FinalBitSize) {
5875
assert(FinalBitSize.isFullByte());
@@ -64,10 +81,10 @@ struct BitcastBuffer {
6481
Bits size() const { return FinalBitSize; }
6582

6683
/// Returns \c true if all bits in the buffer have been initialized.
67-
bool allInitialized() const {
68-
// FIXME: Implement.
69-
return true;
70-
}
84+
bool allInitialized() const;
85+
/// Marks the bits in the given range as initialized.
86+
/// FIXME: Can we do this automatically in pushData()?
87+
void markInitialized(Bits Start, Bits Length);
7188

7289
/// Push \p BitWidth bits at \p BitOffset from \p In into the buffer.
7390
/// \p TargetEndianness is the endianness of the target we're compiling for.

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6483,19 +6483,14 @@ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
64836483
QualType ToType = E->getType();
64846484
std::optional<PrimType> ToT = classify(ToType);
64856485

6486+
// Bitcasting TO nullptr_t is always fine.
64866487
if (ToType->isNullPtrType()) {
64876488
if (!this->discard(SubExpr))
64886489
return false;
64896490

64906491
return this->emitNullPtr(0, nullptr, E);
64916492
}
64926493

6493-
if (FromType->isNullPtrType() && ToT) {
6494-
if (!this->discard(SubExpr))
6495-
return false;
6496-
6497-
return visitZeroInitializer(*ToT, ToType, E);
6498-
}
64996494
assert(!ToType->isReferenceType());
65006495

65016496
// Prepare storage for the result in case we discard.

0 commit comments

Comments
 (0)