Skip to content
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: 4 additions & 0 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
CIRBaseBuilderTy(mlir::MLIRContext &mlirContext)
: mlir::OpBuilder(&mlirContext) {}

cir::ConstantOp getConstant(mlir::Location loc, mlir::TypedAttr attr) {
return create<cir::ConstantOp>(loc, attr.getType(), attr);
}

cir::ConstantOp getBool(bool state, mlir::Location loc) {
return create<cir::ConstantOp>(loc, getBoolTy(), getCIRBoolAttr(state));
}
Expand Down
14 changes: 14 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,20 @@ def CIR_BoolAttr : CIR_Attr<"Bool", "bool", [TypedAttrInterface]> {
}];
}

//===----------------------------------------------------------------------===//
// ZeroAttr
//===----------------------------------------------------------------------===//

def ZeroAttr : CIR_Attr<"Zero", "zero", [TypedAttrInterface]> {
let summary = "Attribute to represent zero initialization";
let description = [{
The ZeroAttr is used to indicate zero initialization on structs.
}];

let parameters = (ins AttributeSelfTypeParameter<"">:$type);
let assemblyFormat = [{}];
}

//===----------------------------------------------------------------------===//
// UndefAttr
//===----------------------------------------------------------------------===//
Expand Down
10 changes: 8 additions & 2 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ struct MissingFeatures {
static bool supportComdat() { return false; }

// Load/store attributes
static bool opLoadThreadLocal() { return false; }
static bool opLoadStoreThreadLocal() { return false; }
static bool opLoadEmitScalarRangeCheck() { return false; }
static bool opLoadBooleanRepresentation() { return false; }
static bool opLoadStoreTbaa() { return false; }
static bool opLoadStoreMemOrder() { return false; }
static bool opLoadStoreVolatile() { return false; }
static bool opLoadStoreAlignment() { return false; }
static bool opLoadStoreAtomic() { return false; }
static bool opLoadStoreObjC() { return false; }

// AllocaOp handling
static bool opAllocaVarDeclContext() { return false; }
static bool opAllocaStaticLocal() { return false; }
static bool opAllocaNonGC() { return false; }
static bool opAllocaImpreciseLifetime() { return false; }
Expand All @@ -61,6 +62,7 @@ struct MissingFeatures {
static bool opAllocaReference() { return false; }
static bool opAllocaAnnotations() { return false; }
static bool opAllocaDynAllocSize() { return false; }
static bool opAllocaCaptureByInit() { return false; }

// FuncOp handling
static bool opFuncOpenCLKernelMetadata() { return false; }
Expand All @@ -76,6 +78,10 @@ struct MissingFeatures {
static bool constructABIArgDirectExtend() { return false; }
static bool opGlobalViewAttr() { return false; }
static bool lowerModeOptLevel() { return false; }
static bool opTBAA() { return false; }
static bool objCLifetime() { return false; }
static bool emitNullabilityCheck() { return false; }
static bool astVarDeclInterface() { return false; }
};

} // namespace cir
Expand Down
100 changes: 100 additions & 0 deletions clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// A helper class for emitting expressions and values as cir::ConstantOp
// and as initializers for global variables.
//
// Note: this is based on clang's LLVM IR codegen in ConstantEmitter.h, reusing
// this class interface makes it easier move forward with bringing CIR codegen
// to completion.
//
//===----------------------------------------------------------------------===//

#ifndef CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H
#define CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H

#include "CIRGenFunction.h"
#include "CIRGenModule.h"
#include "llvm/ADT/SmallVector.h"

namespace clang::CIRGen {

class ConstantEmitter {
public:
CIRGenModule &cgm;
const CIRGenFunction *cgf;

private:
bool abstract = false;

/// Whether we're in a constant context.
bool inConstantContext = false;

public:
/// Initialize this emission in the context of the given function.
/// Use this if the expression might contain contextual references like
/// block addresses or PredefinedExprs.
ConstantEmitter(CIRGenFunction &cgf) : cgm(cgf.cgm), cgf(&cgf) {}

ConstantEmitter(const ConstantEmitter &other) = delete;
ConstantEmitter &operator=(const ConstantEmitter &other) = delete;

// All of the "abstract" emission methods below permit the emission to
// be immediately discarded without finalizing anything. Therefore, they
// must also promise not to do anything that will, in the future, require
// finalization:
//
// - using the CGF (if present) for anything other than establishing
// semantic context; for example, an expression with ignored
// side-effects must not be emitted as an abstract expression
//
// - doing anything that would not be safe to duplicate within an
// initializer or to propagate to another context; for example,
// side effects, or emitting an initialization that requires a
// reference to its current location.
mlir::Attribute emitForMemory(mlir::Attribute c, QualType t);

/// Emit the result of the given expression as an abstract constant,
/// asserting that it succeeded. This is only safe to do when the
/// expression is known to be a constant expression with either a fairly
/// simple type or a known simple form.
mlir::Attribute emitAbstract(SourceLocation loc, const APValue &value,
QualType t);

mlir::Attribute tryEmitConstantExpr(const ConstantExpr *CE);

// These are private helper routines of the constant emitter that
// can't actually be private because things are split out into helper
// functions and classes.

mlir::Attribute tryEmitPrivateForVarInit(const VarDecl &d);

mlir::Attribute tryEmitPrivate(const APValue &value, QualType destType);
mlir::Attribute tryEmitPrivateForMemory(const APValue &value, QualType t);

/// Try to emit the initializer of the given declaration as an abstract
/// constant.
mlir::Attribute tryEmitAbstractForInitializer(const VarDecl &d);

private:
class AbstractStateRAII {
ConstantEmitter &emitter;
bool oldValue;

public:
AbstractStateRAII(ConstantEmitter &emitter, bool value)
: emitter(emitter), oldValue(emitter.abstract) {
emitter.abstract = value;
}
~AbstractStateRAII() { emitter.abstract = oldValue; }
};
};

} // namespace clang::CIRGen

#endif // CLANG_LIB_CIR_CODEGEN_CIRGENCONSTANTEMITTER_H
Loading