Skip to content

Commit

Permalink
Merge reducer destructor callback into reduce callback.
Browse files Browse the repository at this point in the history
  • Loading branch information
VoxSciurorum authored and neboat committed Jul 13, 2022
1 parent 3cbba61 commit 58e0459
Show file tree
Hide file tree
Showing 24 changed files with 48 additions and 86 deletions.
6 changes: 3 additions & 3 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1321,9 +1321,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
return CanQualType::CreateUnsafe(getComplexType((QualType) T));
}

QualType getHyperobjectType(QualType T, Expr *R, Expr *I, Expr *D) const;
CanQualType getHyperobjectType(CanQualType T, Expr *R, Expr *I, Expr *D) const {
return CanQualType::CreateUnsafe(getHyperobjectType((QualType) T, R, I, D));
QualType getHyperobjectType(QualType T, Expr *R, Expr *I) const;
CanQualType getHyperobjectType(CanQualType T, Expr *R, Expr *I) const {
return CanQualType::CreateUnsafe(getHyperobjectType((QualType) T, R, I));
}

/// Return the uniqued reference to the type for a pointer to
Expand Down
11 changes: 4 additions & 7 deletions clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -6395,14 +6395,13 @@ class HyperobjectType final : public Type, public llvm::FoldingSetNode {
friend class ASTContext;

QualType ElementType;
Expr *Identity, *Reduce, *Destroy;
const FunctionDecl *IdentityID, *ReduceID, *DestroyID;
Expr *Identity, *Reduce;
const FunctionDecl *IdentityID, *ReduceID;
bool Bare;

HyperobjectType(QualType Element, QualType CanonicalPtr,
Expr *i, const FunctionDecl *ifn,
Expr *r, const FunctionDecl *rfn,
Expr *d, const FunctionDecl *dfn);
Expr *r, const FunctionDecl *rfn);

public:
QualType getElementType() const { return ElementType; }
Expand All @@ -6411,7 +6410,6 @@ class HyperobjectType final : public Type, public llvm::FoldingSetNode {

Expr *getIdentity() const { return Identity; }
Expr *getReduce() const { return Reduce; }
Expr *getDestroy() const { return Destroy; }

bool hasCallbacks() const { return !Bare; }

Expand All @@ -6422,8 +6420,7 @@ class HyperobjectType final : public Type, public llvm::FoldingSetNode {

static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
const FunctionDecl *I,
const FunctionDecl *R,
const FunctionDecl *D);
const FunctionDecl *R);

static bool classof(const Type *T) {
return T->getTypeClass() == Hyperobject;
Expand Down
5 changes: 1 addition & 4 deletions clang/include/clang/AST/TypeProperties.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,9 @@ let Class = HyperobjectType in {
def : Property<"identity", ExprRef> {
let Read = [{ node->getIdentity() }];
}
def : Property<"destroy", ExprRef> {
let Read = [{ node->getDestroy() }];
}

def : Creator<[{
return ctx.getHyperobjectType(elementType, reduce, identity, destroy);
return ctx.getHyperobjectType(elementType, reduce, identity);
}]>;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1315,7 +1315,7 @@ def warn_pragma_cilk_grainsize_equals: Warning<
"'#pragma cilk grainsize' no longer requires '='">,
InGroup<SourceUsesCilkPlus>;
def error_hyperobject_arguments: Error<
"hyperobject must have 0, 2, or 3 callbacks">;
"hyperobject must have 0 or 2 callbacks">;

// OpenMP support.
def warn_pragma_omp_ignored : Warning<
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -1549,11 +1549,10 @@ struct DeclaratorChunk {
struct HyperobjectTypeInfo {
SourceLocation LParenLoc;
SourceLocation RParenLoc;
Expr *Arg[3];
Expr *Arg[2];
void destroy() {
Arg[0] = nullptr;
Arg[1] = nullptr;
Arg[2] = nullptr;
}
};

Expand Down Expand Up @@ -1700,15 +1699,14 @@ struct DeclaratorChunk {
SourceLocation Loc,
SourceLocation LParen,
SourceLocation RParen,
Expr *E0, Expr *E1, Expr *E2) {
Expr *E0, Expr *E1) {
DeclaratorChunk I;
I.Kind = Hyperobject;
I.Loc = Loc;
I.Hyper.LParenLoc = LParen;
I.Hyper.RParenLoc = RParen;
I.Hyper.Arg[0] = E0;
I.Hyper.Arg[1] = E1;
I.Hyper.Arg[2] = E2;
return I;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1997,7 +1997,7 @@ class Sema final {
QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns,
SourceLocation AttrLoc);
QualType BuildHyperobjectType(QualType Element, Expr *Identity, Expr *Reduce,
Expr *Destroy, SourceLocation Loc);
SourceLocation Loc);

QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace,
SourceLocation AttrLoc);
Expand Down
16 changes: 7 additions & 9 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3267,26 +3267,24 @@ static const FunctionDecl *getFunction(Expr *E) {
return F->getFirstDecl();
}

QualType ASTContext::getHyperobjectType(QualType T, Expr *I, Expr *R, Expr *D) const {
assert(I && R && D);
QualType ASTContext::getHyperobjectType(QualType T, Expr *I, Expr *R) const {
assert(I && R);
bool IN = HyperobjectType::isNullish(I);
bool RN = HyperobjectType::isNullish(R);
bool DN = HyperobjectType::isNullish(D);

const FunctionDecl *IF = getFunction(I);
const FunctionDecl *RF = getFunction(R);
const FunctionDecl *DF = getFunction(D);
bool Varies = (!IN && !IF) || (!RN && !RF) || (!DN && !DF);
bool Varies = (!IN && !IF) || (!RN && !RF);

QualType Canonical;
if (!T.isCanonical())
Canonical = getHyperobjectType(getCanonicalType(T), I, R, D);
Canonical = getHyperobjectType(getCanonicalType(T), I, R);

// Do not unique hyperobject types with variable expressions.
if (Varies) {
auto *New =
new (*this, TypeAlignment)
HyperobjectType(T, Canonical, I, IF, R, RF, D, DF);
HyperobjectType(T, Canonical, I, IF, R, RF);
Types.push_back(New);
return QualType(New, 0);
}
Expand All @@ -3295,15 +3293,15 @@ QualType ASTContext::getHyperobjectType(QualType T, Expr *I, Expr *R, Expr *D) c
// structure.
// TODO: 0 and nullptr are not properly treated as equivalent here.
llvm::FoldingSetNodeID ID;
HyperobjectType::Profile(ID, T, IF, RF, DF);
HyperobjectType::Profile(ID, T, IF, RF);

void *InsertPos = nullptr;
if (HyperobjectType *HT = HyperobjectTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(HT, 0);

auto *New =
new (*this, TypeAlignment)
HyperobjectType(T, Canonical, I, IF, R, RF, D, DF);
HyperobjectType(T, Canonical, I, IF, R, RF);
Types.push_back(New);
HyperobjectTypes.InsertNode(New, InsertPos);
return QualType(New, 0);
Expand Down
5 changes: 1 addition & 4 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,15 +708,12 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const HyperobjectType *H2 = cast<HyperobjectType>(T2);
Expr *R1 = H1->getReduce(), *R2 = H2->getReduce();
Expr *I1 = H1->getIdentity(), *I2 = H2->getIdentity();
Expr *D1 = H1->getDestroy(), *D2 = H2->getDestroy();
if (!!I2 != !!I2 || !!R1 != !!R2 || !!D1 != !!D2)
if (!!I2 != !!I2 || !!R1 != !!R2)
return false;
if (I1 && !IsStructurallyEquivalent(Context, I1, I2))
return false;
if (R1 && !IsStructurallyEquivalent(Context, R1, R2))
return false;
if (D1 && !IsStructurallyEquivalent(Context, D1, D2))
return false;
if (!IsStructurallyEquivalent(Context,
cast<HyperobjectType>(T1)->getElementType(),
cast<HyperobjectType>(T2)->getElementType()))
Expand Down
16 changes: 6 additions & 10 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3164,29 +3164,25 @@ bool HyperobjectType::isNullish(Expr *E) {

HyperobjectType::HyperobjectType(QualType Element, QualType CanonicalPtr,
Expr *i, const FunctionDecl *ifn,
Expr *r, const FunctionDecl *rfn,
Expr *d, const FunctionDecl *dfn)
Expr *r, const FunctionDecl *rfn)
: Type(Hyperobject, CanonicalPtr, Element->getDependence()),
ElementType(Element), Identity(i), Reduce(r), Destroy(d),
IdentityID(ifn), ReduceID(rfn), DestroyID(dfn),
Bare(isNullish(i) && isNullish(r) && isNullish(d)) {
ElementType(Element), Identity(i), Reduce(r),
IdentityID(ifn), ReduceID(rfn),
Bare(isNullish(i) && isNullish(r)) {
}

void HyperobjectType::Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, getElementType(), IdentityID, ReduceID, DestroyID);
Profile(ID, getElementType(), IdentityID, ReduceID);
}

void HyperobjectType::Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
const FunctionDecl *I, const FunctionDecl *R,
const FunctionDecl *D) {
const FunctionDecl *I, const FunctionDecl *R) {
ID.AddPointer(Pointee.getAsOpaquePtr());
// In normal use both I and R will be non-null or neither of them will be.
if (I)
ID.AddPointer(I);
if (R)
ID.AddPointer(R);
if (D)
ID.AddPointer(D);
}

StringRef FunctionType::getNameForCallConv(CallingConv CC) {
Expand Down
5 changes: 0 additions & 5 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,10 @@ void TypePrinter::printHyperobjectBefore(const HyperobjectType *T,
if (T->hasCallbacks()) {
Expr *I = T->getIdentity();
Expr *R = T->getReduce();
Expr *D = T->getDestroy();
OS << '(';
I->printPretty(OS, nullptr, Policy);
OS << ", ";
R->printPretty(OS, nullptr, Policy);
if (!HyperobjectType::isNullish(D)) {
OS << ", ";
D->printPretty(OS, nullptr, Policy);
}
OS << ")";
}
}
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1810,7 +1810,6 @@ bool CodeGenFunction::getReducer(const VarDecl *D, ReducerCallbacks &CB) {
if (H->hasCallbacks()) {
CB.Identity = H->getIdentity();
CB.Reduce = H->getReduce();
CB.Destroy = H->getDestroy();
return true;
}
}
Expand All @@ -1836,7 +1835,6 @@ void CodeGenFunction::EmitReducerInit(const VarDecl *D,
llvm::Value *Addr) {
RValue Identity = EmitAnyExpr(C.Identity);
RValue Reduce = EmitAnyExpr(C.Reduce);
RValue Destroy = EmitAnyExpr(C.Destroy);

llvm::Type *SizeType = ConvertType(getContext().getSizeType());
unsigned SizeBits = SizeType->getIntegerBitWidth();
Expand All @@ -1858,8 +1856,7 @@ void CodeGenFunction::EmitReducerInit(const VarDecl *D,
CGM.getIntrinsic(llvm::Intrinsic::reducer_register, Types);
llvm::Value *IdentityV = Identity.getScalarVal();
llvm::Value *ReduceV = Reduce.getScalarVal();
llvm::Value *DestroyV = Destroy.getScalarVal();
Builder.CreateCall(F, {Addr, Size, IdentityV, ReduceV, DestroyV});
Builder.CreateCall(F, {Addr, Size, IdentityV, ReduceV});
}

void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
Expand All @@ -1872,7 +1869,7 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) {
auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, D.getLocation());
QualType type = D.getType();

ReducerCallbacks RCB = {0, 0, 0};
ReducerCallbacks RCB = {0, 0};
bool Reducer = false;
if (const HyperobjectType *H = type->getAs<HyperobjectType>()) {
type = H->getElementType();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
EmitCXXGlobalVarDeclInit(*D, Addr, PerformInit);
}

ReducerCallbacks RCB = {0, 0, 0};
ReducerCallbacks RCB = {0, 0};
if (getReducer(D, RCB)) {
llvm::Value *Addr =
Builder.CreateBitCast(CGM.GetAddrOfGlobalVar(D, nullptr), CGM.VoidPtrTy);
Expand Down
1 change: 0 additions & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -3675,7 +3675,6 @@ class CodeGenFunction : public CodeGenTypeCache {
struct ReducerCallbacks {
Expr *Identity;
Expr *Reduce;
Expr *Destroy;
};

bool getReducer(const VarDecl *D, ReducerCallbacks &CB);
Expand Down
7 changes: 2 additions & 5 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5880,7 +5880,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
ParseTypeQualifierListOpt(DS, AR_GNUAttributesParsedAndRejected,
true, !D.mayOmitIdentifier());

Expr *Reduce = nullptr, *Identity = nullptr, *Destroy = nullptr;
Expr *Reduce = nullptr, *Identity = nullptr;
if (Tok.is(tok::l_paren)) {
SourceLocation Open = ConsumeParen(); // Eat the parenthesis
SmallVector<Expr *, 3> Args;
Expand All @@ -5907,9 +5907,6 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
switch (Args.size()) {
case 0:
break;
case 3:
Destroy = Args[2];
LLVM_FALLTHROUGH;
case 2:
Identity = Args[0];
Reduce = Args[1];
Expand All @@ -5931,7 +5928,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
D.AddTypeInfo(DeclaratorChunk::getHyperobject(
DS.getTypeQualifiers(),
Loc, SourceLocation(), SourceLocation(),
Identity, Reduce, Destroy),
Identity, Reduce),
std::move(DS.getAttributes()), SourceLocation());
else
Diag(Loc, diag::attribute_requires_cilk) << Kind;
Expand Down
9 changes: 3 additions & 6 deletions clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2401,8 +2401,7 @@ Expr *Sema::ValidateReducerCallback(Expr *E, unsigned NumArgs,
}

QualType Sema::BuildHyperobjectType(QualType Element, Expr *Identity,
Expr *Reduce, Expr *Destroy,
SourceLocation Loc) {
Expr *Reduce, SourceLocation Loc) {
QualType Result = Element;
if (!RequireCompleteType(Loc, Element, CompleteTypeKind::Normal,
diag::incomplete_hyperobject)) {
Expand All @@ -2412,12 +2411,11 @@ QualType Sema::BuildHyperobjectType(QualType Element, Expr *Identity,

Identity = ValidateReducerCallback(Identity, 1, Loc);
Reduce = ValidateReducerCallback(Reduce, 2, Loc);
Destroy = ValidateReducerCallback(Destroy, 1, Loc);

// The result of this function must be HyperobjectType if it is called
// from C++ template instantiation when rebuilding an existing hyperobject
// type.
return Context.getHyperobjectType(Result, Identity, Reduce, Destroy);
return Context.getHyperobjectType(Result, Identity, Reduce);
}

/// Build a Read-only Pipe type.
Expand Down Expand Up @@ -5714,8 +5712,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,

case DeclaratorChunk::Hyperobject: {
T = S.BuildHyperobjectType(T, DeclType.Hyper.Arg[0],
DeclType.Hyper.Arg[1], DeclType.Hyper.Arg[2],
DeclType.Loc);
DeclType.Hyper.Arg[1], DeclType.Loc);
break;
}
}
Expand Down
11 changes: 4 additions & 7 deletions clang/lib/Sema/TreeTransform.h
Original file line number Diff line number Diff line change
Expand Up @@ -1211,7 +1211,7 @@ class TreeTransform {
SourceLocation Loc);

QualType RebuildHyperobjectType(QualType ElementType, Expr *R,
Expr *I, Expr *D, SourceLocation Loc);
Expr *I, SourceLocation Loc);

/// Build a new template name given a nested name specifier, a flag
/// indicating whether the "template" keyword was provided, and the template
Expand Down Expand Up @@ -5009,9 +5009,8 @@ QualType TreeTransform<Derived>::TransformHyperobjectType
SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
NewR = getDerived().TransformExpr(H->getReduce());
NewI = getDerived().TransformExpr(H->getIdentity());
NewD = getDerived().TransformExpr(H->getDestroy());
}
if (NewR.isInvalid() || NewI.isInvalid() || NewD.isInvalid())
if (NewR.isInvalid() || NewI.isInvalid())
return QualType();

QualType ElementType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Expand All @@ -5020,8 +5019,7 @@ QualType TreeTransform<Derived>::TransformHyperobjectType

QualType Result =
getDerived().RebuildHyperobjectType(ElementType, NewI.get(),
NewR.get(), NewD.get(),
TL.getHyperLoc());
NewR.get(), TL.getHyperLoc());

HyperobjectTypeLoc NewT = TLB.push<HyperobjectTypeLoc>(Result);
NewT.setHyperLoc(TL.getHyperLoc());
Expand Down Expand Up @@ -14693,9 +14691,8 @@ QualType TreeTransform<Derived>::RebuildDependentBitIntType(
template<typename Derived>
QualType TreeTransform<Derived>::RebuildHyperobjectType(QualType ElementType,
Expr *I, Expr *R,
Expr *D,
SourceLocation Loc) {
return SemaRef.BuildHyperobjectType(ElementType, I, R, D, Loc);
return SemaRef.BuildHyperobjectType(ElementType, I, R, Loc);
}

template<typename Derived>
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Cilk/hyper-errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ int _Hyperobject(reduce, identity) h;
// expected-error@-2{{incompatible function pointer types passing 'void (*)(void *)' to parameter of type 'void (*)(void *, void *)'}}

int _Hyperobject(x) i; // expected-error{{use of undeclared identifier 'x'}}
int _Hyperobject(0) j; // expected-error{{hyperobject must have 0, 2, or 3 callbacks}}
int _Hyperobject(0,0,0,0) k; // expected-error{{hyperobject must have 0, 2, or 3 callbacks}}
int _Hyperobject(0) j; // expected-error{{hyperobject must have 0 or 2 callbacks}}
int _Hyperobject(0,0,0,0) k; // expected-error{{hyperobject must have 0 or 2 callbacks}}
int _Hyperobject(0, 1) x; // expected-error{{incompatible integer to pointer conversion passing 'int' to parameter of type 'void (*)(void *, void *)'}}
Loading

0 comments on commit 58e0459

Please sign in to comment.