惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Cisco Blogs
NISL@THU
NISL@THU
G
GRAHAM CLULEY
T
Threatpost
I
Intezer
D
Darknet – Hacking Tools, Hacker News & Cyber Security
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Cisco Talos Blog
Cisco Talos Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
P
Palo Alto Networks Blog
L
LINUX DO - 热门话题
Cyberwarzone
Cyberwarzone
AI
AI
Help Net Security
Help Net Security
Forbes - Security
Forbes - Security
T
The Exploit Database - CXSecurity.com
月光博客
月光博客
The GitHub Blog
The GitHub Blog
aimingoo的专栏
aimingoo的专栏
C
CERT Recently Published Vulnerability Notes
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
News and Events Feed by Topic
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Scott Helme
Scott Helme
A
About on SuperTechFans
N
Netflix TechBlog - Medium
TaoSecurity Blog
TaoSecurity Blog
V
V2EX
MongoDB | Blog
MongoDB | Blog
AWS News Blog
AWS News Blog
Google DeepMind News
Google DeepMind News
Google Online Security Blog
Google Online Security Blog
O
OpenAI News
Y
Y Combinator Blog
S
Securelist
GbyAI
GbyAI
D
Docker
SecWiki News
SecWiki News
The Hacker News
The Hacker News
有赞技术团队
有赞技术团队
T
Tenable Blog
WordPress大学
WordPress大学
S
SegmentFault 最新的问题
P
Privacy International News Feed
S
Security Affairs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News - Newest:
Hacker News - Newest: "LLM"
H
Hackread – Cybersecurity News, Data Breaches, AI and More

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
LLVM #3 — Control Flow
Lahari Tenne · 2026-05-06 · via DEV Community

Lahari Tenneti

After all we've done (building a lexer, parser, code-generator, optimiser, and the JIT), we give Kaleidoscope decision-making abilities.

What I built: Commit 5ba5803


What I understood:

If/Then/Else:

1) Lexer:

  • We add three new tokens, namely tok_if, tok_then, and tok_else, and their corresponding checks in gettok() (through if (IdentifierStr == ...))

2) AST:

  • The IfExprAST holds three child expressions — Cond, Then, and Else.
  • It's worth noting that in Kaleidoscope, everything is an expression. There are no statements. This means that if/then/else doesn't result in an action, and instead returns a value.
  • This is to keep the language consistent, as the codegen never has to resolve whether something is an expression or a statement, as only the former is allowed.

3) Parser:

  • The ParseIfExpr() consumes if, parses the condition, expects then, parses the then-expression, expects else, parses the else-expression, and returns an IfExprAST. This is simple recursive descent at play.

4) Codegen:

  • When we generate code for an if-then-else condition, we can't emit instructions linearly anymore. The two branches (then, else) are mutually exclusive, and only one runs.
  • This is where we need proper control-flow: a conditional branch, two separate blocks of code, and a merge point.
  • That looks like:
entry:
   %ifcond = fcmp one double %x, 0.0
   br i1 %ifcond, label %then, label %else

then:
   %calltmp = call double @foo()
   br label %ifcont

else:
  %calltmp1 = call double @bar()
  br label %ifcont

ifcont:
  %iftmp = phi double [ %calltmp, %then ], [ %calltmp1, %else ]
  ret double %iftmp

Enter fullscreen mode Exit fullscreen mode

What I didn't understand (in if/else):

a) Why basic blocks?

  • Code is merely a list of instructions. Why not just emit them line-by-line and tell the CPU to 'jump' when it hits an if?
  • This is because it would be nightmarish for the optimiser to understand the flow in such a scenario. LLVM hence forces us to use 'basic blocks,' which are chunks of code guaranteed to execute from beginning to end, without any jumping in or out.
  • Through blocks, the compiler has a somewhat high-level map (Ex: It knows exactly what happens in a ThenBB, an ElseBB, etc.), which matters for optimisation. If the optimiser knows a block runs as a unit, it can reason about the whole block at once.

b) Why the Phi node?

  • Why couldn't I just assign a value to a variable in both blocks, depending on the condition, and then have the ifcont read the value? For example:
x = 20
ans = ""
if (x % 2 == 0)
   ans = "even"
else
   ans = "odd"

Enter fullscreen mode Exit fullscreen mode

  • This is because LLVM uses SSA. The same variable cannot be changed once defined, thereby making the else branch impossible unless... we use a Phi node.
  • This Phi node sits at the junction where both if and else branches meet. It does no "calculation" and only looks back at the path the CPU took. At runtime, when the CPU jumps from then or else to ifcont, it already carries information about which block it just came from.
  • Phi reads that "came from" information and resolves to the corresponding value.
  • Ex: my value is calltmp if we came from then, or calltmp1 if we came from else.

