[codegen][debug info] debug info generation do not touch llvm builder in the most cases.

This commit is contained in:
Vasily Levchenko
2018-01-12 14:19:49 +03:00
committed by Vasily Levchenko
parent e64c2f5990
commit 56d1881f18
4 changed files with 42 additions and 35 deletions
@@ -77,6 +77,11 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
} }
return typeInfoValue(descriptorForTypeInfo) return typeInfoValue(descriptorForTypeInfo)
} }
fun generateLocationInfo(locationInfo: LocationInfo): DILocationRef? {
return LLVMCreateLocation(LLVMGetModuleContext(context.llvmModule), locationInfo.line, locationInfo.line, locationInfo.scope)
}
} }
internal sealed class ExceptionHandler { internal sealed class ExceptionHandler {
@@ -507,11 +512,9 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
internal fun debugLocation(locationInfo: LocationInfo): DILocationRef? { internal fun debugLocation(locationInfo: LocationInfo): DILocationRef? {
if (!context.shouldContainDebugInfo()) return null if (!context.shouldContainDebugInfo()) return null
update(currentBlock, locationInfo) update(currentBlock, locationInfo)
return LLVMBuilderSetDebugLocation( val debugLocation = codegen.generateLocationInfo(locationInfo)
builder, currentPositionHolder.setBuilderDebugLocation(debugLocation)
locationInfo.line, return debugLocation
locationInfo.column,
locationInfo.scope)
} }
fun indirectBr(address: LLVMValueRef, destinations: Collection<LLVMBasicBlockRef>): LLVMValueRef? { fun indirectBr(address: LLVMValueRef, destinations: Collection<LLVMBasicBlockRef>): LLVMValueRef? {
@@ -624,8 +627,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
fun resetDebugLocation() { fun resetDebugLocation() {
if (!context.shouldContainDebugInfo()) return if (!context.shouldContainDebugInfo()) return
if (!currentPositionHolder.isAfterTerminator) currentPositionHolder.resetBuilderDebugLocation()
LLVMBuilderResetDebugLocation(builder)
} }
private fun position() = basicBlockToLastLocation[currentBlock] private fun position() = basicBlockToLastLocation[currentBlock]
@@ -791,7 +793,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
fun positionAtEnd(block: LLVMBasicBlockRef) { fun positionAtEnd(block: LLVMBasicBlockRef) {
LLVMPositionBuilderAtEnd(builder, block) LLVMPositionBuilderAtEnd(builder, block)
basicBlockToLastLocation[block]?.let(this@PositionHolder::debugLocation) basicBlockToLastLocation[block]?.let{ debugLocation(it) }
val lastInstr = LLVMGetLastInstruction(block) val lastInstr = LLVMGetLastInstruction(block)
isAfterTerminator = lastInstr != null && (LLVMIsATerminatorInst(lastInstr) != null) isAfterTerminator = lastInstr != null && (LLVMIsATerminatorInst(lastInstr) != null)
} }
@@ -800,19 +802,15 @@ internal class FunctionGenerationContext(val function: LLVMValueRef,
LLVMDisposeBuilder(builder) LLVMDisposeBuilder(builder)
} }
fun debugLocation(locationInfo: LocationInfo): DILocationRef? { fun resetBuilderDebugLocation() {
if (!context.shouldContainDebugInfo()) return null
return LLVMBuilderSetDebugLocation(
builder,
locationInfo.line,
locationInfo.column,
locationInfo.scope)
}
fun resetDebugLocation() {
if (!context.shouldContainDebugInfo()) return if (!context.shouldContainDebugInfo()) return
LLVMBuilderResetDebugLocation(builder) LLVMBuilderResetDebugLocation(builder)
} }
fun setBuilderDebugLocation(debugLocation: DILocationRef?) {
if (!context.shouldContainDebugInfo()) return
LLVMBuilderSetDebugLocation(builder, debugLocation)
}
} }
private var currentPositionHolder: PositionHolder = PositionHolder() private var currentPositionHolder: PositionHolder = PositionHolder()
@@ -683,7 +683,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun evaluateExpression(value: IrExpression): LLVMValueRef { private fun evaluateExpression(value: IrExpression): LLVMValueRef {
debugLocation(value) updateBuilderDebugLocation(value)
when (value) { when (value) {
is IrTypeOperatorCall -> return evaluateTypeOperator (value) is IrTypeOperatorCall -> return evaluateTypeOperator (value)
is IrCall -> return evaluateCall (value) is IrCall -> return evaluateCall (value)
@@ -1101,12 +1101,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun debugInfoIfNeeded(function: IrFunction?, element: IrElement): VariableDebugLocation? { private fun debugInfoIfNeeded(function: IrFunction?, element: IrElement): VariableDebugLocation? {
if (function == null || !context.shouldContainDebugInfo()) return null if (function == null || element.startLocation == null || !context.shouldContainDebugInfo()) return null
val functionScope = function.scope() val functionScope = function.scope()
if (functionScope == null || !element.needDebugInfo(context)) return null if (functionScope == null || !element.needDebugInfo(context)) return null
val location = debugLocation(element) val locationInfo = element.startLocation!!
val location = codegen.generateLocationInfo(locationInfo)
val file = (currentCodeContext.fileScope() as FileScope).file.file() val file = (currentCodeContext.fileScope() as FileScope).file.file()
val line = element.startLine()
return when (element) { return when (element) {
is IrVariable -> debugInfoLocalVariableLocation( is IrVariable -> debugInfoLocalVariableLocation(
builder = context.debugInfo.builder, builder = context.debugInfo.builder,
@@ -1114,7 +1114,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
diType = element.descriptor.type.diType(context, codegen.llvmTargetData), diType = element.descriptor.type.diType(context, codegen.llvmTargetData),
name = element.descriptor.name, name = element.descriptor.name,
file = file, file = file,
line = line, line = locationInfo.line,
location = location) location = location)
is IrValueParameter -> debugInfoParameterLocation( is IrValueParameter -> debugInfoParameterLocation(
builder = context.debugInfo.builder, builder = context.debugInfo.builder,
@@ -1123,7 +1123,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
name = element.descriptor.name, name = element.descriptor.name,
argNo = (element.descriptor as? ValueParameterDescriptor)?.index ?: 0, argNo = (element.descriptor as? ValueParameterDescriptor)?.index ?: 0,
file = file, file = file,
line = line, line = locationInfo.line,
location = location) location = location)
else -> throw Error("Unsupported element type: ${ir2string(element)}") else -> throw Error("Unsupported element type: ${ir2string(element)}")
} }
@@ -1616,7 +1616,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
compileTimeEvaluate(value, args)?.let { return it } compileTimeEvaluate(value, args)?.let { return it }
debugLocation(value) updateBuilderDebugLocation(value)
when { when {
value is IrDelegatingConstructorCall -> value is IrDelegatingConstructorCall ->
return delegatingConstructorCall(value.descriptor, args) return delegatingConstructorCall(value.descriptor, args)
@@ -1630,7 +1630,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
private fun file() = (currentCodeContext.fileScope() as FileScope).file private fun file() = (currentCodeContext.fileScope() as FileScope).file
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private fun debugLocation(element: IrElement?):DILocationRef? { private fun updateBuilderDebugLocation(element: IrElement?):DILocationRef? {
if (!context.shouldContainDebugInfo() || element == null) return null if (!context.shouldContainDebugInfo() || element == null) return null
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return element.startLocation?.let{functionGenerationContext.debugLocation(it)} return element.startLocation?.let{functionGenerationContext.debugLocation(it)}
@@ -2429,6 +2429,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
} }
} }
internal data class LocationInfo(val scope:DIScopeOpaqueRef?, val line:Int, val column:Int) internal data class LocationInfo(val scope:DIScopeOpaqueRef?,
val line:Int,
private fun IrFunction.hasNotReceiver() = this.extensionReceiverParameter == null && this.dispatchReceiverParameter == null val column:Int)
+12 -5
View File
@@ -241,15 +241,22 @@ void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariab
llvm::unwrap(bb)); llvm::unwrap(bb));
} }
DILocationRef LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, unsigned line, DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line,
unsigned col, DIScopeOpaqueRef scope) { unsigned col, DIScopeOpaqueRef scope) {
auto sp = llvm::unwrap(scope); auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), nullptr);
auto llvmBuilder = llvm::unwrap(builder);
auto location = llvm::DILocation::get(llvmBuilder->getContext(), line, col, sp, nullptr);
llvmBuilder->SetCurrentDebugLocation(location);
return llvm::wrap(location); return llvm::wrap(location);
} }
DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line,
unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocationInlinedAt) {
auto location = llvm::DILocation::get(*llvm::unwrap(contextRef), line, col, llvm::unwrap(scope), llvm::unwrap(refLocationInlinedAt));
return llvm::wrap(location);
}
void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation) {
llvm::unwrap(builder)->SetCurrentDebugLocation(llvm::unwrap(refLocation));
}
void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder) { void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder) {
llvm::unwrap(builder)->SetCurrentDebugLocation(nullptr); llvm::unwrap(builder)->SetCurrentDebugLocation(nullptr);
} }
+3 -1
View File
@@ -99,7 +99,9 @@ DILocalVariableRef DICreateParameterVariable(DIBuilderRef builder, DIScopeOpaque
void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount); void DIInsertDeclaration(DIBuilderRef builder, LLVMValueRef value, DILocalVariableRef localVariable, DILocationRef location, LLVMBasicBlockRef bb, int64_t *expr, uint64_t exprCount);
DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder); DIExpressionRef DICreateEmptyExpression(DIBuilderRef builder);
void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp); void DIFunctionAddSubprogram(LLVMValueRef fn, DISubprogramRef sp);
DILocationRef LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, unsigned line, unsigned col, DIScopeOpaqueRef scope); DILocationRef LLVMCreateLocation(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope);
DILocationRef LLVMCreateLocationInlinedAt(LLVMContextRef contextRef, unsigned line, unsigned col, DIScopeOpaqueRef scope, DILocationRef refLocation);
void LLVMBuilderSetDebugLocation(LLVMBuilderRef builder, DILocationRef refLocation);
void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder); void LLVMBuilderResetDebugLocation(LLVMBuilderRef builder);
const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder); const char* LLVMBuilderGetCurrentBbName(LLVMBuilderRef builder);
const char *DIGetSubprogramLinkName(DISubprogramRef sp); const char *DIGetSubprogramLinkName(DISubprogramRef sp);