This patch supports construct trait set selector by using the existed
declare variant infrastructure inside OMPContext and simd selector is
currently not supported. The goal of this patch is to pass the declare variant
test inside sollve test suite.
Details
- Reviewers
jdoerfert - Commits
- rG976d474bec35: [OpenMP] Support construct trait set for Clang
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
clang/lib/AST/OpenMPClause.cpp | ||
---|---|---|
2344–2345 | I'm now removing this line since the properties are already added at line 2334 and not removing this line would lead to an extra iteration in OMPContext.cpp (check out the second diff), and the code will always return false even if the construct trait properties are added. Diff for OpenMPClause.cpp 2333 for (const OMPTraitProperty &Property : Selector.Properties) 2334 VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr); 2335 2336 if (Set.Kind != TraitSet::construct) 2337 continue; 2338 2339 // TODO: This might not hold once we implement SIMD properly. 2340 assert(Selector.Properties.size() == 1 && 2341 Selector.Properties.front().Kind == 2342 getOpenMPContextTraitPropertyForSelector( 2343 Selector.Kind) && 2344 "Ill-formed construct selector!"); 2345 2346 // VMI.ConstructTraits.push_back(Selector.Properties.front().Kind); Diff for lib/Frontend/OpenMP/OMPContext.cpp: 224 unsigned ConstructIdx = 0, NoConstructTraits = Ctx.ConstructTraits.size(); 225 for (TraitProperty Property : VMI.ConstructTraits) { 226 assert(getOpenMPContextTraitSetForProperty(Property) == 227 TraitSet::construct && 228 "Variant context is ill-formed!"); 229 230 // Verify the nesting. 231 bool FoundInOrder = false; 232 while (!FoundInOrder && ConstructIdx != NoConstructTraits) 233 FoundInOrder = (Ctx.ConstructTraits[ConstructIdx++] == Property); 234 if (ConstructMatches) 235 ConstructMatches->push_back(ConstructIdx - 1); 236 237 Optional<bool> Result = HandleTrait(Property, FoundInOrder); 238 if (Result.hasValue()) 239 return Result.getValue(); 240 241 if (!FoundInOrder) { 242 LLVM_DEBUG(dbgs() << "[" << DEBUG_TYPE << "] Construct property " 243 << getOpenMPContextTraitPropertyName(Property, "") 244 << " was not nested properly.\n"); 245 return false; 246 } 247 248 // TODO: Verify SIMD 249 } |
clang/test/OpenMP/declare_variant_construct_codegen_1.c | ||
---|---|---|
24 | This test is from sollve test suite: https://github.com/SOLLVE/sollve_vv/blob/master/tests/5.0/declare_variant/test_declare_variant.c |
Cool!
We certainly need more tests but the design you came up with is certainly nicer than what I had in mind.
One thing I wanted to do though is keep track of the constructs in the OpenMPIRBuilder instead. So move the
/// Vector of declare variant construct traits. SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
into OpenMPIRBuilder and add/delete the things there. It's not a conceptual difference but makes it easier
to opt-in for Flang later.
I also left some comments below. I don't think there is anything major though.
clang/lib/AST/OpenMPClause.cpp | ||
---|---|---|
2344–2345 | I'm not surprised some things need adjustment. Never tested construct trait matching much as we did not expose it via clang. Just delete the line if you think it's wrong. Also consider deleting the code before if it's not needed. | |
clang/lib/Sema/SemaOpenMP.cpp | ||
737 | Modification was made to make it clear what happens but now I think this is not needed. See below first. Maybe the interface should be "handleConstructTrait(Property, bool Insert)" and if Insert is false you verify it's the last one and delete it. You'd need to traverse them in opposite order though to verify, unsure if verification is therefore strictly necessary. | |
3900–3902 | ||
4497 | I know think you need to call something like addDeclareVariantConstructTrait again and do pop_back() instead of push_back() for each trait matching the DKind. Clearing, or erasing a fixed amount of traits, does not work. | |
6845 | Maybe we should pass the traits to the constructor, makes it clearer they have to be passed. |
One thing I wanted to do though is keep track of the constructs in the OpenMPIRBuilder instead. So move the
/// Vector of declare variant construct traits. SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;into OpenMPIRBuilder and add/delete the things there. It's not a conceptual difference but makes it easier
to opt-in for Flang later.
We don't have any OpenMPIRBuilder instance inside SemaOpenMP yet and the OpenMPIRBuilder constructor requires a Module parameter so I'm not sure how to achieve this, can you give me some suggestions?
clang/lib/Sema/SemaOpenMP.cpp | ||
---|---|---|
737 | For the delete part, I'm not sure how passing Property would work since I'm not deleting all the construct trait properties inside ActOnOpenMPRegionEnd function. |
clang/lib/Sema/SemaOpenMP.cpp | ||
---|---|---|
737 | I think I've figured out a way to achieve what you suggest. | |
4497 | So you are saying that instead of removing all the construct property inside ActOnOpenMPRegionEnd, we should delete those construct properties more fine-grained? I'd like to do so and has tried putting the insert/delete logic inside more specific function such as ActOnOpenMPParllell, |
clang/lib/AST/OpenMPClause.cpp | ||
---|---|---|
2487 | Nit: no braces. | |
clang/lib/Parse/ParseOpenMP.cpp | ||
2052 | {} might do it but this is fine too. | |
clang/lib/Sema/SemaOpenMP.cpp | ||
746 | So, SmalVector has a pop_back_val which we could use to verify the properties are the ones we expect. However, we would need to first put them into a vector and if insert is false we would need to reverse the vector.
Does that make sense? (Apologies for making you rewrite this twice.) |
clang/lib/Sema/SemaOpenMP.cpp | ||
---|---|---|
746 | This is not what I meant and I doubt this works. Let me try to explain with an example: handleDeclareVariantConstructTrait for a DSKind parallel_for will first add a parallel then a for construct trait. [ teams ] // enter parallel for code generation [ teams, parallel, for] ... // exit parallel for code generation at this point we want to pop for and then parallel from the end. If the last one on the stack was not for or the second to last was not parallel something went wrong. I proposed to accumulate all traits in handleDeclareVariantConstructTrait rather than passing them to handleConstructTrait one by one. stack = [teams, parallel, for] trait_set = [parallel, for] (passed to `handleConstructTrait` by `handleDeclareVariantConstructTrait) verification: for (trait in reverse(trait_set)) { stack_last = stack.pop_back_val(); assert(trait == stack_last && "Something left a trait on the stack!"); } Does this make sense? |
clang/lib/Sema/SemaOpenMP.cpp | ||
---|---|---|
746 | Thanks for your further explanation and patience, it really helps a lot for me to understand! |
clang/lib/Sema/SemaOpenMP.cpp | ||
---|---|---|
741 | I fixed -Wunused-variable in c5f480fcbec04f46a9cfcad08914665ff83d8d8a |
I'm now removing this line since the properties are already added at line 2334 and not removing this line would lead to an extra iteration in OMPContext.cpp (check out the second diff), and the code will always return false even if the construct trait properties are added.
Diff for OpenMPClause.cpp
Diff for lib/Frontend/OpenMP/OMPContext.cpp: