@@ -36,7 +36,15 @@ import SIL
3636///
3737let tempRValueElimination = FunctionPass ( name: " temp-rvalue-elimination " ) {
3838 ( function: Function , context: FunctionPassContext ) in
39+ removeTempRValues ( in: function, keepDebugInfo: false , context)
40+ }
3941
42+ let mandatoryTempRValueElimination = FunctionPass ( name: " mandatory-temp-rvalue-elimination " ) {
43+ ( function: Function , context: FunctionPassContext ) in
44+ removeTempRValues ( in: function, keepDebugInfo: true , context)
45+ }
46+
47+ private func removeTempRValues( in function: Function , keepDebugInfo: Bool , _ context: FunctionPassContext ) {
4048 for inst in function. instructions {
4149 switch inst {
4250 case let copy as CopyAddrInst :
@@ -45,12 +53,12 @@ let tempRValueElimination = FunctionPass(name: "temp-rvalue-elimination") {
4553 // copied the `alloc_stack` back to the source location.
4654 context. erase ( instruction: copy)
4755 } else {
48- tryEliminate ( copy: copy, context)
56+ tryEliminate ( copy: copy, keepDebugInfo : keepDebugInfo , context)
4957 }
5058 case let store as StoreInst :
5159 // Also handle `load`-`store` pairs which are basically the same thing as a `copy_addr`.
5260 if let load = store. source as? LoadInst , load. uses. isSingleUse, load. parentBlock == store. parentBlock {
53- tryEliminate ( copy: store, context)
61+ tryEliminate ( copy: store, keepDebugInfo : keepDebugInfo , context)
5462 }
5563 default :
5664 break
@@ -82,9 +90,10 @@ extension StoreInst: CopyLikeInstruction {
8290 private var load : LoadInst { source as! LoadInst }
8391}
8492
85- private func tryEliminate( copy: CopyLikeInstruction , _ context: FunctionPassContext ) {
93+ private func tryEliminate( copy: CopyLikeInstruction , keepDebugInfo : Bool , _ context: FunctionPassContext ) {
8694
87- guard let ( allocStack, lastUseOfAllocStack) = getRemovableAllocStackDestination ( of: copy, context) else {
95+ guard let ( allocStack, lastUseOfAllocStack) =
96+ getRemovableAllocStackDestination ( of: copy, keepDebugInfo: keepDebugInfo, context) else {
8897 return
8998 }
9099
@@ -127,6 +136,9 @@ private func tryEliminate(copy: CopyLikeInstruction, _ context: FunctionPassCont
127136 }
128137 }
129138 context. erase ( instruction: allocStack)
139+ if keepDebugInfo {
140+ Builder ( before: copy, context) . createDebugStep ( )
141+ }
130142 context. erase ( instructionIncludingAllUsers: copy. loadingInstruction)
131143}
132144
@@ -138,18 +150,24 @@ private func tryEliminate(copy: CopyLikeInstruction, _ context: FunctionPassCont
138150/// %lastUseOfAllocStack = load %allocStack
139151/// ```
140152private func getRemovableAllocStackDestination(
141- of copy: CopyLikeInstruction , _ context: FunctionPassContext
153+ of copy: CopyLikeInstruction , keepDebugInfo : Bool , _ context: FunctionPassContext
142154) -> ( allocStack: AllocStackInst , lastUseOfAllocStack: Instruction ) ? {
143155 guard copy. isInitializationOfDestination,
144156 let allocStack = copy. destinationAddress as? AllocStackInst
145157 else {
146158 return nil
147159 }
148160
149- // If the `allocStack` is lexical we can eliminate it if the source of the copy is lexical and
150- // it is live for longer than the `allocStack`.
151- if allocStack. isLexical && !copy. sourceAddress. accessBase. storageIsLexical {
152- return nil
161+ if keepDebugInfo {
162+ if allocStack. isFromVarDecl || allocStack. isLexical {
163+ return nil
164+ }
165+ } else {
166+ // If the `allocStack` is lexical we can eliminate it if the source of the copy is lexical and
167+ // it is live for longer than the `allocStack`.
168+ if allocStack. isLexical && !copy. sourceAddress. accessBase. storageIsLexical {
169+ return nil
170+ }
153171 }
154172
155173 var allocStackUses = UseCollector ( copy: copy, context)
0 commit comments