c) Why do we insert the Phi node manually for if/else, instead of using alloca + mem2reg to handle user variables?

  • This is because we know exactly where the merge happens.
  • When codegen is processing an IfExprAST, it knows the shape of the problem before it even starts. There are two branches. They will meet at exactly one point. That meeting point needs exactly one Phi node with exactly two inputs. It's the same every single time, no matter what. So we just write it directly.
  • Contrarily, alloca + mem2reg is more helpful when code looks like this:
var x = 1;
x = x + 1;

Enter fullscreen mode Exit fullscreen mode

  • Here, x gets assigned in multiple places. And in a more complex program, those assignments could be scattered across loops, nested ifs, all over the place. The compiler can't just look at the AST node for x and know where to put the Phi. It would have to trace every possible path through the entire program to figure out where values of x merge.
  • So instead of doing that hard work ourselves, we use alloca (we give x a slot in memory, let every branch just write to that slot, and then hand it off to mem2reg).
  • mem2reg is a pass that already knows how to trace control flow, find all the merge points, and insert the right Phi nodes automatically.

d) Why do we re-fetch the ThenBB block?

  • Why is there a need for another ThenBB = Builder -> GetInsertBlock() if we already had it?
  • This is to account for recursion. If the code inside our then block is a simple x + y, the pointer is the same. But if it contains another if/else, the nested if will create its own blocks and move the builder's insertion point.
  • In this case, the builder sits at the end of the nested merge block. Hence, we re-fetch it because the Phi node needs to know the final block that ran, and not necessarily the one we started out with.

The for loop:

for i = 1, i < n, 1.0 in
  putchard(42);

Enter fullscreen mode Exit fullscreen mode

  • There are four parts to this: start value, end condition, step value (defaults to 1.0), and the body. We follow the same 'lexer, parser, AST, codegen' template as if/else.
  • The IR generated by the codegen looks like:
entry:
  br label %loop

loop:
  %i = phi double [ 1.0, %entry ], [ %nextvar, %loop ]
  %calltmp = call double @putchard(double 42.0)
  %nextvar = fadd double %i, 1.0
  %loopcond = fcmp one double %booltmp, 0.0
  br i1 %loopcond, label %loop, label %afterloop

afterloop:
  ret double 0.0

Enter fullscreen mode Exit fullscreen mode


`
What I didn't understand (in for loops):

a) Why is there a preheader in the for-loop, before it even starts?

  • Again, for the Phi node. It needs to know which block a value came from. When we enter a loop for the first time, we aren't wntering from within the loop itself. As trivial as it sounds, we enter from outside the loop.
  • The Preheader thus gives the Phi node a clear starting point for the first iteration, and without which the Phi node wouldn't know what our counter's initial value should be.

b) Why return a 0.0?

  • As of now, our for loops return a value of 0.0.
  • This is because we don't have mutable memory yet. The loop variable disappears once the loop ends, causing the body's value to not be accumulated anywhere.
  • This is just a temporary placeholder of sorts.

c) What if the variable we use for the loop already exists? What happens to its value after the loop ends?

  • This is better understood with an example: var i = 99; for i = 1, i < 10, 1.0 in putchard(i);
  • The outer i's value is 99. And the loop has an i value of its own.
  • The problem is that both live in the same symbol table, NamedValues. Whenever the loop writes NamedValues["i"] = Variable, the previous value gets overwritten. Thus, when the loop ends, the pre-loop value is either gone, or replaced by the loop's last value.
  • The answer to this is Variable shadowing. Pretty similar to what we did with Lox's environments. We peek at NamedValues to see that pre-loop value, and save it. cpp Value *OldVal = NamedValues[VarName]; NamedValues[VarName] = Variable; // loop's i takes over

Then we restore:

cpp
if (OldVal)
NamedValues[VarName] = OldVal; // 99 comes back
else
NamedValues.erase(VarName); // nothing was there before, so clean up

  • The inner variable doesn't destroy the outer one and only temporarily steps in front of it. Once the loop exits, the outer scope is exactly as it was. Same principle as Lox's chained environments, just done manually here since we're managing the symbol table ourselves.


What's next: Extending Kaleidoscope with user-defined operators. More control.


Musings:
Hehe, hello again. Twenty thousand different things came up. I hope to be more consistent with this though. I mean, it is sort of good that I keep coming back. Not even as an obligation because I actually enjoy it very much. But I could do better.

Anyhoo, I've been walking quite a bit lately (which I absolutely love). It is among the few things I do to relax. I think excellently when I'm walking. Any problem I feel I'm unable to find a solution to seems to solve itself merely 15-20 minutes into a walk. I feel more optimistic and in charge of life. I also learn to, briefly though it may be, set aside all that goes on in my little world, and just feel like I'm part of something bigger. Almost akin to that mix of awe and ease one feels knowing they're in the audience witnessing something grand. Our world too, can be beautiful and inspire hope if we figure out how to look at it. A walk out there helps.