Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR] Remove redundant result type of cir.const operation #581

Merged
merged 2 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
}

mlir::TypedAttr getConstPtrAttr(mlir::Type t, uint64_t v) {
assert(t.isa<mlir::cir::PointerType>() && "expected cir.ptr");
return mlir::cir::ConstPtrAttr::get(getContext(), t, v);
return mlir::cir::ConstPtrAttr::get(getContext(),
t.cast<mlir::cir::PointerType>(), v);
}

// Creates constant nullptr for pointer type ty.
Expand Down
15 changes: 12 additions & 3 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -248,20 +248,29 @@ def FPAttr : CIR_Attr<"FP", "fp", [TypedAttrInterface]> {

def ConstPtrAttr : CIR_Attr<"ConstPtr", "ptr", [TypedAttrInterface]> {
let summary = "Holds a constant pointer value";
let parameters = (ins AttributeSelfTypeParameter<"">:$type, "uint64_t":$value);
let parameters = (ins
AttributeSelfTypeParameter<"", "::mlir::cir::PointerType">:$type,
"uint64_t":$value);
let description = [{
A pointer attribute is a literal attribute that represents an integral
value of a pointer type.
}];
let builders = [
AttrBuilderWithInferredContext<(ins "Type":$type, "uint64_t":$value), [{
return $_get(type.getContext(), type, value);
return $_get(type.getContext(), type.cast<mlir::cir::PointerType>(), value);
}]>,
AttrBuilder<(ins "Type":$type,
"uint64_t":$value), [{
return $_get($_ctxt, type.cast<mlir::cir::PointerType>(), value);
}]>,
];
let extraClassDeclaration = [{
bool isNullValue() const { return getValue() == 0; }
}];
let hasCustomAssemblyFormat = 1;

let assemblyFormat = [{
`<` custom<ConstPtr>($value) `>`
}];
}

//===----------------------------------------------------------------------===//
Expand Down
47 changes: 22 additions & 25 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ def PtrStrideOp : CIR_Op<"ptr_stride",
a stride (second operand).

```mlir
%3 = cir.const(0 : i32) : i32
%3 = cir.const 0 : i32
%4 = cir.ptr_stride(%2 : !cir.ptr<i32>, %3 : i32), !cir.ptr<i32>
```
}];
Expand Down Expand Up @@ -293,7 +293,7 @@ def PtrStrideOp : CIR_Op<"ptr_stride",
//===----------------------------------------------------------------------===//

def ConstantOp : CIR_Op<"const",
[ConstantLike, Pure]> {
[ConstantLike, Pure, AllTypesMatch<["value", "res"]>]> {
// FIXME: Use SameOperandsAndResultType or similar and prevent eye bleeding
// type repetition in the assembly form.

Expand All @@ -303,9 +303,9 @@ def ConstantOp : CIR_Op<"const",
attached to the operation as an attribute.

```mlir
%0 = cir.const(42 : i32) : i32
%1 = cir.const(4.2 : f32) : f32
%2 = cir.const(nullptr : !cir.ptr<i32>) : !cir.ptr<i32>
%0 = cir.const 42 : i32
%1 = cir.const 4.2 : f32
%2 = cir.const nullptr : !cir.ptr<i32>
```
}];

Expand All @@ -315,9 +315,7 @@ def ConstantOp : CIR_Op<"const",
// The constant operation returns a single value of CIR_AnyType.
let results = (outs CIR_AnyType:$res);

let assemblyFormat = [{
`(` custom<ConstantValue>($value) `)` attr-dict `:` type($res)
}];
let assemblyFormat = "attr-dict $value";

let hasVerifier = 1;

