This is an archive of the discontinued LLVM Phabricator instance.

[OPENMP] Initial codegen for 'omp task' directive.
ClosedPublic

Authored by ABataev on Feb 11 2015, 7:06 AM.

Details

Summary

The task region is emmitted in several steps:

  1. Emit a call to kmp_task_t *__kmpc_omp_task_alloc(ident_t *, kmp_int32 gtid, kmp_int32 flags, size_t sizeof_kmp_task_t, size_t sizeof_shareds, kmp_routine_entry_t *task_entry). Here task_entry is a pointer to the function:
kmp_int32 .omp_task_entry.(kmp_int32 gtid, kmp_task_t *tt) {
  TaskFunction(gtid, tt->part_id, tt->shareds);
  return 0;
}
  1. Copy a list of shared variables to field shareds of the resulting structure kmp_task_t returned by the previous call (if any).
  2. Copy a pointer to destructions function to field destructions of the resulting structure kmp_task_t.
  3. Emit a call to kmp_int32 __kmpc_omp_task(ident_t *, kmp_int32 gtid, kmp_task_t *new_task), where new_task is a resulting structure from previous items.

Diff Detail

Repository
rL LLVM

Event Timeline

ABataev updated this revision to Diff 19752.Feb 11 2015, 7:06 AM
ABataev retitled this revision from to [OPENMP] Initial codegen for 'omp task' directive..
ABataev updated this object.
ABataev edited the test plan for this revision. (Show Details)
ABataev added a subscriber: Unknown Object (MLST).
rjmccall edited edge metadata.Feb 26 2015, 6:53 PM

Sorry for the delay.

In general, your code is very difficult to read; it doesn't use any vertical whitespace within functions at all, so I can't easily understand how things are supposed to be grouped.

The basic implementation seems fine, though I have a number of requests:

