LLVM static analysis / RTOS stack safety

Compile-Time Stack Usage Analyzer

LLVM-native static analysis for worst-case stack usage

Why It Exists

Compiler flags can report local frame sizes, but embedded and RTOS systems need whole-program cumulative stack depth across call chains.

Tool Coverage Call-chain aware?
GCC -fstack-usage Per-function No
Clang -Wframe-larger-than Per-frame No
This tool Whole-program cumulative Yes

Architecture

The analyzer follows the LLVM pipeline from C source to IR, extracts call graph and machine-frame metadata, then computes worst-case stack depth in Python.

input

.c file

User C program, RTOS task code, or embedded firmware module.

LLVM IR

clang -S -emit-llvm

Produces upload.ll for downstream LLVM tooling.

C++ passes

stack-extractor + collector

Emits cg.json and sizes.json using LLVM call graph and MachineFrameInfo data.

solver

analyzer.py

Propagates stack costs, detects SCC recursion, and applies thresholds.

output

terminal report

Worst-case depths, call chains, recursion warnings, and RTOS task safety tables.

Demo

Drop in a short recording of the local dashboard flow: paste C code, run analysis, and inspect the stack report.

Sample Output

The CLI report highlights recursion risks, per-entry cumulative depths, and the deepest static call chains.

+---------------------------------------------------+
| ^ COMPILE-TIME STACK USAGE ANALYZER ^             |
| LLVM-Native High-Fidelity Static Frame Estimation |
+---------------------------------------------------+

+-------------------- WARNING: RECURSION ---------------------+
| ^ Recursion Loop: factorial -> factorial                     |
| ^ Recursion Loop: functionB -> functionA -> functionB        |
+-------------------------------------------------------------+

Entry Point Cumulative Stack Depths:
+-------------------------------+---------------+------------------+--------+
| Entry Point / Function Name    | Frame (Own)   | Worst-Case Depth | Status |
+-------------------------------+---------------+------------------+--------+
| main                           |    24 B       |       600 B      | OK     |
+-------------------------------+---------------+------------------+--------+

Top-5 Deepest Call Chains:
Call chain: main  [600 bytes cumulative]
`-- main (24 B frame) -> printf, process, functionA
    `-- process (552 B frame) -> factorial
        `-- factorial (24 B frame) -> factorial

Project Structure / Deliverables Status

The implementation combines LLVM C++ passes, a Python graph solver, a local dashboard, and evaluation artifacts.

# Deliverable Status
1 Per-function frame estimator (alloca, spills, padding) on MachineFunction Complete
2 Call graph traversal, worst-case cumulative depth per entry point Complete
3 Recursion detection (SCC), indirect call upper bound, inlining effects Complete
4 CLI tool: top-N deepest call chains with per-function breakdown Complete
5 RTOS evaluation comparing estimates to expected stack usage Complete