Skip to content

Clang OpenMP

Clang Frontend OpenMP Handling Notes

Context

  • Target input: tests/nonsmoke/functional/input_codes/axpy_omp.c.
  • Goal: compile the source with ./build/bin/rose-compiler while ensuring generated code (rose_axpy_omp.c) preserves OpenMP pragmas and is accepted by stock clang.
  • Environment: Clang/LLVM 20 frontend in ROSE (“rex”).

Findings & Fixes

  • Clang builtin redeclarations: local prototypes for __builtin_va_start/__builtin_va_end/__builtin_alloca conflicted with the Clang 20 headers. Added __has_builtin guards and adjusted signatures to match Clang’s runtime expectations.
  • OpenMP command-line detection: prior behaviour never forwarded -fopenmp to Clang, so OpenMP constructs were ignored. The frontend now:
  • Detects -fopenmp, -fopenmp-simd, and _OPENMP defines.
  • Sets LangOptions::OpenMP/OpenMPSimd when present.
  • For pure passthrough mode it suppresses reinsertion of _OPENMP into define_list, avoiding macro redefinition.
  • Loop condition canonicalization: Clang unparses for (int i = 0; ((long)((int)i)) < ((long)n); ++i) inside OpenMP regions. Clang’s OMP semantic checks reject that. VisitForStmt now strips redundant cast layers before rebuilding the test expression so the unparser emits i < n.
  • Pragma preservation: Instead of dropping the directive or asserting, VisitOMPExecutableDirective captures the source text (#pragma ...) and attaches it as PreprocessingInfo to the associated statement. During unparsing the original directive is reproduced verbatim, satisfying the passthrough requirement.
  • Captured statements: OpenMP target regions introduce CapturedStmt nodes. The previous ROSE_ASSERT(FAIL_TODO==0) aborted. The traversal now simply forwards the captured body (or inserts a null statement), enabling the generic pragma path.
  • Array subscripting casts: the earlier generated code used nested casts such as ((char *)((char **)argv)[1]). VisitArraySubscriptExpr now normalises pointer casts when the base expression originates from an array decaying to a pointer, preventing -Wint-to-pointer-cast.

Proposed Mode Strategy

  1. Pure passthrough (current focus)
  2. Triggered when users supply -fopenmp without ROSE-specific OpenMP controls.
  3. Behaviour: treat OpenMP directives as opaque text, attach them (as SgPragmaDeclaration or PreprocessingInfo), do not build ROSE OpenMP IR. Unparser emits original pragmas. Generated C is accepted by clang -fopenmp.
  4. Status: implemented with PreprocessingInfo attachment.

  5. ROSE OpenMP AST construction + lowering (future)

  6. Triggered by -fopenmp plus existing -rose:openmp:* options.
  7. Behaviour: reuse the mature legacy frontend-based pipeline—parse pragmas, build ROSE OpenMP IR, then generate lowered multithreaded code. Clang frontend would need parity with the legacy frontend path (currently incomplete).

  8. Clang-native OpenMP-to-SAGE translation (long-term)

  9. Triggered by an explicit --rex-openmp-clang or similar.
  10. Behaviour: rely on Clang’s OpenMP AST nodes to build precise ROSE IR, bypassing text-based handling.
  11. Status: not yet implemented; would require comprehensive mapping from Clang OpenMP classes to SgOmp* nodes.

Outstanding Items

  • Evaluate whether pure passthrough should use SgPragmaDeclaration instead of raw PreprocessingInfo for improved tooling compatibility.
  • Investigate compatibility of existing ROSE OpenMP lowering passes when driven from Clang ASTs (mode 2).
  • Design command-line UX for selecting between modes 1–3 without confusing legacy frontend users.
  • Add regression coverage: run rose-compiler -fopenmp and verify that the emitted pragmas and loop headers remain canonical.

Practical Notes

  • The current passthrough path allows the user to recompile the generated file with clang-20 -fopenmp successfully.
  • When no OpenMP flags are supplied, pragmas remain untouched but Clang also does not attempt to parse them as structured directives, matching legacy frontend’s historical behaviour.
  • Mode selection logic lives entirely in clang-frontend.cpp; no build-system changes are required.