2016-03-22 9 views
2

Ich schreibe einen Programmiersprachencompiler, um DSLs und C/C++ zu integrieren. Dafür habe ich mich aus verschiedenen Gründen für LLVM entschieden.Datentyp für Bool in LLVM IR

Es gibt ein Hauptprogramm. In diesem Hauptprogramm lade ich Bitcode-Dateien, die von clang kompiliert wurden. Die ladbare Bitcodedatei stellt eine kurze, aber vollständige Programmiersprachenumgebung mit REPL, Parser, Linker und AST dar.

Mein bisheriges Verständnis war, dass boolesche Datentypen in IR als i1 dargestellt werden. Ich habe meinen Code mit O3 optimiert und ich für einen boolean IR-Code folgenden (durch mit llvm-dis aus der erzeugten Bitcode Datei Demontage):

%"class.tl::contrib::toy::ToyREPL" = type <{ %"class.tl::contrib::toy::InitLanguage"*, i8, [7 x i8] }> 

Die Klasse ist ToyREPL und es wird mit einer anderen Klasse InitLanguage. Seltsamerweise scheint der Boolesche Wert von einem i8 und einem Array von i8 dargestellt zu werden. Ich verstehe es nicht wirklich.

Ich habe ein Makefile definiert. Zuerst kompiliere ich die Dateien. Danach verknüpfe ich sie mit einer bc-Datei, optimiere sie und verlinke sie mit anderen libs.

@cd $(BIN)/$(TARGET)/$(2); $(LINK) -o $(1).$(BITCODE_EXT) $(3) 

@cd $(BIN)/$(TARGET)/$(2); $(OPT) -O3 $(1).$(BITCODE_EXT) -o $(1).$(OPT_NAME).$(BITCODE_EXT) $(OPTIMIZER_FLAGS) 

@$(LINK) -o $(BIN)/$(TARGET)/$(2)/$(1).$(BITCODE_EXT) $(BIN)/$(TARGET)/$(2)/$(1).$(OPT_NAME).bc $(LINK_OPTION) $(4) 

Compiler-Flags sind:

-v -g -emit-llvm -I$(BOOST_INC_DIR) -std=c++11 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS 

Optimizer Flags sind -std-link-opts

Link-Flagge -v ist.

Der relevante Teil der Klasse ToyREPL ist hier:

class ToyREPL { 
private: 

    InitLanguage *initLang; 

    bool runs = false; 

Nun meine Frage: Ist meine Annahme falsch Bool sollte i1 zusammengestellt Bitcode werden? Welche Art von Compiler-Switch muss ich berücksichtigen, um nach i1 zu kompilieren? Lass es mich wissen, wenn du denkst, dass mein Build-Prozess in irgendeiner Weise falsch ist. Die Generate-Bitcode-Datei ist lesbar und ich kann das Modul und die Klasse ToyREPL als StructType abrufen.

+0

Ersetzte Anführungszeichen mit Code - Anführungszeichen sind in der Regel am besten, wenn Dinge zitiert werden, die für Menschen gedacht sind, nicht für Computer.;) – Yakk

Antwort

2

Wenn ich Sie richtig verstehe, ist Ihre Frage im Wesentlichen - warum wurde die C++ Klasse

class ToyREPL { 
    bool runs = false; 
    ... 
}; 

Zusammengestellt von Clang in type <{ i8, [7 x i8], ... }>?

Also zunächst einmal, warum Clang i8 über i1 für ein boolean Feld gewählt hat, ist einfach - the smallest C++ type takes one byte of memory, und es sei denn, Sie Bit-Felder verwenden, das gilt auch in structs auf Felder. Siehe auch this related question about why a whole byte is used for booleans. LLVM selbst verwendet i1 für boolesche Werte, aber das liegt daran, dass es ungefähr plattformunabhängig ist - in der Absenkphase können diese wiederum ganze Bytes werden.

Wie für [7 x i8], Padding, um sicherzustellen, dass jedes Objekt dieses Typs 64-Bit ausgerichtet ist und seinen Speicher nicht mit anderen Objekten teilt - sehr vernünftiger Ansatz auf einem 64-Bit-System. Wenn das folgende struct-Feld vorhanden ist, wurde das Padding möglicherweise eingefügt, um sicherzustellen, dass das Feld 64-Bit-ausgerichtet ist.

The Wikipedia article on alignment and padding ist ein nützlicher Ausgangspunkt, wenn Sie mehr wissen möchten.

+0

Das scheint die offensichtliche Antwort zu sein ... aber gibt es keine Ausnahme auf der Seite von LLVM oder wird das meiste davon nur durch die Art und Weise verursacht, wie C++ angegeben wird? – VermillionAzure

+0

Danke. Die Paddings machen Sinn, da ich eine 64-Bit-Maschine habe. Aber das bedeutet, dass ich niemals zwischen einem ganzzahligen Wert und einem booleschen Wert unterscheiden kann, wenn ich den Bitcode zur Hand habe, oder? – repl

+0

@VermillionAzure das kommt alles von Clang, soweit ich weiß, aufgrund der Art, wie C++ angegeben ist und aus Leistungsgründen. Zum Beispiel kann eine andere Sprache 'i1' für boolesche Zeichen verwenden, um Speicherplatz zu sparen - aber dann könnte die Absenkphase funky Dinge tun, um ein' i1' auf einer Maschine zu laden und zu speichern, die nur Byteadressierung hat. – Oak