Page MenuHomePhabricator

[Clang][OpenMP] Add support for compare capture in parser
ClosedPublic

Authored by tianshilei1992 on Dec 23 2021, 8:16 PM.

Details

Summary

This patch adds the support for atomic compare capture in parser and part of
sema. We don't create an AST node for this because the spec doesn't say compare
and capture clauses should be used tightly, so we cannot look one more token
ahead in the parser.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
tianshilei1992 requested review of this revision.Dec 23 2021, 8:16 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptDec 23 2021, 8:16 PM
tianshilei1992 added inline comments.Dec 23 2021, 8:17 PM
clang/lib/Sema/SemaOpenMP.cpp
11380

This is the place where the dummy kind OMPC_compare_capture is used. We will have another use in CodeGen.

update test case

tianshilei1992 retitled this revision from [WIP][Clang][OpenMP] Add support for compare capture in parser to [Clang][OpenMP] Add support for compare capture in parser.Dec 25 2021, 10:49 AM
koops added a subscriber: koops.Jan 18 2022, 2:50 AM
tianshilei1992 edited the summary of this revision. (Show Details)Feb 8 2022, 9:24 AM
ABataev added inline comments.Feb 8 2022, 9:38 AM
clang/include/clang/AST/OpenMPClause.h
2277 ↗(On Diff #406867)

final

clang/lib/AST/OpenMPClause.cpp
1804 ↗(On Diff #406867)

Output?

clang/lib/Sema/SemaOpenMP.cpp
11334

Use LLVM_FALLTHROUGH

11374–11375

Why?

11824–11829

Emit in codegen

tianshilei1992 marked 2 inline comments as done.Feb 8 2022, 10:02 PM
tianshilei1992 added inline comments.
clang/lib/AST/OpenMPClause.cpp
1804 ↗(On Diff #406867)

I did it on purpose because OMPCompareCaptureClause is a dummy node. When it is visited (I really doubt if it can be visited because we don't create it explicitly), it should not output any thing. compare and capture are printed when visiting the two clauses.

clang/lib/Sema/SemaOpenMP.cpp
11374–11375

For the same reason for the output in AST.

ABataev added inline comments.Feb 9 2022, 7:37 AM
clang/lib/AST/OpenMPClause.cpp
1804 ↗(On Diff #406867)

Why? I see ActOnOpenMPCompareCaptureClause, which creates such nodes.

tianshilei1992 marked 2 inline comments as done.

rebase and mark related functions as unreachable

tianshilei1992 marked 3 inline comments as done.Feb 9 2022, 2:46 PM
tianshilei1992 added inline comments.
clang/lib/AST/OpenMPClause.cpp
1804 ↗(On Diff #406867)

I updated those functions. They should be unreachable.

clang/lib/Sema/SemaOpenMP.cpp
11824–11829

Since we are lack of Sema, putting it in Sema for now sounds more reasonable.

tianshilei1992 marked 2 inline comments as done.

use LLVM_FALLTHROUGH

tianshilei1992 marked an inline comment as done.Feb 9 2022, 2:48 PM
ABataev added inline comments.Feb 10 2022, 12:44 PM
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

Better to build a node and emit error in codegen. Without it you're unable to create ast-print/dump tests, test for serialization/deserialization etc.

cchen added a subscriber: cchen.Feb 10 2022, 1:31 PM
tianshilei1992 marked an inline comment as done.Feb 10 2022, 2:27 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

IIUC, OMPC_compare_capture will only be used in Sema and CodeGen to tell we actually want compare_capture instead of compare or capture. The corresponding class(es) have no actual use. If I could directly have OMPC_compare_capture w/o adding a class, I would like to do it. On the other hand, we already have a node for compare, and a node for capture, we don't want a node for compare and capture, especially the spec doesn't say they should be tightly close. That being said, it should not affect other functionality.

ABataev added inline comments.Feb 10 2022, 2:29 PM
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

Then why do you need OMPC_compare_capture? Just emit compare and capture and check for both of them at the same time.

tianshilei1992 marked 2 inline comments as done.Feb 10 2022, 2:38 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

OMPC_compare_capture is the natural way, especially when we call emitOMPAtomicExpr. Of course we can set Kind to OMPC_compare and add a boolean argument bool IsCompareCapture = false. It's just not as clear as this way, but TBH not a bad way.

tianshilei1992 marked an inline comment as done.Feb 10 2022, 2:38 PM
ABataev added inline comments.Feb 10 2022, 2:40 PM
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

I think it is better to have a flag (or an internal enum) rather than adding an extra external enum and a class just for internal processing.

remove the dummy node

tianshilei1992 edited the summary of this revision. (Show Details)Feb 10 2022, 3:18 PM
tianshilei1992 marked an inline comment as done.
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11818–11824

Done.

tianshilei1992 marked an inline comment as done.Feb 10 2022, 3:20 PM
ABataev added inline comments.Feb 11 2022, 6:57 AM
clang/lib/Sema/SemaOpenMP.cpp
11802–11817

Better not to emit error here, if possible. What's prevent this?

tianshilei1992 marked an inline comment as done.Feb 11 2022, 7:29 AM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11802–11817

I put it here because I think we don't have Sema support yet, so it is not good to move it to later phase like codegen because that will implicitly mean Sema has already passed but apparently it doesn't. Of course like atomic compare, I'll move it to codegen in the Sema patch.

tianshilei1992 marked an inline comment as done.Feb 11 2022, 7:29 AM

Add ast print with serialization/deserialization tests.

clang/lib/Sema/SemaOpenMP.cpp
11327

SmallVector with 2 elements should be enough, no need to use SmallSet here.

tianshilei1992 marked an inline comment as done.Feb 12 2022, 1:55 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11327

SmallVector doesn't provide contains, which we use to check if OMPC_compare and OMPC_capture exist at the same time. Using SmallVector requires us to have a complicated comparison, for example:

(EncounteredAtomicKinds[0] == OMPC_compare && EncounteredAtomicKinds[1] == OMPC_capture) || (EncounteredAtomicKinds[1] == OMPC_compare && EncounteredAtomicKinds[0] == OMPC_capture)

which is not as neat as SmallSet.

ABataev added inline comments.Feb 12 2022, 2:10 PM
clang/lib/Sema/SemaOpenMP.cpp
11327

Use llvm::find

tianshilei1992 marked 2 inline comments as done.Feb 12 2022, 2:18 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11327

That is linear time. Why it is better than SmallSet?

ABataev added inline comments.Feb 12 2022, 2:22 PM
clang/lib/Sema/SemaOpenMP.cpp
11327

Because there are only 2 elements, no?

tianshilei1992 marked 2 inline comments as done.Feb 12 2022, 2:29 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11327

It could have more. If user writes it like atomic compare compare capture capture capture, then it will have 5 elements. SmallSet<T>::insert returns a pair and we know if it is already in the set, which I have not added it yet but I'll. SmallVector then is not that easy to use. Of course you could say do llvm::find beforehand but it's not neat.

ABataev added inline comments.Feb 12 2022, 2:34 PM
clang/lib/Sema/SemaOpenMP.cpp
11327

Is this correct at all?

11327

You still can scan over the small vector and check if it has specified clause already.

tianshilei1992 marked 3 inline comments as done.Feb 12 2022, 2:41 PM
tianshilei1992 added inline comments.
clang/lib/Sema/SemaOpenMP.cpp
11327

It's not correct. We can easily check via the following code:

if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
  // emit an error
}

Using SmallVector we need to:

if (llvm::find(EncounteredAtomicKinds.begin(), EncounteredAtomicKinds.end(), C->getClauseKind() != EncounteredAtomicKinds.end()) {
  // emit an error
} else {
  EncounteredAtomicKinds.push_back(C->getClauseKind());
}

It's obvious which one looks better and have better readability. I can't see any point of using SmallVector here, unless there is huge performance difference, which I really doubt that matters.

tianshilei1992 marked an inline comment as done.

add tests

Erroneous tests?

clang/lib/Sema/SemaOpenMP.cpp
11327
if (llvm::find(EncounteredAtomicKinds, C->getClauseKind() != EncounteredAtomicKinds.end()) {
  // emit an error
} else {
  EncounteredAtomicKinds.push_back(C->getClauseKind());
}

but ok, let's keep SmallSet

We don't have Sema yet, so there is no erroneous test.

We don't have Sema yet, so there is no erroneous test.

But you have the checks for the clauses, repeated several times in a construct.

add a small test

This revision is now accepted and ready to land.Feb 18 2022, 4:31 AM
This revision was landed with ongoing or failed builds.Feb 18 2022, 7:24 AM
This revision was automatically updated to reflect the committed changes.