Expand Down Expand Up @@ -1111,13 +1109,13 @@ def BitClrsbOp : CIR_BitOp<"bit.clrsb", AnyTypeOf<[SInt32, SInt64]>> {
!s32i = !cir.int<s, 32>

// %0 = 0xDEADBEEF, 0b1101_1110_1010_1101_1011_1110_1110_1111
%0 = cir.const(#cir.int<3735928559> : !s32i) : !s32i
%0 = cir.const #cir.int<3735928559> : !s32i
// %1 will be 1 because there is 1 bit following the most significant bit
// that is identical to it.
%1 = cir.bit.clrsb(%0 : !s32i) : !s32i

// %2 = 1, 0b0000_0000_0000_0000_0000_0000_0000_0001
%2 = cir.const(#cir.int<1> : !s32i) : !s32i
%2 = cir.const #cir.int<1> : !s32i
// %3 will be 30
%3 = cir.bit.clrsb(%2 : !s32i) : !s32i
```
Expand All @@ -1142,7 +1140,7 @@ def BitClzOp : CIR_BitOp<"bit.clz", AnyTypeOf<[UInt16, UInt32, UInt64]>> {
!u32i = !cir.int<u, 32>

// %0 = 0b0000_0000_0000_0000_0000_0000_0000_1000
%0 = cir.const(#cir.int<8> : !u32i) : !u32i
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 28
%1 = cir.bit.clz(%0 : !u32i) : !s32i
```
Expand All @@ -1167,7 +1165,7 @@ def BitCtzOp : CIR_BitOp<"bit.ctz", AnyTypeOf<[UInt16, UInt32, UInt64]>> {
!u32i = !cir.int<u, 32>

// %0 = 0b1000
%0 = cir.const(#cir.int<8> : !u32i) : !u32i
%0 = cir.const #cir.int<8> : !u32i
// %1 will be 3
%1 = cir.bit.ctz(%0 : !u32i) : !s32i
```
Expand All @@ -1190,7 +1188,7 @@ def BitFfsOp : CIR_BitOp<"bit.ffs", AnyTypeOf<[SInt32, SInt64]>> {
!s32i = !cir.int<s, 32>

// %0 = 0x0010_1000
%0 = cir.const(#cir.int<40> : !s32i) : !s32i
%0 = cir.const #cir.int<40> : !s32i
// #1 will be 4 since the 4th least significant bit is 1.
%1 = cir.bit.ffs(%0 : !s32i) : !s32i
```
Expand All @@ -1212,9 +1210,9 @@ def BitParityOp : CIR_BitOp<"bit.parity", AnyTypeOf<[UInt32, UInt64]>> {
!u32i = !cir.int<u, 32>

// %0 = 0x0110_1000
%0 = cir.const(#cir.int<104> : !u32i) : !s32i
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 1 since there are 3 1-bits in %0
%1 = cir.bit.parity(%0 : !u32i) : !s32i
%1 = cir.bit.parity(%0 : !u32i) : !u32i
```
}];
}
Expand All @@ -1230,13 +1228,12 @@ def BitPopcountOp
Example:

```mlir
!s32i = !cir.int<s, 32>
!u32i = !cir.int<u, 32>

// %0 = 0x0110_1000
%0 = cir.const(#cir.int<104> : !u32i) : !s32i
%0 = cir.const #cir.int<104> : !u32i
// %1 will be 3 since there are 3 1-bits in %0
%1 = cir.bit.popcount(%0 : !u32i) : !s32i
%1 = cir.bit.popcount(%0 : !u32i) : !u32i
```
}];
}
Expand All @@ -1260,7 +1257,7 @@ def ByteswapOp : CIR_Op<"bswap", [Pure, SameOperandsAndResultType]> {
!u32i = !cir.int<u, 32>

// %0 = 0x12345678
%0 = cir.const(#cir.int<305419896> : !u32i) : !u32i
%0 = cir.const #cir.int<305419896> : !u32i

// %1 should be 0x78563412
%1 = cir.bswap(%0 : !u32i) : !u32i
Expand Down Expand Up @@ -1302,12 +1299,12 @@ def CmpThreeWayOp : CIR_Op<"cmp3way", [Pure, SameTypeOperands]> {
#cmp3way_strong = #cmp3way_info<strong, lt = -1, eq = 0, gt = 1>
#cmp3way_partial = #cmp3way_info<strong, lt = -1, eq = 0, gt = 1, unordered = 2>

%0 = cir.const(#cir.int<0> : !s32i) : !s32i
%1 = cir.const(#cir.int<1> : !s32i) : !s32i
%0 = cir.const #cir.int<0> : !s32i
%1 = cir.const #cir.int<1> : !s32i
%2 = cir.cmp3way(%0 : !s32i, %1, #cmp3way_strong) : !s8i

%3 = cir.const(#cir.fp<0.0> : !cir.float) : !cir.float
%4 = cir.const(#cir.fp<1.0> : !cir.float) : !cir.float
%3 = cir.const #cir.fp<0.0> : !cir.float
%4 = cir.const #cir.fp<1.0> : !cir.float
%5 = cir.cmp3way(%3 : !cir.float, %4, #cmp3way_partial) : !s8i
```
}];
Expand Down Expand Up @@ -1961,7 +1958,7 @@ def SetBitfieldOp : CIR_Op<"set_bitfield"> {
!struct_type = !cir.struct<struct "S" {!cir.int<u, 32>, !cir.int<u, 32>, !cir.int<u, 16>} #cir.record.decl.ast>
#bfi_d = #cir.bitfield_info<name = "d", storage_type = !u32i, size = 2, offset = 17, is_signed = true>

%1 = cir.const(#cir.int<3> : !s32i) : !s32i
%1 = cir.const #cir.int<3> : !s32i
%2 = cir.load %0 : !cir.ptr<!cir.ptr<!struct_type>>, !cir.ptr<!struct_type>
%3 = cir.get_member %2[1] {name = "d"} : !cir.ptr<!struct_type> -> !cir.ptr<!u32i>
%4 = cir.set_bitfield(#bfi_d, %3 : !cir.ptr<!u32i>, %1 : !s32i) -> !s32i
Expand Down Expand Up @@ -3045,7 +3042,7 @@ def MemCpyOp : CIR_Op<"libc.memcpy"> {

```mlir
// Copying 2 bytes from one array to a struct:
%2 = cir.const(#cir.int<2> : !u32i) : !u32i
%2 = cir.const #cir.int<2> : !u32i
cir.libc.memcpy %2 bytes from %arr to %struct : !cir.ptr<!arr> -> !cir.ptr<!struct>
```
}];
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/CodeGen/CIRGenExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ void AggExprEmitter::buildArrayInit(Address DestPtr, mlir::cir::ArrayType AType,
mlir::Value element = begin;

// Don't build the 'one' before the cycle to avoid
// emmiting the redundant cir.const(1) instrs.
// emmiting the redundant `cir.const 1` instrs.
mlir::Value one;

// Emit the explicit initializers.
Expand Down
37 changes: 14 additions & 23 deletions clang/lib/CIR/Dialect/IR/CIRAttrs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ static mlir::ParseResult
parseFloatLiteral(mlir::AsmParser &parser,
mlir::FailureOr<llvm::APFloat> &value, mlir::Type ty);

static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser,
uint64_t &value);

static void printConstPtr(mlir::AsmPrinter &p, uint64_t value);

#define GET_ATTRDEF_CLASSES
#include "clang/CIR/Dialect/IR/CIROpsAttributes.cpp.inc"

Expand Down Expand Up @@ -212,37 +217,23 @@ void LangAttr::print(AsmPrinter &printer) const {
// ConstPtrAttr definitions
//===----------------------------------------------------------------------===//

Attribute ConstPtrAttr::parse(AsmParser &parser, Type odsType) {
uint64_t value;

if (!odsType.isa<cir::PointerType>())
return {};

// Consume the '<' symbol.
if (parser.parseLess())
return {};
// TODO: Consider encoding the null value differently and use conditional
// assembly format instead of custom parsing/printing.
static ParseResult parseConstPtr(AsmParser &parser, uint64_t &value) {

if (parser.parseOptionalKeyword("null").succeeded()) {
value = 0;
} else {
if (parser.parseInteger(value))
parser.emitError(parser.getCurrentLocation(), "expected integer value");
return success();
}

// Consume the '>' symbol.
if (parser.parseGreater())
return {};

return ConstPtrAttr::get(odsType, value);
return parser.parseInteger(value);
}

void ConstPtrAttr::print(AsmPrinter &printer) const {
printer << '<';
if (isNullValue())
printer << "null";
static void printConstPtr(AsmPrinter &p, uint64_t value) {
if (!value)
p << "null";
else
printer << getValue();
printer << '>';
p << value;
}

//===----------------------------------------------------------------------===//
Expand Down
29 changes: 12 additions & 17 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,23 +364,6 @@ LogicalResult ConstantOp::verify() {
return checkConstantTypes(getOperation(), getType(), getValue());
}

static ParseResult parseConstantValue(OpAsmParser &parser,
mlir::Attribute &valueAttr) {
NamedAttrList attr;
return parser.parseAttribute(valueAttr, "value", attr);
}

// FIXME: create a CIRConstAttr and hide this away for both global
// initialization and cir.const operation.
static void printConstant(OpAsmPrinter &p, Attribute value) {
p.printAttribute(value);
}

static void printConstantValue(OpAsmPrinter &p, cir::ConstantOp op,
Attribute value) {
printConstant(p, value);
}

OpFoldResult ConstantOp::fold(FoldAdaptor /*adaptor*/) { return getValue(); }

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1487,6 +1470,18 @@ ::llvm::SmallVector<Region *> ForOp::getLoopRegions() { return {&getBody()}; }
// GlobalOp
//===----------------------------------------------------------------------===//

static ParseResult parseConstantValue(OpAsmParser &parser,
mlir::Attribute &valueAttr) {
NamedAttrList attr;
return parser.parseAttribute(valueAttr, "value", attr);
}

// FIXME: create a CIRConstAttr and hide this away for both global
// initialization and cir.const operation.
static void printConstant(OpAsmPrinter &p, Attribute value) {
p.printAttribute(value);
}

static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, GlobalOp op,
TypeAttr type, Attribute initAttr,
mlir::Region &ctorRegion,
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3178,10 +3178,10 @@ static void buildCtorDtorList(
// cir.func @foo(%arg0: !s32i) -> !s32i {
// %4 = cir.cast(int_to_bool, %arg0 : !s32i), !cir.bool
// cir.if %4 {
// %5 = cir.const(#cir.int<1> : !s32i) : !s32i
// %5 = cir.const #cir.int<1> : !s32i
// cir.return %5 : !s32i
// } else {
// %5 = cir.const(#cir.int<0> : !s32i) : !s32i
// %5 = cir.const #cir.int<0> : !s32i
// cir.return %5 : !s32i
// }
// cir.return %arg0 : !s32i
Expand Down
4 changes: 2 additions & 2 deletions clang/test/CIR/CodeGen/OpenMP/parallel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ void omp_parallel_2() {
// CHECK: omp.parallel {
// CHECK-NEXT: cir.scope {
// CHECK-NEXT: %[[XVarDecl:.+]] = {{.*}} ["x", init]
// CHECK-NEXT: %[[C1:.+]] = cir.const(#cir.int<1> : !s32i)
// CHECK-NEXT: %[[C1:.+]] = cir.const #cir.int<1> : !s32i
// CHECK-NEXT: cir.store %[[C1]], %[[XVarDecl]]
// CHECK-NEXT: %[[XVal:.+]] = cir.load %[[XVarDecl]]
// CHECK-NEXT: %[[COne:.+]] = cir.const(#cir.int<1> : !s32i)
// CHECK-NEXT: %[[COne:.+]] = cir.const #cir.int<1> : !s32i
// CHECK-NEXT: %[[BinOpVal:.+]] = cir.binop(add, %[[XVal]], %[[COne]])
// CHECK-NEXT: cir.store %[[BinOpVal]], %[[YVarDecl]]
// CHECK-NEXT: }
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CIR/CodeGen/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ void test() {
// CHECK-NEXT: cir.store %arg0, %0
// CHECK-NEXT: %1 = cir.load %0
// CHECK-NEXT: %2 = cir.get_member %1[0] {name = "storage"}
// CHECK-NEXT: %3 = cir.const(#cir.ptr<null> : !cir.ptr<!s8i>) : !cir.ptr<!s8i>
// CHECK-NEXT: %3 = cir.const #cir.ptr<null> : !cir.ptr<!s8i>
// CHECK-NEXT: cir.store %3, %2 : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: %4 = cir.get_member %1[1] {name = "size"} : !cir.ptr<!ty_22String22> -> !cir.ptr<!s64i>
// CHECK-NEXT: %5 = cir.const(#cir.int<0> : !s32i) : !s32i
// CHECK-NEXT: %5 = cir.const #cir.int<0> : !s32i
// CHECK-NEXT: %6 = cir.cast(integral, %5 : !s32i), !s64i
// CHECK-NEXT: cir.store %6, %4 : !s64i, !cir.ptr<!s64i>
// CHECK-NEXT: cir.return
Expand All @@ -37,7 +37,7 @@ void test() {
// CHECK-NEXT: cir.store %arg1, %1
// CHECK-NEXT: %2 = cir.load %0
// CHECK-NEXT: %3 = cir.get_member %2[0] {name = "storage"}
// CHECK-NEXT: %4 = cir.const(#cir.ptr<null> : !cir.ptr<!s8i>)
// CHECK-NEXT: %4 = cir.const #cir.ptr<null> : !cir.ptr<!s8i>
// CHECK-NEXT: cir.store %4, %3
// CHECK-NEXT: %5 = cir.get_member %2[1] {name = "size"} : !cir.ptr<!ty_22String22> -> !cir.ptr<!s64i>
// CHECK-NEXT: %6 = cir.load %1 : !cir.ptr<!s32i>, !s32i
Expand All @@ -53,7 +53,7 @@ void test() {
// CHECK-NEXT: cir.store %arg1, %1 : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: %2 = cir.load %0 : !cir.ptr<!cir.ptr<!ty_22String22>>, !cir.ptr<!ty_22String22>
// CHECK-NEXT: %3 = cir.get_member %2[0] {name = "storage"} : !cir.ptr<!ty_22String22> -> !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: %4 = cir.const(#cir.ptr<null> : !cir.ptr<!s8i>) : !cir.ptr<!s8i>
// CHECK-NEXT: %4 = cir.const #cir.ptr<null> : !cir.ptr<!s8i>
// CHECK-NEXT: cir.store %4, %3 : !cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: cir.return

Expand Down
6 changes: 3 additions & 3 deletions clang/test/CIR/CodeGen/agg-copy.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ typedef struct {
// CHECK: cir.store %arg0, [[TMP0]] : !cir.ptr<!ty_22A22>, !cir.ptr<!cir.ptr<!ty_22A22>>
// CHECK: cir.store %arg1, [[TMP1]] : !cir.ptr<!ty_22A22>, !cir.ptr<!cir.ptr<!ty_22A22>>
// CHECK: [[TMP2:%.*]] = cir.load [[TMP0]] : !cir.ptr<!cir.ptr<!ty_22A22>>, !cir.ptr<!ty_22A22>
// CHECK: [[TMP3:%.*]] = cir.const(#cir.int<1> : !s32i) : !s32i
// CHECK: [[TMP3:%.*]] = cir.const #cir.int<1> : !s32i
// CHECK: [[TMP4:%.*]] = cir.ptr_stride([[TMP2]] : !cir.ptr<!ty_22A22>, [[TMP3]] : !s32i), !cir.ptr<!ty_22A22>
// CHECK: [[TMP5:%.*]] = cir.load [[TMP1]] : !cir.ptr<!cir.ptr<!ty_22A22>>, !cir.ptr<!ty_22A22>
// CHECK: [[TMP6:%.*]] = cir.const(#cir.int<1> : !s32i) : !s32i
// CHECK: [[TMP6:%.*]] = cir.const #cir.int<1> : !s32i
// CHECK: [[TMP7:%.*]] = cir.ptr_stride([[TMP5]] : !cir.ptr<!ty_22A22>, [[TMP6]] : !s32i), !cir.ptr<!ty_22A22>
// CHECK: cir.copy [[TMP7]] to [[TMP4]] : !cir.ptr<!ty_22A22>
void foo1(A* a1, A* a2) {
Expand Down Expand Up @@ -68,7 +68,7 @@ A create() { A a; return a; }
// CHECK: [[TMP1:%.*]] = cir.alloca !ty_22A22, !cir.ptr<!ty_22A22>, ["tmp"] {alignment = 4 : i64}
// CHECK: [[TMP2:%.*]] = cir.call @create() : () -> !ty_22A22
// CHECK: cir.store [[TMP2]], [[TMP1]] : !ty_22A22, !cir.ptr<!ty_22A22>
// CHECK: cir.copy [[TMP1]] to [[TMP0]] : !cir.ptr<!ty_22A22>
// CHECK: cir.copy [[TMP1]] to [[TMP0]] : !cir.ptr<!ty_22A22>
void foo5() {
A a;
a = create();
Expand Down
Loading
Loading