Skip to content

Commit d85d0db

Browse files
committed
added new tests, fixed some mappings
1 parent 333edb5 commit d85d0db

File tree

6 files changed

+562
-12
lines changed

6 files changed

+562
-12
lines changed

xcfa-mapper/src/Mapper.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ std::string Mapper::mapTypeToC(mlir::Type t) const {
340340

341341
// Check for CIR bool type
342342
if (typeStr.find("!cir.bool") != std::string::npos) {
343-
return "int"; // C89 compatible, or "bool" for C99+
343+
return "_Bool"; // Emit C99 _Bool for true boolean values
344344
}
345345

346346
// Check for CIR integer types with size and signedness
@@ -425,7 +425,7 @@ std::string Mapper::mapTypeToC(mlir::Type t) const {
425425
} else if (elementTypeStr.find("!cir.double") != std::string::npos) {
426426
ctype = "double";
427427
} else if (elementTypeStr.find("!cir.bool") != std::string::npos) {
428-
ctype = "int";
428+
ctype = "_Bool";
429429
}
430430
return ctype + "[" + sizeStr + "]";
431431
}
@@ -629,6 +629,27 @@ bool Mapper::mapModule(ModuleOp module, std::ostream &out) {
629629
// collisions when demangling.
630630
prepareFunctionNames(module);
631631

632+
// Discover union record names from the textual IR so aliases (!rec_*)
633+
// that denote unions can be recognized without heuristics.
634+
std::set<std::string> unionRecordNames;
635+
{
636+
std::string irText;
637+
llvm::raw_string_ostream rso(irText);
638+
module.print(rso);
639+
rso.flush();
640+
const std::string needle = "!cir.record<union \"";
641+
std::size_t pos = 0;
642+
while ((pos = irText.find(needle, pos)) != std::string::npos) {
643+
pos += needle.size();
644+
auto end = irText.find("\"", pos);
645+
if (end == std::string::npos) break;
646+
std::string name = irText.substr(pos, end - pos);
647+
std::replace(name.begin(), name.end(), '.', '_');
648+
unionRecordNames.insert(name);
649+
pos = end + 1;
650+
}
651+
}
652+
632653
// Auto-parse struct definitions by scanning member accesses.
633654
struct FieldInfo {
634655
std::string name; // field name
@@ -801,10 +822,7 @@ bool Mapper::mapModule(ModuleOp module, std::ostream &out) {
801822
}
802823
info.name = fname;
803824

804-
// Heuristic: if we see a field named 'value' on a record, it's likely a union
805-
if (fname == "value") {
806-
isUnionContainer[structName] = true;
807-
}
825+
// Note: union detection is driven by IR-declared unions, not field names.
808826

809827
// Avoid duplicate entries for the same field name
810828
auto &vec = structFields[structName];
@@ -817,6 +835,14 @@ bool Mapper::mapModule(ModuleOp module, std::ostream &out) {
817835
// Kick off collection for top-level operations
818836
for (auto &op : module.getOps()) collectFromOp(op);
819837

838+
// Mark union containers based on discovered union record names.
839+
for (auto &kv : structFields) {
840+
const auto &recName = kv.first;
841+
if (unionRecordNames.count(recName)) {
842+
isUnionContainer[recName] = true;
843+
}
844+
}
845+
820846
// Order structs to satisfy dependencies: if a struct references another
821847
// struct in its fields, emit the dependency first. Simple fixed-point topo.
822848
auto getDeps = [&](const std::string &sname){

xcfa-mapper/src/handlers/Handlers.cpp

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,19 @@ bool handleUnaryOp(cir::UnaryOp op, Mapper &m, std::ostream &out) {
600600
case cir::UnaryOpKind::Dec: opStr = "--"; opFound = true; isPrefix = true; break;
601601
case cir::UnaryOpKind::Plus: opStr = "+"; opFound = true; isPrefix = true; break;
602602
case cir::UnaryOpKind::Minus: opStr = "-"; opFound = true; isPrefix = true; break;
603-
case cir::UnaryOpKind::Not: opStr = "!"; opFound = true; isPrefix = true; break;
603+
case cir::UnaryOpKind::Not: {
604+
// CIR 'not' may represent logical not when applied to !cir.bool,
605+
// and bitwise complement otherwise. Inspect operand type.
606+
std::string ty;
607+
if (o->getNumOperands() > 0) {
608+
llvm::SmallString<64> tbuf; llvm::raw_svector_ostream tos(tbuf);
609+
o->getOperand(0).getType().print(tos);
610+
ty = tos.str().str();
611+
}
612+
if (ty.find("!cir.bool") != std::string::npos) opStr = "!";
613+
else opStr = "~";
614+
opFound = true; isPrefix = true; break;
615+
}
604616
default: opFound = false; break;
605617
}
606618
}
@@ -640,11 +652,22 @@ bool handleShiftOp(cir::ShiftOp op, Mapper &m, std::ostream &out) {
640652
std::string l = m.getOrCreateName(lhs);
641653
std::string r = m.getOrCreateName(rhs);
642654

643-
// ShiftOp doesn't have a kind attribute in the current CIR - it uses
644-
// the 'is_left_shift' boolean attribute instead
645-
std::string opStr = "<<"; // default to left shift
646-
if (auto isLeftAttr = o->getAttrOfType<mlir::BoolAttr>("is_left_shift")) {
647-
opStr = isLeftAttr.getValue() ? "<<" : ">>";
655+
// Determine direction from textual form (left/right) to avoid relying on
656+
// generated enum types across CIR versions.
657+
std::string opStr = "<<"; // default to left
658+
{
659+
llvm::SmallString<128> sbuf;
660+
llvm::raw_svector_ostream sos(sbuf);
661+
o->print(sos);
662+
std::string os = sos.str().str();
663+
if (os.find("shift(right,") != std::string::npos) opStr = ">>";
664+
else if (os.find("shift(left,") != std::string::npos) opStr = "<<";
665+
else {
666+
// Fallback: some older dumps may encode a boolean direction
667+
if (auto isLeftAttr = o->getAttrOfType<mlir::BoolAttr>("is_left_shift")) {
668+
opStr = isLeftAttr.getValue() ? "<<" : ">>";
669+
}
670+
}
648671
}
649672

650673
std::string tmp = m.freshName("s");
@@ -947,6 +970,15 @@ bool handleGetGlobal(cir::GetGlobalOp op, Mapper &m, std::ostream &out) {
947970
// Sanitize the global name to be a valid C identifier
948971
globalName = Mapper::sanitizeIdentifier(globalName);
949972

973+
// If the result of get_global isn't used, don't emit a temporary.
974+
if (o->getNumResults() > 0) {
975+
mlir::Value res = o->getResult(0);
976+
if (res.use_empty()) {
977+
// No side effects, safe to elide.
978+
return true;
979+
}
980+
}
981+
950982
std::string tmp = m.freshName("g");
951983
std::string ctype = "int*";
952984
if (o->getNumResults() > 0) ctype = m.mapTypeToC(o->getResult(0).getType());

0 commit comments

Comments
 (0)