lib/CodeGen/CGOpenMPRuntime.cpp
118 ↗(On Diff #19752)

Build this type lazily, please.

119 ↗(On Diff #19752)

A better way of commenting the next few lines would be to just write the struct definition out and then put all the addFieldToRecordDecl calls together.

133 ↗(On Diff #19752)

Build this type lazily, please.

252 ↗(On Diff #19752)

It looks like the invariants about getThreadIDVariable have changed; it used to always be an int32*, and now it can be either that or an int32. EmitThreadIDAddress appears to still assume that it's an ident*. You should fix that and then add a test that the OpenMP constructs using that still work correctly within a task.

You should also document this on CGOpenMPRegionInfo::ThreadIDVar.

257 ↗(On Diff #19752)

Missing braces.

1009 ↗(On Diff #19752)

Somewhere around here would be a good place to put the code that lazily builds KmpTaskTRD.

1012 ↗(On Diff #19752)

Comment, please. Please include the fact that this leaves the RecordDecl incomplete.

Also, RD has to be KmpTaskTRD, so remove that argument and make this take the CGOpenMPRuntime.

1093 ↗(On Diff #19752)

Please add a newline after this comment to make it clear that it's describing the next sequence of steps as a whole.

lib/CodeGen/CGOpenMPRuntime.h
17 ↗(On Diff #19752)

I don't think you need this; you can just forward-declare QualType. If you do need this, you can remove the forward-declaration of RecordDecl, I am positive that Type.h does that already.

288 ↗(On Diff #19752)

I was concerned about awkwardly making a single function do completely different things based on weird defaulted parameter, but it turns out that those types are exactly the same.

Would it be more appropriate to say that this creates an outlined function, and that if PartID is given, it's bound to the appropriate parameter value?

Although it also looks like PartIDVar is completely ignored except for an assertion. Is that expected to change?

lib/Sema/SemaOpenMP.cpp
1124 ↗(On Diff #19752)

This seems be hard-coding KMP runtime assumptions into Sema and the AST. Is that unavoidable?

John, thanks for the review!

lib/CodeGen/CGOpenMPRuntime.cpp
118 ↗(On Diff #19752)

Ok

119 ↗(On Diff #19752)

Ok

133 ↗(On Diff #19752)

Ok

252 ↗(On Diff #19752)

I'll fix it.

257 ↗(On Diff #19752)

My bad, will be fixed

1012 ↗(On Diff #19752)

Ok, I'll improve it

1093 ↗(On Diff #19752)

Ok, will be done.

lib/CodeGen/CGOpenMPRuntime.h
17 ↗(On Diff #19752)

I'll fix it.

288 ↗(On Diff #19752)

I'll try to split this function in two - one for tasks and another one for parallel regions. I think this is better, rather than keep too complex single function.

lib/Sema/SemaOpenMP.cpp
1124 ↗(On Diff #19752)

Unfortunately, no. I'm trying to avoid runtime assumptions in common code, but sometimes (like function parameters for outlined functions) I'm just forced to make some hard-coding of runtime specific features.

ABataev updated this revision to Diff 20986.Mar 2 2015, 1:33 AM
ABataev edited edge metadata.

Update after review

Sorry for the delay. Phabricator's been acting up; you'll notice a couple of comments that I wasn't able to delete, because deleting them locked the webpage up and never applied the deletion. Hooray for tools.

Generally looking better.

lib/CodeGen/CGOpenMPRuntime.cpp
44 ↗(On Diff #20986)

Okay. I think I see what you've done here with the subclass, so that this always produces a ident_t l-value, and thus its address is always an ident_t*. That makes a lot of sense to me. Please document that.

91 ↗(On Diff #20986)

.

170 ↗(On Diff #20986)

.

171 ↗(On Diff #20986)

.

229 ↗(On Diff #20986)

This is a great assertion, thanks.

1138 ↗(On Diff #20986)

*Indexes* of fields in type kmp_task_t.

1200 ↗(On Diff #20986)

Closing parenthesis. Also, I'd make a getter for this instead of inlining it here.

1230 ↗(On Diff #20986)

Argument comments are useful when somebody reading the code might not understand the purpose of the argument. In this case, that purpose is pretty obvious from the argument expression itself, so the comment is useless.

1266 ↗(On Diff #20986)

It's generally better to emit helper functions in a separate function, so that any particular function only knows about one CodeGenFunction object:

  • It removes some code from what's already a pretty large function.
  • It makes the shared data between the two functions a lot more obvious.
  • It removes any confusion about which function any particular llvm::Value* is valid in, so that you aren't tempted to (e.g.) use SharedsParam in the CGF function instead of the TaskEntryCGF function.
1302 ↗(On Diff #20986)

You're probably going to need to ask Sema to generate a copy constructor expression to get this right in C++. Feel free to do that in a separate patch.

1318 ↗(On Diff #20986)

Nothing cares about the result of this call?

lib/CodeGen/CGOpenMPRuntime.h
273 ↗(On Diff #20986)

I'd write these as parameter names, i.e. void (*)(kmp_int32 *ThreadID, kip_int32 BoundID, struct context_vars*). The C-style comment right next to the * is really hard to read.

282 ↗(On Diff #20986)

Same thing. Just write these comments as parameter names.

lib/CodeGen/CGStmtOpenMP.cpp
737 ↗(On Diff #20986)

You don't need to comment obvious arguments like this (and like a few other places nearby). The reader understands what the purpose of the argument is, and "K=" doesn't add anything meaningful anyway.

746 ↗(On Diff #20986)

Braces.

John, thanks for the review!

lib/CodeGen/CGOpenMPRuntime.cpp
44 ↗(On Diff #20986)

Ok, will do

1138 ↗(On Diff #20986)

Ok, thanks.

1200 ↗(On Diff #20986)

Ok, agree, that getter would look much better.

1230 ↗(On Diff #20986)

Ok, removed

1266 ↗(On Diff #20986)

Agree, I will create a separate function for proxy function

1302 ↗(On Diff #20986)

I don't think I need to call a copy constructor here. Actually structure with a list of shared variables is always POD type (it stores only pointers and integer values), so we can simply copy it

1318 ↗(On Diff #20986)

The check is required for untied tasks only, but they are not supported yet. I'll add TODO here.

lib/CodeGen/CGOpenMPRuntime.h
273 ↗(On Diff #20986)

Fixed

282 ↗(On Diff #20986)

Fixed

lib/CodeGen/CGStmtOpenMP.cpp
737 ↗(On Diff #20986)

Ok, removed

746 ↗(On Diff #20986)

Fixed

ABataev updated this revision to Diff 21551.Mar 10 2015, 12:15 AM

Update after review

Okay, if all the shareds are by-reference or something, that certainly simplifies things.

LGTM, thanks!

This revision was automatically updated to reflect the committed changes.