MCPcopy
hub / github.com/tinygo-org/tinygo / SplitBasicBlock

Function SplitBasicBlock

compiler/llvmutil/llvm.go:111–178  ·  view source on GitHub ↗

SplitBasicBlock splits a LLVM basic block into two parts. All instructions after afterInst are moved into a new basic block (created right after the current one) with the given name.

(builder llvm.Builder, afterInst llvm.Value, insertAfter llvm.BasicBlock, name string)

Source from the content-addressed store, hash-verified

109// after afterInst are moved into a new basic block (created right after the
110// current one) with the given name.
111func SplitBasicBlock(builder llvm.Builder, afterInst llvm.Value, insertAfter llvm.BasicBlock, name string) llvm.BasicBlock {
112 oldBlock := afterInst.InstructionParent()
113 newBlock := afterInst.Type().Context().InsertBasicBlock(insertAfter, name)
114 var nextInstructions []llvm.Value // values to move
115
116 // Collect to-be-moved instructions.
117 inst := afterInst
118 for {
119 inst = llvm.NextInstruction(inst)
120 if inst.IsNil() {
121 break
122 }
123 nextInstructions = append(nextInstructions, inst)
124 }
125
126 // Move instructions.
127 builder.SetInsertPointAtEnd(newBlock)
128 for _, inst := range nextInstructions {
129 inst.RemoveFromParentAsInstruction()
130 builder.Insert(inst)
131 }
132
133 // Find PHI nodes to update.
134 var phiNodes []llvm.Value // PHI nodes to update
135 for bb := insertAfter.Parent().FirstBasicBlock(); !bb.IsNil(); bb = llvm.NextBasicBlock(bb) {
136 for inst := bb.FirstInstruction(); !inst.IsNil(); inst = llvm.NextInstruction(inst) {
137 if inst.IsAPHINode().IsNil() {
138 continue
139 }
140 needsUpdate := false
141 incomingCount := inst.IncomingCount()
142 for i := 0; i < incomingCount; i++ {
143 if inst.IncomingBlock(i) == oldBlock {
144 needsUpdate = true
145 break
146 }
147 }
148 if !needsUpdate {
149 // PHI node has no incoming edge from the old block.
150 continue
151 }
152 phiNodes = append(phiNodes, inst)
153 }
154 }
155
156 // Update PHI nodes.
157 for _, phi := range phiNodes {
158 builder.SetInsertPointBefore(phi)
159 newPhi := builder.CreatePHI(phi.Type(), "")
160 incomingCount := phi.IncomingCount()
161 incomingVals := make([]llvm.Value, incomingCount)
162 incomingBlocks := make([]llvm.BasicBlock, incomingCount)
163 for i := 0; i < incomingCount; i++ {
164 value := phi.IncomingValue(i)
165 block := phi.IncomingBlock(i)
166 if block == oldBlock {
167 block = newBlock
168 }

Callers

nothing calls this directly

Calls 3

IsNilMethod · 0.80
ContextMethod · 0.65
TypeMethod · 0.45

Tested by

no test coverage detected