leaningtech / cheerp-meta

Cheerp - a C/C++ compiler for Web applications - compiles to WebAssembly and JavaScript
https://labs.leaningtech.com/cheerp
Other
1.02k stars 50 forks source link

With what LLVM version/tag/release is cheerp based ? #150

Closed mingodad closed 1 year ago

mingodad commented 1 year ago

I'm trying to see what cheerp changes over the LLVM project and I'm confused the build of cheerp-latest says it's clang-16:

cheerp-env clang -v
clang version 16.0.0 (https://github.com/leaningtech/cheerp-compiler 582073c5ffe5f822a5b49fb4e984f535e40fc5b5)
Target: cheerp-leaningtech-webbrowser-wasm
Thread model: posix

But when I use kdiff3 tool to see the differences between cheerp-compiler-latest / llvm-project-llvmorg-16.0.0-rc1 / llvm-project-llvmorg-16.0.0 it seems strange because in several places llvm-16.0.0-rc1 and llvm-16.0.0 are equal but cheerp-compiler-latest is different (I mean in places that apparently cheerp doesn't change anything there) like the ones bellow (notice that the differences shown bellow are only examples that I think can be used to discover the base LLVM version and it doesn't seem that cheerp also work for flang).

--- cheerp-compiler/flang/include/flang/Common/enum-set.h
+++ llvm-project-llvmorg-16.0.0-rc1/flang/include/flang/Common/enum-set.h
@@ -207,7 +207,7 @@

   template <typename STREAM>
   STREAM &Dump(
-      STREAM &o, const std::string &EnumToString(enumerationType)) const {
+      STREAM &o, std::string_view EnumToString(enumerationType)) const {
     char sep{'{'};
     IterateOverMembers([&](auto e) {
       o << sep << EnumToString(e);
--- cheerp-compiler/flang/include/flang/Evaluate/expression.h
+++ llvm-project-llvmorg-16.0.0-rc1/flang/include/flang/Evaluate/expression.h
@@ -473,20 +473,20 @@
 public:
   using Result = Type<TypeCategory::Character, KIND>;
   using Base = ArrayConstructorValues<Result>;
-  CLASS_BOILERPLATE(ArrayConstructor)
-  ArrayConstructor(Expr<SubscriptInteger> &&len, Base &&v)
-      : Base{std::move(v)}, length_{std::move(len)} {}
-  template <typename A>
-  explicit ArrayConstructor(const A &prototype)
-      : length_{prototype.LEN().value()} {}
+  DEFAULT_CONSTRUCTORS_AND_ASSIGNMENTS(ArrayConstructor)
+  explicit ArrayConstructor(Base &&values) : Base{std::move(values)} {}
+  template <typename T> explicit ArrayConstructor(const Expr<T> &) {}
+  ArrayConstructor &set_LEN(Expr<SubscriptInteger> &&);
   bool operator==(const ArrayConstructor &) const;
   static constexpr Result result() { return Result{}; }
   static constexpr DynamicType GetType() { return Result::GetType(); }
   llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
-  const Expr<SubscriptInteger> &LEN() const { return length_.value(); }
-
-private:
-  common::CopyableIndirection<Expr<SubscriptInteger>> length_;
+  const Expr<SubscriptInteger> *LEN() const {
+    return length_ ? &length_->value() : nullptr;
+  }
+
+private:
+  std::optional<common::CopyableIndirection<Expr<SubscriptInteger>>> length_;
 };

 template <>
--- cheerp-compiler/flang/lib/Evaluate/characteristics.cpp
+++ llvm-project-llvmorg-16.0.0-rc1/flang/lib/Evaluate/characteristics.cpp
@@ -73,11 +73,10 @@
   return common::visit(
       common::visitors{
           [&](const semantics::ProcEntityDetails &proc) {
-            const semantics::ProcInterface &interface { proc.interface() };
-            if (interface.type()) {
-              return Characterize(*interface.type(), context);
-            } else if (interface.symbol()) {
-              return Characterize(*interface.symbol(), context);
+            if (proc.procInterface()) {
+              return Characterize(*proc.procInterface(), context);
+            } else if (proc.type()) {
+              return Characterize(*proc.type(), context);
             } else {
               return std::optional<TypeAndShape>{};
             }
@@ -506,8 +505,8 @@
               }
               return intrinsic;
             }
-            const semantics::ProcInterface &interface { proc.interface() };
-            if (const semantics::Symbol * interfaceSymbol{interface.symbol()}) {
+            if (const semantics::Symbol *
+                interfaceSymbol{proc.procInterface()}) {
               auto interface {
                 CharacterizeProcedure(*interfaceSymbol, context, seenProcs)
               };
@@ -517,7 +516,7 @@
               return interface;
             } else {
               result.attrs.set(Procedure::Attr::ImplicitInterface);
-              const semantics::DeclTypeSpec *type{interface.type()};
+              const semantics::DeclTypeSpec *type{proc.type()};
               if (symbol.test(semantics::Symbol::Flag::Subroutine)) {
                 // ignore any implicit typing
                 result.attrs.set(Procedure::Attr::Subroutine);
@@ -921,7 +920,7 @@
         if (whyNot) {
           *whyNot = "function results have distinct constant extents";
         }
-      } else if (!ifaceTypeShape->type().IsTkCompatibleWith(
+      } else if (!ifaceTypeShape->type().IsTkLenCompatibleWith(
                      actualTypeShape->type())) {
         if (whyNot) {
           *whyNot = "function results have incompatible types: "s +
@@ -1000,7 +999,7 @@
       auto sep{": "s};
       *whyNot = "incompatible procedure attributes";
       differences.IterateOverMembers([&](Attr x) {
-        *whyNot += sep + EnumToString(x);
+        *whyNot += sep + std::string{EnumToString(x)};
         sep = ", ";
       });
     }
alexp-sssup commented 1 year ago

You can compare against commit f22a573b2b8afaee88001168eeeb70c77f28a03e, that's the latest one in common. We rebase periodically against LLVM to get all the latest improvements, usually around the time we do a new release.