graph TD A["Source Code (.c file)"] --> B[AST]; B --> C[LLVM IR]; C --> D[Assembly]; subgraph Clang-Frontend A -- parser --> B; B -- lowering --> C; end subgraph LLVM C -- "optimizer (opt)" --> C; C -- "backend (llc)" --> D; end A:::source B:::ast C:::ir D:::asm classDef source fill:#FFD700, stroke:#FFA500, stroke-width:2px, color:#000; classDef ast fill:#87CEFA,stroke:#1E90FF,stroke-width:2px; classDef ir fill:#98FB98,stroke:#3CB371,stroke-width:2px; classDef asm fill:#FFA07A,stroke:#FF6347,stroke-width:2px;
graph TD BBA["Basic Block A"] --> PHI["%x.1 = phi\n[ %x.0, BB-A ], [ %x.2, BB-B ]"] BBB["Basic Block B"] --> PHI PHI --> USE["%result = add i32 %x.1, %y.1"] style BBA fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style BBB fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style PHI fill:#fff9c4,stroke:#f57f17,stroke-width:3px style USE fill:#ffccbc,stroke:#bf360c,stroke-width:3px
graph TD MOD[ModuleOp] --> FUNC{Operation\ne.g., FuncOp} FUNC --> REG[Region\nordered list of blocks] REG --> BLK[Block\nentry block + args] BLK --> OP[Operation\n...] OP -.->|"can contain"| REG style MOD fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style FUNC fill:#fff9c4,stroke:#f57f17,stroke-width:3px style REG fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style BLK fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px style OP fill:#ffccbc,stroke:#bf360c,stroke-width:3px
graph LR HL["High-Level\nDialect Ops"] -->|"Dialect Conversion\n(Dag-to-Dag rewrites)"| ML["Mid-Level\nDialect Ops"] ML -->|"Partial / Full Conversion"| LL["Low-Level\nDialect Ops"] LL -->|"Type Conversion"| TGT["Target\n(e.g., LLVM IR)"] style HL fill:#e3f2fd,stroke:#1565c0,stroke-width:3px style ML fill:#fff9c4,stroke:#f57f17,stroke-width:3px style LL fill:#fff9c4,stroke:#f57f17,stroke-width:3px style TGT fill:#c8e6c9,stroke:#2e7d32,stroke-width:3px