@@ -828,6 +828,73 @@ Constant *getString(Module &M, StringRef Str) {
828828 return ConstantExpr::getInBoundsGetElementPtr (s->getType (), gv, Idxs);
829829}
830830
831+ void emit_backtrace (llvm::Instruction *inst, llvm::raw_ostream &ss) {
832+ SmallPtrSet<llvm::Instruction *, 8 > visited;
833+ while (true ) {
834+ if (visited.contains (inst))
835+ break ;
836+ visited.insert (inst);
837+
838+ // Print debug info for this instruction
839+ if (auto dbgLoc = inst->getDebugLoc ()) {
840+ auto *loc = dbgLoc.get ();
841+ while (loc) {
842+ if (auto *scope = loc->getScope ()) {
843+ StringRef name = scope->getName ();
844+ // Remove trailing semicolons (Julia-style function name decoration)
845+ while (!name.empty () && name.back () == ' ;' )
846+ name = name.drop_back ();
847+ if (auto *file = scope->getFile ()) {
848+ StringRef dir = file->getDirectory ();
849+ StringRef fn = file->getFilename ();
850+ ss << " in '" << name << " ' at " ;
851+ if (!dir.empty ())
852+ ss << dir << " /" ;
853+ ss << fn << " :" << loc->getLine () << " \n " ;
854+ } else {
855+ ss << " in '" << name << " ' at unknown:" << loc->getLine () << " \n " ;
856+ }
857+ }
858+ loc = loc->getInlinedAt ();
859+ }
860+ }
861+
862+ // Move up the call chain
863+ Function *f = inst->getParent ()->getParent ();
864+
865+ // Collect callers with debug info
866+ SmallVector<CallInst *, 4 > callersWithDbg;
867+ for (auto *U : f->users ()) {
868+ auto *CI = dyn_cast<CallInst>(U);
869+ if (!CI)
870+ continue ;
871+ if (!CI->getDebugLoc ())
872+ continue ;
873+ callersWithDbg.push_back (CI);
874+ }
875+
876+ if (callersWithDbg.empty ())
877+ break ;
878+
879+ // Deduplicate by debug location MDNode
880+ SmallVector<CallInst *, 4 > uniqueCallSites;
881+ SmallPtrSet<const MDNode *, 4 > seenMD;
882+ for (auto *CI : callersWithDbg) {
883+ if (seenMD.insert (CI->getDebugLoc ().getAsMDNode ()).second )
884+ uniqueCallSites.push_back (CI);
885+ }
886+
887+ if (uniqueCallSites.size () > 1 ) {
888+ ss << " (multiple call sites)\n " ;
889+ break ;
890+ } else if (uniqueCallSites.size () == 1 ) {
891+ inst = uniqueCallSites[0 ];
892+ continue ;
893+ }
894+ break ;
895+ }
896+ }
897+
831898void ErrorIfRuntimeInactive (llvm::IRBuilder<> &B, llvm::Value *primal,
832899 llvm::Value *shadow, const char *Message,
833900 llvm::DebugLoc &&loc, llvm::Instruction *orig) {
@@ -892,9 +959,17 @@ void ErrorIfRuntimeInactive(llvm::IRBuilder<> &B, llvm::Value *primal,
892959 EB.CreateRetVoid ();
893960 }
894961
962+ std::string Message2 = Message;
963+ if (!CustomRuntimeInactiveError) {
964+ std::string str;
965+ raw_string_ostream ss (str);
966+ ss << Message << " \n " ;
967+ emit_backtrace (orig, ss);
968+ Message2 = ss.str ();
969+ }
895970 Value *args[] = {B.CreatePointerCast (primal, getInt8PtrTy (M.getContext ())),
896971 B.CreatePointerCast (shadow, getInt8PtrTy (M.getContext ())),
897- getString (M, Message )};
972+ getString (M, Message2 )};
898973 auto call = B.CreateCall (F, args);
899974 call->setDebugLoc (loc);
900975}
@@ -4138,7 +4213,12 @@ llvm::Value *EmitNoDerivativeError(const std::string &message,
41384213 auto &M = *inst.getParent ()->getParent ()->getParent ();
41394214 FunctionType *FT = FunctionType::get (Type::getInt32Ty (M.getContext ()),
41404215 {getInt8PtrTy (M.getContext ())}, false );
4141- auto msg = getString (M, message);
4216+ std::string str;
4217+ raw_string_ostream ss (str);
4218+ ss << message << " \n " ;
4219+ emit_backtrace (&inst, ss);
4220+ auto msg = getString (M, ss.str ());
4221+ ;
41424222 auto PutsF = M.getOrInsertFunction (" puts" , FT);
41434223 Builder2.CreateCall (PutsF, msg);
41444224
@@ -4173,7 +4253,12 @@ bool EmitNoDerivativeError(const std::string &message, Value *todiff,
41734253 auto &M = *context.ip ->GetInsertBlock ()->getParent ()->getParent ();
41744254 FunctionType *FT = FunctionType::get (Type::getInt32Ty (M.getContext ()),
41754255 {getInt8PtrTy (M.getContext ())}, false );
4176- auto msg = getString (M, message);
4256+ std::string str;
4257+ raw_string_ostream ss (str);
4258+ ss << message << " \n " ;
4259+ if (auto inst = dyn_cast<Instruction>(todiff))
4260+ emit_backtrace (inst, ss);
4261+ auto msg = getString (M, ss.str ());
41774262 auto PutsF = M.getOrInsertFunction (" puts" , FT);
41784263 context.ip ->CreateCall (PutsF, msg);
41794264
@@ -4206,7 +4291,11 @@ void EmitNoTypeError(const std::string &message, llvm::Instruction &inst,
42064291 auto &M = *inst.getParent ()->getParent ()->getParent ();
42074292 FunctionType *FT = FunctionType::get (Type::getInt32Ty (M.getContext ()),
42084293 {getInt8PtrTy (M.getContext ())}, false );
4209- auto msg = getString (M, message);
4294+ std::string str;
4295+ raw_string_ostream ss (str);
4296+ ss << message << " \n " ;
4297+ emit_backtrace (&inst, ss);
4298+ auto msg = getString (M, ss.str ());
42104299 auto PutsF = M.getOrInsertFunction (" puts" , FT);
42114300 Builder2.CreateCall (PutsF, msg);
42124301
0 commit comments