Call Graph for RPG Programs, Built From Your IBM i Source

  • November 8, 2026
  • Ty Woods
  • 9 min read

A change request lands on your desk for one RPG program. The program itself is small. The question that matters is which jobs reach it, because it may never be called directly. A nightly job starts one program, and four calls later your small program runs inside a job nobody linked to it. A call graph is the map that answers that question before anyone approves the change.

What a call graph is

A call graph is a directed graph of the calling relationships inside a program or a set of programs. Each node stands for a procedure. Each edge says that one procedure calls another, and the arrow points from the caller to the program it calls.

On IBM i, the nodes your team cares about are programs and the procedures inside them. The edges are the calls between them. Follow the arrows from a job’s first program and you see every program that job can reach. Follow them backward from one program and you see every caller that can bring it into a run.

A call graph also works as documentation for people. A developer who joins the team can open the graph for a job and see its shape in one look.

Static and dynamic call graphs

There are two kinds of call graph, and they answer different questions.

A dynamic call graph records what happened during one run of the code, for example from a profiler. It is exact for that run. It says nothing about the month end branch that did not run that night, or the error path that runs twice a year.

A static call graph is built from the source, and it tries to cover every possible run. Because it has to cover every path, it usually overapproximates. It can include calls that exist in the code but never happen in practice. For change work on an old library, that is the safer side to err on, because a call that might happen is a call your test team should know about.

A static call graph is what an IBM i team needs before it changes code. It shows every call the source spells out, including the ones nobody has run in a long time.

What a call graph shows in an RPG library

An IBM i team asks practical questions about calls, and a call graph built from the source answers each one.

Question your team asks What the call graph gives you
Which jobs can reach this program? Every chain of callers, traced back to the program at the top of each chain
What does this job run, start to finish? Every program below the job’s first program, down each chain of calls
Which programs does nothing call? The programs with no caller anywhere in the source you provided
If we change this program, who else should test? The callers above it and the programs below it
Which programs run inside many jobs? The programs with many callers, which need a careful review before any change

A call graph covers calls. Programs also share files and copy members, and those links matter just as much. Our post on how copy members hide dependencies covers that side of the map.

How AS/Forward builds the call graph from your source

AS/Forward ingests your IBM i source through a proprietary ingestion layer, along with the DDS around it. It builds a dependency map across the whole codebase before any AI model sees a line of code. That map covers programs, files and copy members, and it surfaces the call chains between programs. The call graph is part of the same map, so a call and a shared file show up in one place. The model then works from that map and from the descriptions. We don’t hand raw code to a language model and hope for the best.

Each program in the Programs view shows its source, a plain-English description, its dependency edges, its warnings and its confidence status. The IBM i Navigator shows how each program connects to the files and procedures it uses. When your team follows a call chain, each step comes with a description of what that program does. A long chain of program names becomes a chain of short explanations.

The analysis runs inside your infrastructure. The preferred deployment is fully local and air-gapped, so your source stays on your network. You pick the model that works from the map and the descriptions, whether Claude, OpenAI, Gemini or one you run locally.

Tracing one job from its first program

Pick one job on your own system, such as the month end close. An operator starts it from a menu, and its first program calls other programs. Each of those programs can call more, and the chain can run several programs deep.

Without a call graph, a developer learns that chain by opening each program in turn and searching for calls. He writes the chain on a notepad, and the notepad stays on his desk. With a call graph, he opens the first program and sees every program below it. He can open any step and read its plain-English description before he opens its source.

Now reverse the question. Your developer starts at the program that updates the customer balance and follows the arrows upward. Each caller leads to the next one, until every chain ends at a program that nothing in the source calls. Your developer knows which of those programs start a job. The answer becomes a list of jobs, and each job on it has a path your team can check by hand.

That reverse trace matters for change work. When a program has many callers, a change to it lands inside many jobs. When it has one caller, the change is easier to contain. Your reviewer sees which case he has before the change goes to test.

We run this analysis inside your network and hand your team the map. Your developers do the tracing, and the map shortens each trace.

The programs nothing calls

A call graph shows procedures that no caller reaches. In an old RPG library, a program may have lost its only caller in a rewrite years ago and stayed in the library ever since.

The analysis flags code that nothing references, and your team decides what to retire. That decision stays with your people, because a scheduler entry or an operator menu can start a program, and the source does not show either one. A program with no caller in the source is a strong candidate for retirement. Your team still confirms it before anyone removes it.

Every program your team retires is one less program to test and convert later. You also know the size of any modernization job up front, program by program, once the retired programs come off the list. The list of programs nothing calls shrinks the work before the work starts.

Where a static call graph stops

A static call graph is only as complete as the source behind it.

Some calls are built at run time. When a program assembles the name of the program it calls from a parameter, the target does not appear in any static cross-reference. No tool that reads source can see that value. Your developers usually know where these calls live, and they belong on a short list beside the graph.

Copy members can leave gaps too. A copy member pulls source into a program at compile time. When the analysis cannot find a copy member, AS/Forward lists it as unresolved, and that list shows exactly where the map stops. Your team finds the missing source, and the map fills in. Each program also carries a readiness status based on how confident the ingestion layer is in what it read. Clean programs are marked ready, and programs with gaps go to human review first.

IBM’s DSPPGMREF command has the same limit. It captures a program’s references when the program is compiled, so a program name built at run time does not show up there either.

Using the map for change review and conversion

The call graph pays off the day someone proposes a change. Your reviewer opens the program, follows the callers up to each job, and follows the calls down to each program below. The Migration view adds the other half: pick a field or an object, and see what else would need to change, down to programs, logical files, display files and reports. The question “If we touch this, what else moves?” gets a list for an answer.

That list feeds change impact analysis and the test plan that follows. It also feeds a conversion. A team converting code program by program can start with programs at the edge of the call graph and work inward, with a person on your team reviewing every change.

Your team picks the target. We clean up fixed-format RPG to free-format and keep it on IBM i, or we convert it to Python or another language you choose. Some teams want to keep their green screens, and we modernize the programs behind them. Every one of those outcomes is valid, and the call graph supports each one.

Get a call graph of your RPG library

Your first step is the IBM i modernization assessment. It gives you the program count, the dependency map with its call chains, a plain-English description of each program and the list of programs nothing calls. It sizes any work that follows, and the decision about what comes next stays with you.

Tell us how many source libraries you run and which job you would trace first. Call 501-232-7188, or reach us through our contact page.

Leave a Reply

Your email address will not be published. Required fields are marked *