This is an archive of the discontinued LLVM Phabricator instance.

[flang] Upstream changes to the PFT data structure
ClosedPublic

Authored by schweitz on May 22 2020, 10:29 AM.

Details

Summary
[flang] Batch together the changes to the PFT intermediate data
structure for upstreaming to llvm-project.

These files have had many changes since they were originally upstreamed.
Some of the changes are cosmetic.  Most of the functional changes were
done to support the lowering of control-flow syntax from the front-end
parse trees to the FIR dialect.

This patch is meant to be a reviewable size. The functionality it
provides will be used by code yet to be upstreamed in lowering.

Generation of FIR (Fortran IR, a dialect of MLIR) from the front end f18 parse tree, occurs in two steps.

The first step builds a Pre-Fir Tree (PFT), a light weight tree of relevant indexes into the parse tree. This is done with a primary pass over the parse tree for a source file, which invokes a secondary pass at the function level. The primary pass creates the PFT data structure and fills in sequential pass information such as lexical successors for statements. The secondary pass (function analyzeBranches) is invoked at the end of each source function to fill in non-sequential branching information, such as the targets of goto statements.

The second step traverses the PFT to generate FIR. This step also has a primary traversal pass and a secondary, per-function pass. In this case, the secondary pass (function createEmptyBlocks) is a pre-pass invoked at the beginning of the primary pass for each function, which uses information gathered in the first step to generate most MLIR basic blocks in advance. The primary pass over the PFT then generates code in sequential order, which is possible since branch targets are valid without differentiating between forward and backward branches.

Diff Detail

Event Timeline

schweitz created this revision.May 22 2020, 10:29 AM

Thanks @schweitz for submitting this change. I also felt that putting out all the changes in PFTBuilder as a single step is the best way forward while preparing D79731. I guess this will simplify the introduction of the bridge code.

I see that bulk of the changes are in PFTBuilder.h and PFTBuilder.cpp. Many are cosmetic but some changes look like a design change? I have summarised below the changes that I saw just for reference. It will be great to have some more explanation for the key changes in the code or in the commit message. Particularly for the introduction of the ReferenceVariant, removal of the annote functions, CFGannotations enum and the introduction of analyse functions.

Also, should any of the new pointers introduced in Evaluation/PFTBuilder struct/class be smart pointers?

PFTBuilder.h
-> Rename
EvaluationCollection to EvaluationList
ParentType to ParentVariant
Split constructs into constructs and directives.
FunctionLikeUnit:
evals -> evaluationList
funcs -> nestedFunctions (also in Module like unit)

-> Modification
createPFT function takes another argument semanticsContext

-> Introduce
LabelEvalMap type (an llvm dense map from Label to Evaluation*)
isIntermediateConstructStmt, isNopConstructStmt template variable expressions.
Types LabelSet, SymbolRef, SymbolLabelMap
ReferenceVariant class and helpers.
EvaluationTuple, EvaluationVariant, struct Evaluation
Struct variable
FunctionLikeUnit:
Functions to get location
LabelEvalMap labelEvaluationMap;
SymbolLabelMap assignSymbolLabelMap;
const semantics::Symbol *symbol{nullptr};
mlir::Block *finalBlock{};
std::vector<std::vector<Variable>> varList;

-> Remove
CFGAnnotation
CGJump
annotateControlFunction

PFTBuilder.cpp
-> Rename
All names with Eval changed to Evaluation. (dumpEvalList -> dumpEvaluationList)
evallist -> evaluationListStack
parents -> parentVariantStack

-> Introduce
getConstructName function
struct SymbolDependenceDepth and processSymbolTable function
const semantics::SemanticsContext &semanticsContext;
std::vector<lower::pft::Evaluation *> constructAndDirectiveStack{};
std::vector<lower::pft::Evaluation *> doConstructStack{};
llvm::DenseMap<parser::Label, lower::pft::Evaluation *> *labelEvaluationMap{nullptr};
lower::pft::SymbolLabelMap *assignSymbolLabelMap{nullptr};
std::map<std::string, lower::pft::Evaluation *> constructNameMap{};
lower::pft::Evaluation *lastLexicalEvaluation{nullptr};

-> Modification
analyzeBranches kind of replaces the annotate* functions. It is also called during PFT construction and hence need not be called separately, hence the call to annotateControl is not needed from f18.cpp.

Pre-fir tree tests
Minor change in tests {introduces space, distinguishes structured and unstructured}

flang/include/flang/Lower/PFTBuilder.h
46

Why is this not a reference variant?

134

nit: holds->hold

336

nit: remove this?

flang/lib/Lower/PFTBuilder.cpp
1044

nit: Remove this

schweitz edited the summary of this revision. (Show Details)May 26 2020, 3:08 PM
schweitz updated this revision to Diff 266361.May 26 2020, 3:50 PM

respond to some of the issues Kiran raised

schweitz updated this revision to Diff 266658.May 27 2020, 2:01 PM

add a mutable reference variant data structure to hide pointers

Looks OK to me. It will be great if @tskeith can review.

This revision is now accepted and ready to land.May 28 2020, 4:05 PM
schweitz updated this revision to Diff 267267.May 29 2020, 9:43 AM

Add a bit of implementation to replace a "stub" comment that related to supporting Fortran beyond F77.