// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "LLVMReactorDebugInfo.hpp"

#ifdef ENABLE_RR_DEBUG_INFO

#include "Reactor.hpp"
#include "LLVMReactor.hpp"

#include "boost/stacktrace.hpp"

#include "llvm/Demangle/Demangle.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"

#include <cctype>
#include <fstream>
#include <mutex>
#include <regex>
#include <sstream>
#include <string>

#if 0
#define LOG(msg, ...) printf(msg "\n", ##__VA_ARGS__)
#else
#define LOG(msg, ...)
#endif

namespace {

std::pair<llvm::StringRef, llvm::StringRef> splitPath(const char* path)
{
	return llvm::StringRef(path).rsplit('/');
}

// Note: createGDBRegistrationListener() returns a pointer to a singleton.
// Nothing is actually created.
auto jitEventListener = llvm::JITEventListener::createGDBRegistrationListener(); // guarded by jitEventListenerMutex
std::mutex jitEventListenerMutex;

}  // anonymous namespaces

namespace rr {

DebugInfo::DebugInfo(
		llvm::IRBuilder<> *builder,
		llvm::LLVMContext *context,
		llvm::Module *module,
		llvm::Function *function)
	: builder(builder), context(context), module(module), function(function)
{
	using namespace ::llvm;

	auto location = getCallerLocation();

	auto fileAndDir = splitPath(location.function.file.c_str());
	diBuilder.reset(new llvm::DIBuilder(*module));
	diCU = diBuilder->createCompileUnit(
		llvm::dwarf::DW_LANG_C,
		diBuilder->createFile(fileAndDir.first, fileAndDir.second),
		"Reactor",
		0, "", 0);

	registerBasicTypes();

	SmallVector<Metadata *, 8> EltTys;
	auto funcTy = diBuilder->createSubroutineType(diBuilder->getOrCreateTypeArray(EltTys));

	auto file = getOrCreateFile(location.function.file.c_str());
	auto sp = diBuilder->createFunction(
		file,                   // scope
		"ReactorFunction",      // function name
		"ReactorFunction",      // linkage
		file,                   // file
		location.line,          // line
		funcTy,                 // type
		false,                  // internal linkage
		true,                   // definition
		location.line,          // scope line
		DINode::FlagPrototyped, // flags
		false                   // is optimized
	);
	diSubprogram = sp;
	function->setSubprogram(sp);
	diRootLocation = DILocation::get(*context, location.line, 0, sp);
	builder->SetCurrentDebugLocation(diRootLocation);
}

DebugInfo::~DebugInfo() = default;

void DebugInfo::Finalize()
{
	while (diScope.size() > 0)
	{
		emitPending(diScope.back(), builder);
		diScope.pop_back();
	}
	diBuilder->finalize();
}

void DebugInfo::EmitLocation()
{
	auto const& backtrace = getCallerBacktrace();
	syncScope(backtrace);
	builder->SetCurrentDebugLocation(getLocation(backtrace, backtrace.size() - 1));

#ifdef ENABLE_RR_EMIT_PRINT_LOCATION
	static Location lastLocation;
	if (backtrace.size() == 0)
	{
		return;
	}
	Location currLocation = backtrace[backtrace.size() - 1];
	if (currLocation != lastLocation)
	{
		rr::Print("rr> {0} [{1}:{2}]\n", currLocation.function.name.c_str(), currLocation.function.file.c_str(), currLocation.line);
		lastLocation = std::move(currLocation);
	}
#endif // ENABLE_RR_EMIT_PRINT_LOCATION
}

void DebugInfo::Flush()
{
	emitPending(diScope.back(), builder);
}

void DebugInfo::syncScope(Backtrace const& backtrace)
{
	auto shrink = [this](size_t newsize)
	{
		while (diScope.size() > newsize)
		{
			auto &scope = diScope.back();
			LOG("- STACK(%d): di: %p, location: %s:%d",
				int(diScope.size() - 1), scope.di,
				scope.location.function.file.c_str(),
				int(scope.location.line));
			emitPending(scope, builder);
			diScope.pop_back();
		}
	};

	if (backtrace.size() < diScope.size())
	{
		shrink(backtrace.size());
	}

	for (size_t i = 0; i < diScope.size(); i++)
	{
		auto &scope = diScope[i];
		auto const &oldLocation = scope.location;
		auto const &newLocation = backtrace[i];

		if (oldLocation.function != newLocation.function)
		{
			LOG("  STACK(%d): Changed function %s -> %s", int(i),
				oldLocation.function.name.c_str(), newLocation.function.name.c_str());
			shrink(i);
			break;
		}

		if (oldLocation.line > newLocation.line)
		{
			// Create a new di block to shadow all the variables in the loop.
			auto file = getOrCreateFile(newLocation.function.file.c_str());
			auto di = diBuilder->createLexicalBlock(scope.di, file, newLocation.line, 0);
			LOG("  STACK(%d): Jumped backwards %d -> %d. di: %p -> %p", int(i),
				oldLocation.line, newLocation.line, scope.di, di);
			emitPending(scope, builder);
			scope = {newLocation, di};
			shrink(i+1);
			break;
		}

		scope.location = newLocation;
	}

	while (backtrace.size() > diScope.size())
	{
		auto i = diScope.size();
		auto location = backtrace[i];
		auto file = getOrCreateFile(location.function.file.c_str());
		auto funcTy = diBuilder->createSubroutineType(diBuilder->getOrCreateTypeArray({}));

		char buf[1024];
		size_t size = sizeof(buf);
		int status = 0;
		llvm::itaniumDemangle(location.function.name.c_str(), buf, &size, &status);
		auto name = "jit!" + (status == 0 ? std::string(buf) : location.function.name);

		auto func = diBuilder->createFunction(
			file,                           // scope
			name,                           // function name
			"",                             // linkage
			file,                           // file
			location.line,                  // line
			funcTy,                         // type
			false,                          // internal linkage
			true,                           // definition
			location.line,                  // scope line
			llvm::DINode::FlagPrototyped,   // flags
			false                           // is optimized
		);
		diScope.push_back({location, func});
		LOG("+ STACK(%d): di: %p, location: %s:%d", int(i), di,
			location.function.file.c_str(), int(location.line));
	}
}

llvm::DILocation* DebugInfo::getLocation(const Backtrace &backtrace, size_t i)
{
	if (backtrace.size() == 0) { return nullptr; }
	assert(backtrace.size() == diScope.size());
	return llvm::DILocation::get(
		*context,
		backtrace[i].line,
		0,
		diScope[i].di,
		i > 0 ? getLocation(backtrace, i - 1) : diRootLocation
	);
}

void DebugInfo::EmitVariable(Value *variable)
{
	auto const& backtrace = getCallerBacktrace();
	syncScope(backtrace);

	for (int i = backtrace.size() - 1; i >= 0; i--)
	{
		auto const &location = backtrace[i];
		auto tokens = getOrParseFileTokens(location.function.file.c_str());
		auto tokIt = tokens->find(location.line);
		if (tokIt == tokens->end())
		{
			break;
		}
		auto token = tokIt->second;
		auto name = token.identifier;
		if (token.kind == Token::Return)
		{
			// This is a:
			//
			//   return <expr>;
			//
			// Emit this expression as two variables -
			// Once as a synthetic 'return_value' variable at this scope.
			// Again by bubbling the expression value up the callstack as
			// Return Value Optimizations (RVOs) are likely to carry across
			// the value to a local without calling a constructor in
			// statements like:
			//
			//   auto val = foo();
			//
			name = "return_value";
		}

		auto &scope = diScope[i];
		if (scope.pending.location != location)
		{
			emitPending(scope, builder);
		}

		auto value = V(variable);
		auto block = builder->GetInsertBlock();

		auto insertAfter = block->size() > 0 ? &block->back() : nullptr;
		while (insertAfter != nullptr && insertAfter->isTerminator())
		{
			insertAfter = insertAfter->getPrevNode();
		}

		scope.pending = Pending{};
		scope.pending.name = name;
		scope.pending.location = location;
		scope.pending.diLocation = getLocation(backtrace, i);
		scope.pending.value = value;
		scope.pending.block = block;
		scope.pending.insertAfter = insertAfter;
		scope.pending.scope = scope.di;

		if (token.kind == Token::Return)
		{
			// Insert a noop instruction so the debugger can inspect the
			// return value before the function scope closes.
			scope.pending.addNopOnNextLine = true;
		}
		else
		{
			break;
		}
	}
}

void DebugInfo::emitPending(Scope &scope, IRBuilder *builder)
{
	auto const &pending = scope.pending;
	if (pending.value == nullptr)
	{
		return;
	}

	if (!scope.symbols.emplace(pending.name).second)
	{
		return;
	}

	bool isAlloca = llvm::isa<llvm::AllocaInst>(pending.value);

	LOG("  EMIT(%s): di: %p, location: %s:%d, isAlloca: %s", pending.name.c_str(), scope.di,
		pending.location.function.file.c_str(), pending.location.line, isAlloca ? "true" : "false");

	auto value = pending.value;

	IRBuilder::InsertPointGuard guard(*builder);
	if (pending.insertAfter != nullptr)
	{
		builder->SetInsertPoint(pending.block, ++pending.insertAfter->getIterator());
	}
	else
	{
		builder->SetInsertPoint(pending.block);
	}
	builder->SetCurrentDebugLocation(pending.diLocation);

	if (!isAlloca)
	{
		// While insertDbgValueIntrinsic should be enough to declare a
		// variable with no storage, variables of RValues can share the same
		// llvm::Value, and only one can be named. Take for example:
		//
		//   Int a = 42;
		//   RValue<Int> b = a;
		//   RValue<Int> c = b;
		//
		// To handle this, always promote named RValues to an alloca.

		llvm::BasicBlock &entryBlock = function->getEntryBlock();
		auto alloca = new llvm::AllocaInst(value->getType(), 0, pending.name);
		entryBlock.getInstList().push_front(alloca);
		builder->CreateStore(value, alloca);
		value = alloca;
	}

	value->setName(pending.name);

	auto diFile = getOrCreateFile(pending.location.function.file.c_str());
	auto diType = getOrCreateType(value->getType()->getPointerElementType());
	auto diVar = diBuilder->createAutoVariable(scope.di, pending.name, diFile, pending.location.line, diType);

	auto di = diBuilder->insertDeclare(value, diVar, diBuilder->createExpression(), pending.diLocation, pending.block);
	if (pending.insertAfter != nullptr) { di->moveAfter(pending.insertAfter); }

	if (pending.addNopOnNextLine)
	{
		builder->SetCurrentDebugLocation(llvm::DILocation::get(
			*context,
			pending.diLocation->getLine() + 1,
			0,
			pending.diLocation->getScope(),
			pending.diLocation->getInlinedAt()
		));
		Nop();
	}

	scope.pending = Pending{};
}

void DebugInfo::NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L)
{
	std::unique_lock<std::mutex> lock(jitEventListenerMutex);
	jitEventListener->NotifyObjectEmitted(Obj, static_cast<const llvm::RuntimeDyld::LoadedObjectInfo&>(L));
}

