What does badref mean? - llvm

What does that IR line mean
define i32 <badref>() {
for defining a new function and writing it in the file

Typically you get <badref> printed out when the IR is malformed. You should run the verifier pass on your module to see if it can help you find out what the precise problem is.
In this particular case I'm guessing you have created a new unnamed function but have not yet added it to a module - without a module it cannot number the global values, so it cannot name the function.

Related

LLVM linker: weird error message when importing a function

I'm trying to implement a module system in my programming language.
I've read the docs (https://llvm.org/doxygen/classllvm_1_1Linker.html) and the linkModules() function is exactly what I need. When linking two modules I'm getting a weird error message. I don't get what I'm doing wrong.
export.mylang:
export func eoeo(x: i32) -> void {}
import.mylang:
import "#project/eo.mylang";
func main() -> i32 {
return 0;
}
by the way, import.mylang doesn't even call to eoeo() ...
Then I use linkModules() to glue the two modules together:
llvm::Linker::linkModules(*mylang::CompilationUnits[mylang::CompilationUnits.size() - 2]->Module,
std::unique_ptr<llvm::Module>(mylang::CompilationUnits.back()->Module));
this code generates the following LLVM IR (after connecting the two modules):
define void #eoeo(i32 %x) {
entry:
%x1 = alloca i32, align 4
store i32 %x, i32* %x1, align 4
ret void
}
define i32 #main() {
entry:
ret i32 0
}
And in my terminal I see this error message:
Function context does not match Module context!
void (i32)* #eoeo
What does that even mean? Yeah, the two modules do have different contexts, but isn't linkModules() supposed to glue them together into a single large module (regardless of different contexts)? I'm so confused.
(I'm writing this an hour later).
So I've tried to call eoeo() and my source file did compile but I was left with a weird error message:
Call parameter type does not match function signature!
i32 3
i32 call void #eoeo(i32 3)
Function context does not match Module context!
void (i32)* #eoeo
Call parameter type does not match function signature!
i32 3
i32 call void #eoeo(i32 3)
So now I guess types are scoped to an LLVM context?
How can I simply take one module and put it's stuff into another module without worrying about contexts? What's interesting is that I can not define but declare a function in a module (without the body) and then have the body defined in a different module. then I can dump these modules to .ll files and use the llvm-link command line tool to link them (everything works).
The thing is that I really don't want to deal with the file system and use std::system() to interact with LLVM's tools. It does work, but it's tedious to deal with file paths manually.
How can I simply take one module and put it's stuff into another module without worrying about contexts?
The only way to do this is to serialize it down to bitcode out of one context, and then deserialize it into the target context.
Here's what LLVMContext is for. Suppose you're writing a video game and you want to use a scripting engine, a 3d audio subsystem and a graphics system. Each of these libraries uses LLVM under the hood for their own purposes. Instead of having global anything which would cause them to potentially step on each other's data, everything, everything, is scoped to the LLVMContext, keeping each library's data separate. Both Type* and Constant* are stored as members of the LLVMContext. The LLVM module linker assumes that the inputs come from the same context.
You're free to create multiple modules within a single context. These can share Type* and Constant*.
Sometimes people also use contexts for threading, since we have the same problem of making sure two threads don't touch each other's data. If you do that, you then need to serialize to bitcode and deserialize.

How to get loopinfo in Module Pass

I want to get loopinfo in each function by iterating through functions in Module Pass. My code is as follows:
for (auto &F:M) {
if(!F.isDeclaration()){
LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>(F).getLoopInfo();
}
}
However, there is an error, I think my variable Settings should conform to the first function definition, how should I resolve.
clang-12: /llvmtest/llvm/lib/IR/LegacyPassManager.cpp:1645: virtual
std::tuple<llvm::Pass*, bool>
{anonymous}::MPPassManager::getOnTheFlyPass(llvm::Pass*,
llvm::AnalysisID, llvm::Function&): Assertion `FPP && “Unable to find
on the fly pass”’ failed. PLEASE submit a bug report to
https://bugs.llvm.org/ and include the crash backtrace, preprocessed
source, and associated run script.
You can not do this with the legacy pass manager. In the legacy pass manager, every pass could only get info from same-scoped passes -- module from module, function from function, loop from loop, plus one exception allowing function passes to get data from module passes.
With the new pass manager, you'd create a LoopAnalysisManager and add the analysis pass you want and run it. See https://llvm.org/docs/NewPassManager.html#using-analyses .
Note that most of LLVM is presently written to support both pass managers at once. If you do this, you'll need to write your pass differently from most of LLVM's passes, you can't use the types with names like "WrapperPass" that exist to support both legacy and new pass managers.

Lazy evaluation of Lauterbach macro - is it possible?

I'm currently writing some kind of a "skeleton" for tests to be performed using Lauterbach scripts.
In this skeleton I want to have a part in which all test specific definitions shall be done, e.g. functions to set breaks on, variables to be altered etc. This part shall be just near the top of the script file, so that other users do not have to go through the complete script file, changing values here and there.
Some of the variables that'll be used are defined function-local within the C-code to be tested. So, these become available to the Lauterbach script only once the scope of that function has been entered - which is deeply within the skeleton script code.
Is there a way to define a macro for these variables just way before the scope has been entered?
Let's give some example structure:
LOCAL &funcToTest // the function we want to test
LOCAL &varToBeSet // a variable within the function we want to alter
LOCAL &valueToBeSet // the value we want to set &varToBeSet to
... // some more definitions here
&funcToTest=someFunc
&varToBeSet=status
&valueToBeSet=1
... // some test code following here that sets up log files, screen areas
... // start the program to be tested etc.
IF (Register(PC)==ADDRESS.OFFSET(&funcToTest))
(
// OK - we've hit the breakpoint inside the function to test
... // Run to some point where we can set the local variable
Var.Set &varToBeSet=&valueToBeSet
... // Go on with the program and see what happens - this will be logged
)
The problem is that Lauterbach complains at the line &varToBeSet=status
with Symbol not found in this context - which is correct, because it is a local variable.
Looking at the symbols via View->Symbols->SymbolsTreeView (or by giving the command Symbol.List.Tree) I can find the symbol (in this particular case found under the node some_module.some_function.status). Clicking on it gives the information in the TRACE32 status status line \\some_app\some_module\some_func\status with type (auto STATUS), scope local, location stack.
Changing my script to read &varToBeSet=\\some_app\some_module\some_func\status instead of &varToBeSet=status, however, does not help much. In this case Lauterbach complains with no access to that symbol.
Is there a way, I can delay evaluation of the macro to some point where it is actually used instead of having it evaluated when it is defined?
Use quotes:
&varToBeSet="\\some_app\some_module\some_func\status"

Lua: Redirect extern function definitions to a specified table

I have one file "example.lua":
local function manipulate(something)
return string.rep(something, 3) -- repeats the given string
end
function apiFunction(somethingelse)
return manipulate(somethingelse)
end
and another files (main.lua) task is to "load"/"do" it:
loadAPI("example.lua", "externAPI") --< the part i need help with
externAPI.apiFunction("Test") --> should return TestTestTest
the thing that should happen is, that example.lua gets executed just like
dofile("example.lua")
but everything globally "defined" within example.lua (in this case the apiFunction) moves to the new generated global "externAPI" table and the rest (ie. manipulate) is hidden and only available from inside the example.lua file.
I've seen this bahaviour before in the minecraft mod "ComputerCraft" in which there is a function called "os.loadAPI("/somepath/sha-2") and it would define the definitions in the sha-2-chunk in the due to the name specified "sha-2"-table.
I've been searching for this sort of scoping/redirecting stuff for a while but there are no solutions putting the stuff into the new table.
I've been thinking of parsing the _G table after new indexes and move those to the new table but I'm sure there are some lua-magicians out here that know a much cleaner, better working solution to this.
All this is in one C lua_state* , so if there are any solutions adding this loadAPI function in C/C++ and just registrating it at the state this would be fine, too.
I've also looked at "require", but didn't seem to understand whether it does what I need.
Using Lua 5.2.3
Hope i didn't forget anything.
Thanks in advance :)
~InDieTasten
Try this:
function loadAPI(f,g)
_G[g]=setmetatable({},{__index=_G})
loadfile(f,"bt",_G[g])()
end
loadAPI("example.lua", "externAPI")
print(externAPI.apiFunction("Test"))

How to access predefined variables within cfscript?

The following code works:
<cfoutput>#$.currentURL()#</cfoutput>
However, within a function, "$" is not available.
<cfscript>
function myTest() {
return $.currentURL();
}
</cfscript>
Does anyone know what actually is the equivalent of $ within a function?
Likewise, #pluginConfig.getDirectory()# works when used directly in cfoutput. However, within a cfscript function, it reports "unknown variable pluginConfig."
Thank you for advance for guiding me in the right direction.
When writing code outside the Mura Event Scope (like you do with that function), you have to obtain an instance of the Mura Scope ($) yourself. This can be done using the following code:
$ = application.serviceFactory.getBean('$');
Next you'll have to initialise the instance using an event object, a struct with value pairs or a 'siteID':
$.init(event);
$.init(myStruct);
$.init(siteID);
The same counts for the pluginConfig, this you can abtain via the Mura Scope. You'll have to pass the pluginID, moduleID, name or package of the plugin:
$.getPlugin(pluginID);
$.getPlugin(moduleID);
$.getPlugin(name);
$.getPlugin(package);
An other option you have is to pass the Mura Scope and the pluginConfig as arguments to the function. When writing a small plugin, this might be the easier way. But when writting medium or large plugins, it will get a bit messy when you're passing along these objects all the time.
The $ is used as a special framework variable in some CF frameworks (like Mura). You will need to figure out the framework context (if any) your code is executing in