Debugging flang

This guide aims at presenting different debugging tools and techniques available in flang.

Invocation and debuggers

flang binary program actually calls flang1 and flang2, so running gdb or lldb on flang makes little sense unless you account for this for example by setting follow-fork-mode child in gdb before starting the process.

It might be easier though to invoke gdb/lldb with flang1 and flang2 instead.

flang1 produces ILM, consumed by flang2 which translates from ILM to ILI and then to LLVM IR assemblies.

Note that you need to pass the -DCMAKE_BUILD_TYPE=Debug flag to cmake to enable the debugging symbols in the binary.

Debugging output dumps

Both flang1 and flang2 are capable of providing a large number of diagnostic outputs. By default they are written into a file ending in .qdbg in the current working directory. Alternatively you can use debug flag -q,0,1 to redirect the output to standard output.

The flags are enabled by passing -q or -qq parameters, always carrying a “flag,value” pair. On flang invocation level the flags must be specified for either flang1 or flang2, by specifying “H” or “M” respectively.

See Coding Practices for details of the flang2 flags meanings.

Example 1: print human-readable ILM representation as read by flang2 for further processing:

$ flang -c func.f90 -Mq,0,1 -Mq,4,1

Example 2: print human-readable ILI representation as used internally by flang2:

$ flang -c hello.f90 -Mq,0,1 -Mq,10,2 -Mq,10,1

In the source code these flags are represented by flg.dbg[i], where i is the flag number.

The -qq parameter causes debug routines to dump human-readable views of various internal data structures. The syntax is:

-qq,<phase_name>,<object_name>

E.g. to dump flang1 AST, one can pass -Hq,0,1 -Hqq,parser,ast to the compiler, or to dump flang1 symtab, one can pass -Hq,0,1 -Hqq,parser,symtab to the compiler.

The available phase names are: init, parser, bblock, vectorize, optimize, schedule, assemble, xref, unroll

The available object names are: ast, dtype, std, sstd, stdp, sym, syms, symtab, allsym, stats, area, olddtype, odtype, oldsym, osym, hsym, hsyms, common, commons, nast, stdtree, stdtrees, shape, aux

Note: In case you are passing arguments to flang1 or flang2 directly, you need to skip the “H” or “M” prefix and replace commas with whitespaces. For example, the two commands should give the same debugging output:

flang -Hq,0,1 -Hq,3,8 -Hq,47,1 -Hqq,parser,symtab example.f90
/usr/local/bin/flang1 -q 0 1 -q 3 8 -q 47 1 -qq parser symtab example.f90

flang1 and flang2 command line options

As mentioned in Invocation and debuggers, you may often need to run flang1 and flang2 separately in the debugger and thus provide them with all the parameters that a normal flang invocation would. Unfortunately flang1 and flang2 do not have --help option, so here is a list of possible options and their functionality. For flang1:

Flang1 Option

Explanation

filename

source file name (method 1 of 2)

src

source file name (method 2 of 2)

output

output .ilm text file name (will contain STB + ILM)

stbfile

output .stb symbol table text file name (will contain STB only)

modexport

output .cmod text file name, collective content of all modules exported by given Fortran source file (note that separate .mod files will be also generated by Flang1!)

modindex

output .cmdx text file containing index of exported modules (including offsets in .cmod file where each of the modules begins)

qfile

output debug .qdbg text file name, see -q 0

opt

optimization level

def

same as clang’s -D

undef

same as clang’s -U

idir

same as clang’s -I

moddir

same as flang’s -J

x

magic x parameter

y

magic y parameter (turn off the corresponding x flag)

q

magic debug parameter

qq

magic dump parameter

mp/nomp

process OpenMP pragmas

preprocess /nopreprocess

process C preprocessor directives in Fortran code same as clang’s -D

reentrant /noreentrant

local variables should have RECURSIVE semantics instead of SAVE semantics (same as recursive/norecursive below); also inhibit special treatment of terminus functions

terse

reduce verbosity of error messages (0 = don’t reduce)

inform

increase verbosity level of error messages

hpf/nohpf

handle HPF (High Performance Fortran) - off by default doesn’t seem to be fully implemented!

static /nostatic

enable IPA (inter-procedural analysis), doesn’t seem to do anything, always set to OFF

quad //noquad

quad align (round-up size) “unconstrained objects” if sizeof >= 16

freeform /nofreeform

allow free form code

tp

Intel-specific target architecture name

stdinc

‘:’-separated list of include directories

vect

vectorizer settings (bitmask), doesn’t seem to be examined anywhere in the frontend

standard /nostandard

be strict about standard, e.g. disallow use of <> instead of /= or .ne.

save /nosave

local variables should have SAVE semantics instead of RECURSIVE semantics (typically used for overriding OpenMP’s default using -Msave)

extend /noextend

allow lines up to 132 characters length (instead of 72 characters)

recursive /norecursive

local variables should have RECURSIVE semantics instead of SAVE semantics (OpenMP’s default, can be forced by -Mrecursive)

cmdline

override command line used to invoke the compiler

And for flang2:

Flang2 Option

Explanation

filename

source .ilm file name

fn

(the original) Fortran source file name

stbfile

input .stb symbol table text file name

opt

output .ll LLVM IR text file name

asm

same as clang’s -D

vh

build host; doesn’t seem to have any use currently

x

magic x parameter

y

magic y parameter (turn off the corresponding x flag)

q

magic debug parameter

qq

magic dump parameter

ieee

1 = -Kieee (set by default), 0 = -Knoieee or -fast-math or -Ofast

inform

increase verbosity level of error messages

endian

force endianness, 0 = little, 1 = big

mp/nomp

process OpenMP pragmas

reentrant /noreentrant

local variables should have RECURSIVE semantics instead of SAVE semantics (same as recursive/norecursive below); also inhibit special treatment of terminus functions

terse

reduce verbosity of error messages (0 = don’t reduce)

quad /noquad

quad align (round-up size) “unconstrained objects” if sizeof >= 16

tp

Intel-specific target architecture name

save /nosave

local variables should have SAVE semantics instead of RECURSIVE semantics (typically used for overriding OpenMP’s default using -Msave)

astype

assembler syntax: 0 = ELF, 1 = COFF

vect

vectorizer settings (bitmask), doesn’t seem to be examined anywhere in the frontend

debug /nodebug

debug ON/OFF flag

recursive /norecursive

local variables should have RECURSIVE semantics instead of SAVE semantics (OpenMP’s default, can be forced by -Mrecursive)

cmdline

override command line used to invoke the compiler

xflags

Compilers have a number of supported and unsupported switches that are used internal to the compilers. These are referred to as “xflags”. See Other Compiler Switches for details on the available xflags and how to use them.

In the code these flags are represented by flg.x[n], where n is the ID of the flag.