void DebugInfo::NotifyFreeingObject(const llvm::object::ObjectFile &Obj)
{
	std::unique_lock<std::mutex> lock(jitEventListenerMutex);
	jitEventListener->NotifyFreeingObject(Obj);
}

void DebugInfo::registerBasicTypes()
{
	using namespace rr;
	using namespace llvm;

	auto vec4 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 4));
	auto vec8 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 8));
	auto vec16 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 16));

	diTypes.emplace(T(Bool::getType()), diBuilder->createBasicType("Bool", sizeof(bool), dwarf::DW_ATE_boolean));
	diTypes.emplace(T(Byte::getType()), diBuilder->createBasicType("Byte", 8, dwarf::DW_ATE_unsigned_char));
	diTypes.emplace(T(SByte::getType()), diBuilder->createBasicType("SByte", 8, dwarf::DW_ATE_signed_char));
	diTypes.emplace(T(Short::getType()), diBuilder->createBasicType("Short", 16, dwarf::DW_ATE_signed));
	diTypes.emplace(T(UShort::getType()), diBuilder->createBasicType("UShort", 16, dwarf::DW_ATE_unsigned));
	diTypes.emplace(T(Int::getType()), diBuilder->createBasicType("Int", 32, dwarf::DW_ATE_signed));
	diTypes.emplace(T(UInt::getType()), diBuilder->createBasicType("UInt", 32, dwarf::DW_ATE_unsigned));
	diTypes.emplace(T(Long::getType()), diBuilder->createBasicType("Long", 64, dwarf::DW_ATE_signed));
	diTypes.emplace(T(Half::getType()), diBuilder->createBasicType("Half", 16, dwarf::DW_ATE_float));
	diTypes.emplace(T(Float::getType()), diBuilder->createBasicType("Float", 32, dwarf::DW_ATE_float));

	diTypes.emplace(T(Byte4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
	diTypes.emplace(T(SByte4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
	diTypes.emplace(T(Byte8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
	diTypes.emplace(T(SByte8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
	diTypes.emplace(T(Byte16::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
	diTypes.emplace(T(SByte16::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
	diTypes.emplace(T(Short2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
	diTypes.emplace(T(UShort2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
	diTypes.emplace(T(Short4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
	diTypes.emplace(T(UShort4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
	diTypes.emplace(T(Short8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
	diTypes.emplace(T(UShort8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
	diTypes.emplace(T(Int2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Int::getType())], {vec4}));
	diTypes.emplace(T(UInt2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UInt::getType())], {vec4}));
	diTypes.emplace(T(Int4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Int::getType())], {vec4}));
	diTypes.emplace(T(UInt4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UInt::getType())], {vec4}));
	diTypes.emplace(T(Float2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Float::getType())], {vec4}));
	diTypes.emplace(T(Float4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Float::getType())], {vec4}));
}

DebugInfo::Location DebugInfo::getCallerLocation() const
{
	return getCallerBacktrace(1)[0];
}

DebugInfo::Backtrace DebugInfo::getCallerBacktrace(size_t limit /* = 0 */) const
{
	auto shouldSkipFile = [](llvm::StringRef fileSR) {
			return fileSR.empty() ||
				fileSR.endswith_lower("ReactorDebugInfo.cpp") ||
				fileSR.endswith_lower("Reactor.cpp") ||
				fileSR.endswith_lower("Reactor.hpp") ||
				fileSR.endswith_lower("stacktrace.hpp");
	};

	std::vector<DebugInfo::Location> locations;

	// Note that bs::stacktrace() effectively returns a vector of addresses; bs::frame construction is where
	// the heavy lifting is done: resolving the function name, file and line number.
	namespace bs = boost::stacktrace;
	for (bs::frame frame : bs::stacktrace())
	{
		if (shouldSkipFile(frame.source_file()))
		{
			continue;
		}

		DebugInfo::Location location;
		location.function.file = frame.source_file();
		location.function.name = frame.name();
		location.line = frame.source_line();
		locations.push_back(location);

		if (limit > 0 && locations.size() >= limit)
		{
			break;
		}
	}

	std::reverse(locations.begin(), locations.end());

	return locations;
}

llvm::DIType *DebugInfo::getOrCreateType(llvm::Type* type)
{
	auto it = diTypes.find(type);
	if (it != diTypes.end()) { return it->second; }

	if(type->isPointerTy())
	{
		auto dbgTy = diBuilder->createPointerType(
			getOrCreateType(type->getPointerElementType()),
			sizeof(void*)*8, alignof(void*)*8);
		diTypes.emplace(type, dbgTy);
		return dbgTy;
	}
	llvm::errs() << "Unimplemented debug type: " << type << "\n";
	assert(false);
	return nullptr;
}

llvm::DIFile *DebugInfo::getOrCreateFile(const char* path)
{
	auto it = diFiles.find(path);
	if (it != diFiles.end()) { return it->second; }
	auto dirAndName = splitPath(path);
	auto file = diBuilder->createFile(dirAndName.second, dirAndName.first);
	diFiles.emplace(path, file);
	return file;
}

DebugInfo::LineTokens const *DebugInfo::getOrParseFileTokens(const char* path)
{
	static std::regex reLocalDecl(
		"^" // line start
		"\\s*" // initial whitespace
		"(?:For\\s*\\(\\s*)?" // optional 'For ('
		"((?:\\w+(?:<[^>]+>)?)(?:::\\w+(?:<[^>]+>)?)*)" // type (match group 1)
		"\\s+" // whitespace between type and name
		"(\\w+)" // identifier (match group 2)
		"\\s*" // whitespace after identifier
		"(\\[.*\\])?"); // optional array suffix (match group 3)

	auto it = fileTokens.find(path);
	if (it != fileTokens.end())
	{
		return it->second.get();
	}

	auto tokens = std::unique_ptr<LineTokens>(new LineTokens());

	std::ifstream file(path);
	std::string line;
	int lineCount = 0;
	while (std::getline(file, line))
	{
		lineCount++;
		std::smatch match;
		if (std::regex_search(line, match, reLocalDecl) && match.size() > 3)
		{
			bool isArray = match.str(3) != "";
			if (!isArray) // Cannot deal with C-arrays of values.
			{
				if (match.str(1) == "return")
				{
					(*tokens)[lineCount] = Token{Token::Return};
				}
				else
				{
					(*tokens)[lineCount] = Token{Token::Identifier, match.str(2)};
				}
			}
		}
	}

	auto out = tokens.get();
	fileTokens.emplace(path, std::move(tokens));
	return out;
}

}  // namespace rr

#endif // ENABLE_RR_DEBUG_INFO
