@@ -185,144 +185,58 @@ void CodeGenCPU::Init(const std::string& module_name, LLVMTarget* llvm_target,
185185 InitGlobalContext (dynamic_lookup);
186186}
187187
188- llvm::DISubprogram* CodeGenCPU::CreateDebugFunction (const PrimFunc& f) {
189- #if TVM_LLVM_VERSION >= 50
188+ llvm::DISubprogram* CodeGenCPU::CreateDebugFunction (llvm::StringRef name,
189+ const Array<Type>& param_types,
190+ const Type& return_type) {
191+ #if TVM_LLVM_VERSION < 50
192+ return nullptr ;
193+ #else
194+
190195 llvm::SmallVector<llvm::Metadata*, 4 > paramTys;
191196
192- paramTys.push_back (GetDebugType (f-> ret_type ));
193- for (const auto & param : f-> params ) {
194- paramTys.push_back (GetDebugType (GetType (param) ));
197+ paramTys.push_back (GetDebugType (return_type ));
198+ for (const auto & param_type : param_types ) {
199+ paramTys.push_back (GetDebugType (param_type ));
195200 }
196201
197202 auto * DIFunctionTy = dbg_info_->di_builder_ ->createSubroutineType (
198203 dbg_info_->di_builder_ ->getOrCreateTypeArray (paramTys));
199204
200205 bool local_to_unit = llvm::GlobalVariable::isLocalLinkage (llvm::GlobalValue::InternalLinkage);
201206
202- // TODO(driazati): determine the IRModule name instead of hardcoding 'main.tir'
203207#if TVM_LLVM_VERSION >= 80
204208 auto SPFlags = llvm::DISubprogram::toSPFlags (local_to_unit, /* IsDefinition=*/ true ,
205209 /* IsOptimized=*/ true );
206- auto * DIFunction = dbg_info_->di_builder_ ->createFunction (
207- /* Scope=*/ dbg_info_->file_ , /* Name=*/ " main.tir" , /* LinkageName=*/ " " ,
208- /* File=*/ dbg_info_->file_ , /* LineNo=*/ 0 , /* Ty=*/ DIFunctionTy,
209- /* ScopeLine=*/ 0 , /* Flags=*/ llvm::DINode::FlagZero, /* SPFlags=*/ SPFlags);
210210#else
211+ bool SPFlags = /* IsOptimized=*/ true ;
212+ #endif
213+
211214 auto * DIFunction = dbg_info_->di_builder_ ->createFunction (
212- /* Scope=*/ dbg_info_->file_ , /* Name=*/ " main.tir " , /* LinkageName=*/ " " ,
215+ /* Scope=*/ dbg_info_->file_ , /* Name=*/ name , /* LinkageName=*/ " " ,
213216 /* File=*/ dbg_info_->file_ , /* LineNo=*/ 0 , /* Ty=*/ DIFunctionTy,
214- /* isLocalToUnit=*/ local_to_unit, /* isDefinition=*/ true , /* ScopeLine=*/ 0 ,
215- /* Flags=*/ llvm::DINode::FlagPrototyped, /* isOptimized=*/ true );
216- #endif
217+ /* ScopeLine=*/ 0 , /* Flags=*/ llvm::DINode::FlagPrototyped, /* SPFlags=*/ SPFlags);
218+
217219 return DIFunction;
218- #else
219- return nullptr ;
220+
220221#endif
221222}
222223
223- void CodeGenCPU::AddFunction (const GlobalVar& gvar, const PrimFunc& f) {
224- #if TVM_LLVM_VERSION >= 50
225- di_subprogram_ = CreateDebugFunction (f);
226- #endif
227- EmitDebugLocation (f->span );
228- CodeGenLLVM::AddFunction (gvar, f);
224+ llvm::DISubprogram* CodeGenCPU::CreateDebugFunction (const GlobalVar& gvar, const PrimFunc& func) {
225+ std::string name = func->GetAttr <String>(tvm::attr::kGlobalSymbol ).value_or (gvar->name_hint );
226+ return CreateDebugFunction (name, func->params .Map (GetType), func->ret_type );
227+ }
228+
229+ void CodeGenCPU::AddFunction (const GlobalVar& gvar, const PrimFunc& func) {
230+ di_subprogram_ = CreateDebugFunction (gvar, func);
231+ EmitDebugLocation (func->span );
232+ CodeGenLLVM::AddFunction (gvar, func);
229233 if (f_tvm_register_system_symbol_ != nullptr ) {
230- if (auto global_symbol = f ->GetAttr <String>(tvm::attr::kGlobalSymbol )) {
234+ if (auto global_symbol = func ->GetAttr <String>(tvm::attr::kGlobalSymbol )) {
231235 export_system_symbols_.emplace_back (
232236 std::make_pair (global_symbol.value ().operator std::string (), function_));
233237 }
234238 }
235- AddDebugInformation (f, function_);
236- }
237-
238- // Following Glow |DebugInfo::generateFunctionDebugInfo|, https://git.io/fjadv
239- void CodeGenCPU::AddDebugInformation (PrimFunc f_tir, llvm::Function* f_llvm) {
240- #if TVM_LLVM_VERSION >= 50
241- ICHECK (di_subprogram_);
242- f_llvm->setSubprogram (di_subprogram_);
243- ICHECK_EQ (f_llvm->getSubprogram (), di_subprogram_);
244-
245- IRBuilder builder (&f_llvm->getEntryBlock ());
246- if (!f_llvm->getEntryBlock ().empty ()) {
247- builder.SetInsertPoint (&f_llvm->getEntryBlock ().front ());
248- }
249- llvm::DebugLoc DL;
250- builder.SetCurrentDebugLocation (DL);
251- llvm::LLVMContext* ctx = llvm_target_->GetContext ();
252- for (size_t i = 0 ; i < f_llvm->arg_size (); ++i) {
253- auto * paramAlloca = builder.CreateAlloca (f_llvm->getFunctionType ()->getParamType (i));
254- std::string paramName = " arg" + std::to_string (i + 1 );
255- auto param = dbg_info_->di_builder_ ->createParameterVariable (
256- di_subprogram_, paramName, i + 1 , dbg_info_->file_ , 0 ,
257- GetDebugType (GetType (f_tir->params [i]), f_llvm->getFunctionType ()->getParamType (i)),
258- /* alwaysPreserve=*/ true );
259- auto * store = builder.CreateStore (f_llvm->arg_begin () + i, paramAlloca);
260- auto * di_loc = llvm::DILocation::get (*ctx, 0 , 0 , di_subprogram_);
261- dbg_info_->di_builder_ ->insertDeclare (paramAlloca, param,
262- dbg_info_->di_builder_ ->createExpression (),
263- llvm::DebugLoc (di_loc), store);
264- }
265- dbg_info_->di_builder_ ->finalizeSubprogram (f_llvm->getSubprogram ());
266- auto * scope = f_llvm->getSubprogram ();
267- if (!scope) {
268- return ;
269- }
270-
271- for (auto & BB : *f_llvm) {
272- for (auto & I : BB) {
273- if (I.getDebugLoc ()) {
274- continue ;
275- }
276- auto * di_loc = llvm::DILocation::get (*ctx, 0 , 0 , scope);
277- I.setDebugLoc (llvm::DebugLoc (di_loc));
278- }
279- }
280- #endif
281- }
282-
283- llvm::DIType* CodeGenCPU::GetDebugType (const Type& ty_tir) {
284- return GetDebugType (ty_tir, GetLLVMType (ty_tir));
285- }
286- llvm::DIType* CodeGenCPU::GetDebugType (const Type& ty_tir, llvm::Type* ty_llvm) {
287- if (ty_llvm == t_void_) {
288- return nullptr ;
289-
290- } else if (ty_llvm->isPointerTy ()) {
291- auto * ptr_type = ty_tir.as <PointerTypeNode>();
292- ICHECK (ptr_type != nullptr || GetRuntimeDataType (ty_tir).is_handle ())
293- << " Got LLVM pointer type from non-pointer IR type: " << ty_tir;
294- auto * pointee_type = ptr_type != nullptr ? GetDebugType (ptr_type->element_type ,
295- GetLLVMType (ptr_type->element_type ))
296- : nullptr ;
297- return dbg_info_->di_builder_ ->createPointerType (pointee_type,
298- ty_llvm->getPrimitiveSizeInBits ());
299-
300- } else if (auto * prim_type = ty_tir.as <PrimTypeNode>()) {
301- DataType dtype = prim_type->dtype ;
302- auto dwarf_type = [&]() -> llvm::dwarf::TypeKind {
303- if (dtype.is_bool ()) {
304- return llvm::dwarf::DW_ATE_boolean;
305- } else if (dtype.is_float ()) {
306- return llvm::dwarf::DW_ATE_float;
307- } else if (dtype.is_int ()) {
308- return llvm::dwarf::DW_ATE_signed;
309- } else if (dtype.is_uint ()) {
310- return llvm::dwarf::DW_ATE_unsigned;
311- } else {
312- LOG (FATAL) << " No DWARF representation for TIR type " << dtype;
313- }
314- }();
315-
316- return dbg_info_->di_builder_ ->createBasicType (DLDataType2String (dtype),
317- dtype.bits () * dtype.lanes (), dwarf_type);
318-
319- } else {
320- std::string type_str;
321- llvm::raw_string_ostream rso (type_str);
322- ty_llvm->print (rso);
323- LOG (FATAL) << " Unknown LLVM type:" << rso.str ();
324- }
325- return nullptr ;
239+ AddDebugInformation (function_, func->params .Map (GetType));
326240}
327241
328242void CodeGenCPU::AddMainFunction (const std::string& entry_func_name) {
@@ -570,15 +484,18 @@ void CodeGenCPU::CreateComputeScope(const AttrStmtNode* op) {
570484 std::swap (function_, parent_->function_ );
571485 std::swap (analyzer_, parent_->analyzer_ );
572486 std::swap (var_map_, parent_->var_map_ );
487+ std::swap (di_subprogram_, parent_->di_subprogram_ );
573488 }
574489
575490 void ExitWithScope () {
576491 std::swap (function_, parent_->function_ );
577492 std::swap (analyzer_, parent_->analyzer_ );
578493 std::swap (var_map_, parent_->var_map_ );
494+ std::swap (di_subprogram_, parent_->di_subprogram_ );
579495 }
580496
581497 llvm::Function* function_{nullptr };
498+ llvm::DISubprogram* di_subprogram_{nullptr };
582499 std::unordered_map<const VarNode*, llvm::Value*> var_map_;
583500 std::unique_ptr<arith::Analyzer> analyzer_{std::make_unique<arith::Analyzer>()};
584501 CodeGenCPU* parent_;
@@ -606,6 +523,10 @@ void CodeGenCPU::CreateComputeScope(const AttrStmtNode* op) {
606523 llvm::Function* fcompute = llvm::Function::Create (ftype, llvm::Function::InternalLinkage,
607524 MakeStringRef (value->value ), module_.get ());
608525 SetTargetAttributes (fcompute);
526+ for (auto it = fcompute->arg_begin (); it != fcompute->arg_end (); it++) {
527+ const Var& var = vargs[std::distance (fcompute->arg_begin (), it)];
528+ it->setName (std::string (var->name_hint ));
529+ }
609530
610531 llvm::BasicBlock* compute_call_end = CheckCallSuccess (builder_->CreateCall (fcompute, arg_values));
611532 llvm::LLVMContext* ctx = llvm_target_->GetContext ();
@@ -640,11 +561,15 @@ void CodeGenCPU::CreateComputeScope(const AttrStmtNode* op) {
640561 }
641562
642563 function_ = fcompute;
564+ di_subprogram_ = CreateDebugFunction (MakeStringRef (value->value ), vargs.Map (GetType),
565+ PrimType (DataType::Int (32 )));
643566 auto * compute_entry = llvm::BasicBlock::Create (*ctx, " entry" , function_);
644567 builder_->SetInsertPoint (compute_entry);
645568 this ->VisitStmt (op->body );
646569 builder_->CreateRet (ConstInt32 (0 ));
647570 builder_->SetInsertPoint (compute_call_end);
571+
572+ AddDebugInformation (fcompute, vargs.Map (GetType));
648573}
649574
650575CodeGenLLVM::TypedPointer CodeGenCPU::PackClosureData (const Array<Var>& vfields,
0 commit comments