Compare commits
10 Commits
7c1e7e21a9
...
fabbe35483
| Author | SHA1 | Date | |
|---|---|---|---|
| fabbe35483 | |||
| 9b2dc1d49c | |||
| 612a6feac2 | |||
| f0bb29a11a | |||
| cfcdcd9cea | |||
| 229d948850 | |||
| be7d321755 | |||
| 39f9f6800e | |||
| b1bab9ce29 | |||
| 5bf893651e |
331
.gitignore
vendored
Normal file
331
.gitignore
vendored
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/linux,vim,c,cmake,macos,visualstudiocode,windows,node
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=linux,vim,c,cmake,macos,visualstudiocode,windows,node
|
||||||
|
|
||||||
|
### C ###
|
||||||
|
# Prerequisites
|
||||||
|
*.d
|
||||||
|
|
||||||
|
# Object files
|
||||||
|
*.o
|
||||||
|
*.ko
|
||||||
|
*.obj
|
||||||
|
*.elf
|
||||||
|
|
||||||
|
# Linker output
|
||||||
|
*.ilk
|
||||||
|
*.map
|
||||||
|
*.exp
|
||||||
|
|
||||||
|
# Precompiled Headers
|
||||||
|
*.gch
|
||||||
|
*.pch
|
||||||
|
|
||||||
|
# Libraries
|
||||||
|
*.lib
|
||||||
|
*.a
|
||||||
|
*.la
|
||||||
|
*.lo
|
||||||
|
|
||||||
|
# Shared objects (inc. Windows DLLs)
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.so.*
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Executables
|
||||||
|
*.exe
|
||||||
|
*.out
|
||||||
|
*.app
|
||||||
|
*.i*86
|
||||||
|
*.x86_64
|
||||||
|
*.hex
|
||||||
|
|
||||||
|
# Debug files
|
||||||
|
*.dSYM/
|
||||||
|
*.su
|
||||||
|
*.idb
|
||||||
|
*.pdb
|
||||||
|
|
||||||
|
# Kernel Module Compile Results
|
||||||
|
*.mod*
|
||||||
|
*.cmd
|
||||||
|
.tmp_versions/
|
||||||
|
modules.order
|
||||||
|
Module.symvers
|
||||||
|
Mkfile.old
|
||||||
|
dkms.conf
|
||||||
|
|
||||||
|
### CMake ###
|
||||||
|
CMakeLists.txt.user
|
||||||
|
CMakeCache.txt
|
||||||
|
CMakeFiles
|
||||||
|
CMakeScripts
|
||||||
|
Testing
|
||||||
|
Makefile
|
||||||
|
cmake_install.cmake
|
||||||
|
install_manifest.txt
|
||||||
|
compile_commands.json
|
||||||
|
CTestTestfile.cmake
|
||||||
|
_deps
|
||||||
|
|
||||||
|
### CMake Patch ###
|
||||||
|
# External projects
|
||||||
|
*-prefix/
|
||||||
|
|
||||||
|
### Linux ###
|
||||||
|
*~
|
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file
|
||||||
|
.fuse_hidden*
|
||||||
|
|
||||||
|
# KDE directory preferences
|
||||||
|
.directory
|
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk
|
||||||
|
.Trash-*
|
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed
|
||||||
|
.nfs*
|
||||||
|
|
||||||
|
### macOS ###
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
||||||
|
|
||||||
|
### macOS Patch ###
|
||||||
|
# iCloud generated files
|
||||||
|
*.icloud
|
||||||
|
|
||||||
|
### Vim ###
|
||||||
|
# Swap
|
||||||
|
[._]*.s[a-v][a-z]
|
||||||
|
!*.svg # comment out if you don't need vector files
|
||||||
|
[._]*.sw[a-p]
|
||||||
|
[._]s[a-rt-v][a-z]
|
||||||
|
[._]ss[a-gi-z]
|
||||||
|
[._]sw[a-p]
|
||||||
|
|
||||||
|
# Session
|
||||||
|
Session.vim
|
||||||
|
Sessionx.vim
|
||||||
|
|
||||||
|
# Temporary
|
||||||
|
.netrwhist
|
||||||
|
# Auto-generated tag files
|
||||||
|
tags
|
||||||
|
# Persistent undo
|
||||||
|
[._]*.un~
|
||||||
|
|
||||||
|
### Node ###
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
|
# Runtime data
|
||||||
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
.stylelintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variable files
|
||||||
|
.env
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# vuepress v2.x temp and cache directory
|
||||||
|
.temp
|
||||||
|
|
||||||
|
# Docusaurus cache and generated files
|
||||||
|
.docusaurus
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
|
||||||
|
### Node Patch ###
|
||||||
|
# Serverless Webpack directories
|
||||||
|
.webpack/
|
||||||
|
|
||||||
|
# Optional stylelint cache
|
||||||
|
|
||||||
|
# SvelteKit build / generate output
|
||||||
|
.svelte-kit
|
||||||
|
|
||||||
|
### VisualStudioCode ###
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
!.vscode/*.code-snippets
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions
|
||||||
|
*.vsix
|
||||||
|
|
||||||
|
### VisualStudioCode Patch ###
|
||||||
|
# Ignore all local history of files
|
||||||
|
.history
|
||||||
|
.ionide
|
||||||
|
|
||||||
|
### Windows ###
|
||||||
|
# Windows thumbnail cache files
|
||||||
|
Thumbs.db
|
||||||
|
Thumbs.db:encryptable
|
||||||
|
ehthumbs.db
|
||||||
|
ehthumbs_vista.db
|
||||||
|
|
||||||
|
# Dump file
|
||||||
|
*.stackdump
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
[Dd]esktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Windows Installer files
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# Windows shortcuts
|
||||||
|
*.lnk
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/linux,vim,c,cmake,macos,visualstudiocode,windows,node
|
||||||
|
|
||||||
|
build/
|
||||||
|
*.bak
|
||||||
33
CMakeLists.txt
Normal file
33
CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
project(mie C)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(CMAKE_RC_COMPILER_INIT windres)
|
||||||
|
enable_language(RC)
|
||||||
|
SET(CMAKE_RC_COMPILE_OBJECT
|
||||||
|
"<CMAKE_RC_COMPILER> <FLAGS> -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
|
||||||
|
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
if (NOT MIE_STATIC)
|
||||||
|
set(MIE_STATIC 0)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (MIE_STATIC)
|
||||||
|
set(Bluelib_STATIC TRUE)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
find_package(Bluelib REQUIRED)
|
||||||
|
|
||||||
|
add_subdirectory(mie)
|
||||||
|
add_subdirectory(tool)
|
||||||
32
LICENSE
Normal file
32
LICENSE
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
The Clear BSD License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Doorstuck Technologies Group
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted (subject to the limitations in the disclaimer
|
||||||
|
below) provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the copyright holder nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from this
|
||||||
|
software without specific prior written permission.
|
||||||
|
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
|
||||||
|
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||||
|
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||||
|
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
41
README.md
Normal file
41
README.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
[](https://opensource.org/licenses/BSD-3-Clause)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<div align="center">
|
||||||
|
<a href="https://github.com/washh/mie.git">
|
||||||
|
<img src="./doc/assets/logo.png" alt="Logo" width="150">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<h3 align="center">Mie</h3>
|
||||||
|
<p>
|
||||||
|
The Metacompute Instruction Engine
|
||||||
|
<br />
|
||||||
|
<a href="doc"><strong>Explore the docs »</strong></a>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<a href="https://github.com/washh/mie/issues">Report Bug</a>
|
||||||
|
·
|
||||||
|
<a href="https://github.com/washh/mie/issues">Request Feature</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- TABLE OF CONTENTS -->
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
* [About the Project](#about-the-project)
|
||||||
|
* [License](#license)
|
||||||
|
|
||||||
|
<!-- ABOUT THE PROJECT -->
|
||||||
|
## About The Project
|
||||||
|
Mie is an extensible intermediate representation framework inspired by LLVM and MLIR. It is designed to accept high-level program representation from a compiler front-end, lower and optimise it into a flat stream of low-level instructions, and then convert it into a target-specific implementation.
|
||||||
|
|
||||||
|
*(The name Mie is pronounced like "me", "bee", or "sea", and (despite the logo) is _not_ pronounced like "my", "bye", or "pie")*
|
||||||
|
|
||||||
|
|
||||||
|
<!-- LICENSE -->
|
||||||
|
## License
|
||||||
|
|
||||||
|
Distributed under the BSD 3-Clause License. See `LICENSE` for more information.
|
||||||
|
|
||||||
189
cmake/FindBluelib.cmake
Normal file
189
cmake/FindBluelib.cmake
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
#[=======================================================================[.rst:
|
||||||
|
FindBluelib
|
||||||
|
------------
|
||||||
|
|
||||||
|
Find the Bluelib library and header directories
|
||||||
|
|
||||||
|
Imported Targets
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This module defines the following :prop_tgt:`IMPORTED` target:
|
||||||
|
|
||||||
|
``Bluelib::Bluelib``
|
||||||
|
The Bluelib library, if found
|
||||||
|
|
||||||
|
Result Variables
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
This module will set the following variables in your project:
|
||||||
|
|
||||||
|
``Bluelib_FOUND``
|
||||||
|
true if the Bluelib C headers and libraries were found
|
||||||
|
``Bluelib_INCLUDE_DIR``
|
||||||
|
directories containing the Bluelib C headers.
|
||||||
|
|
||||||
|
``Bluelib_LIBRARY``
|
||||||
|
the C library to link against
|
||||||
|
|
||||||
|
Hints
|
||||||
|
^^^^^
|
||||||
|
|
||||||
|
The user may set the environment variable ``Bluelib_PREFIX`` to the root
|
||||||
|
directory of a Bluelib library installation.
|
||||||
|
#]=======================================================================]
|
||||||
|
|
||||||
|
set (Bluelib_SEARCH_PATHS
|
||||||
|
~/Library/Frameworks
|
||||||
|
/Library/Frameworks
|
||||||
|
/usr/local
|
||||||
|
/usr/local/share
|
||||||
|
/usr
|
||||||
|
/sw # Fink
|
||||||
|
/opt/local # DarwinPorts
|
||||||
|
/opt/csw # Blastwave
|
||||||
|
/opt
|
||||||
|
${Bluelib_PREFIX}
|
||||||
|
$ENV{Bluelib_PREFIX})
|
||||||
|
|
||||||
|
if (Bluelib_STATIC)
|
||||||
|
set(_lib_suffix "-s")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(supported_components Core Ds Term Cmd Io Serial Compress)
|
||||||
|
set(components ${Bluelib_FIND_COMPONENTS})
|
||||||
|
string(REPLACE ";" ", " supported_components_string_list "${supported_components}")
|
||||||
|
|
||||||
|
if (NOT components)
|
||||||
|
set(components ${supported_components})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(required_vars)
|
||||||
|
|
||||||
|
foreach (component ${components})
|
||||||
|
if (NOT "${component}" IN_LIST supported_components)
|
||||||
|
message(FATAL_ERROR "'${component}' is not a valid Bluelib module.\nSupported modules: ${supported_components_string_list}")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
string(TOLOWER ${component} header_name)
|
||||||
|
set(lib_name ${header_name}${_lib_suffix})
|
||||||
|
|
||||||
|
if (NOT Bluelib_${component}_INCLUDE_DIR)
|
||||||
|
find_path(Bluelib_${component}_INCLUDE_DIR
|
||||||
|
NAMES blue/${header_name}.h ${Bluelib_FIND_ARGS}
|
||||||
|
PATH_SUFFIXES include
|
||||||
|
PATHS ${Bluelib_SEARCH_PATHS})
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT Bluelib_${component}_LIBRARY)
|
||||||
|
find_library(Bluelib_${component}_LIBRARY
|
||||||
|
NAMES blue-${lib_name} ${Bluelib_FIND_ARGS}
|
||||||
|
PATH_SUFFIXES lib
|
||||||
|
PATHS ${Bluelib_SEARCH_PATHS})
|
||||||
|
else ()
|
||||||
|
# on Windows, ensure paths are in canonical format (forward slahes):
|
||||||
|
file(TO_CMAKE_PATH "${Bluelib_${component}_LIBRARY}" Bluelib_${component}_LIBRARY)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(APPEND required_vars Bluelib_${component}_INCLUDE_DIR Bluelib_${component}_LIBRARY)
|
||||||
|
endforeach (component)
|
||||||
|
|
||||||
|
unset(Bluelib_FIND_ARGS)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
|
||||||
|
find_package_handle_standard_args(Bluelib
|
||||||
|
REQUIRED_VARS ${required_vars})
|
||||||
|
|
||||||
|
if (Bluelib_FOUND)
|
||||||
|
set(created_targets)
|
||||||
|
foreach (component ${components})
|
||||||
|
string(TOLOWER ${component} header_name)
|
||||||
|
set(lib_name ${header_name}${_lib_suffix})
|
||||||
|
|
||||||
|
if(NOT TARGET Bluelib::${component})
|
||||||
|
add_library(Bluelib::${component} UNKNOWN IMPORTED)
|
||||||
|
set_target_properties(Bluelib::${component} PROPERTIES
|
||||||
|
INTERFACE_INCLUDE_DIRECTORIES "${Bluelib_${component}_INCLUDE_DIR}")
|
||||||
|
target_compile_definitions(Bluelib::${component} INTERFACE _CRT_SECURE_NO_WARNINGS=1)
|
||||||
|
|
||||||
|
if (Bluelib_STATIC)
|
||||||
|
target_compile_definitions(Bluelib::${component} INTERFACE BLUELIB_STATIC=1)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set_target_properties(Bluelib::${component} PROPERTIES
|
||||||
|
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||||
|
IMPORTED_LOCATION "${Bluelib_${component}_LIBRARY}")
|
||||||
|
set(created_targets ${created_targets} ${component})
|
||||||
|
endif ()
|
||||||
|
endforeach (component)
|
||||||
|
|
||||||
|
foreach (component ${created_targets})
|
||||||
|
if ("${component}" STREQUAL "Ds")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Ds' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Ds INTERFACE Bluelib::Core)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${component}" STREQUAL "Term")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET Bluelib::Ds)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Term' depends on 'Ds', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Term INTERFACE Bluelib::Core Bluelib::Ds)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${component}" STREQUAL "Serial")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET Bluelib::Ds)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Serial' depends on 'Ds', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Serial INTERFACE Bluelib::Core Bluelib::Ds)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${component}" STREQUAL "Cmd")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET Bluelib::Ds)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Ds', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET Bluelib::Term)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Cmd' depends on 'Term', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Cmd INTERFACE Bluelib::Core Bluelib::Ds Bluelib::Term)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${component}" STREQUAL "Io")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT TARGET Bluelib::Ds)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Io' depends on 'Ds', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Io INTERFACE Bluelib::Core Bluelib::Ds)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if ("${component}" STREQUAL "Compress")
|
||||||
|
if (NOT TARGET Bluelib::Core)
|
||||||
|
message(FATAL_ERROR "Bluelib: Module 'Compress' depends on 'Core', which was not specified in find_package()")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
target_link_libraries(Bluelib::Compress INTERFACE Bluelib::Core Bluelib::Ds)
|
||||||
|
endif ()
|
||||||
|
endforeach (component)
|
||||||
|
endif()
|
||||||
BIN
doc/assets/logo.png
Normal file
BIN
doc/assets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
14
doc/sample/for-loop-1.mie
Normal file
14
doc/sample/for-loop-1.mie
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||||
|
; Initial sum set to 0.
|
||||||
|
%sum.0 = arith.constant 0.0 : f32
|
||||||
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
|
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
|
||||||
|
%t = memref.load %buffer[%iv] : memref<1024*f32>
|
||||||
|
%sum.next = arith.addf %sum.iter, %t : f32
|
||||||
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
|
; if final iteration.
|
||||||
|
scf.yield %sum.next : f32
|
||||||
|
}
|
||||||
|
|
||||||
|
func.return %sum : f32
|
||||||
|
}
|
||||||
16
doc/sample/for-loop-2.mie
Normal file
16
doc/sample/for-loop-2.mie
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
|
||||||
|
; Initial sum set to 0.
|
||||||
|
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
|
||||||
|
|
||||||
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
|
%sum = scf.for %iv = %lb to %ub step %step iter_args(%sum.iter = %sum.0) -> (f32) {
|
||||||
|
%t = *memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
|
||||||
|
%sum.next = *arith.addf(%sum.iter, %t) : (f32, f32) -> f32
|
||||||
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
|
; if final iteration.
|
||||||
|
*scf.yield(%sum.next) : (f32) -> ()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*func.return(%sum) : (f32) -> ()
|
||||||
|
}
|
||||||
19
doc/sample/for-loop-3.mie
Normal file
19
doc/sample/for-loop-3.mie
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
*func.func(%buffer, %lb, %ub, %step) ({
|
||||||
|
; Initial sum set to 0.
|
||||||
|
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
|
||||||
|
|
||||||
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
|
%sum = *scf.for(%lb, %ub, %step) -> (f32) {
|
||||||
|
^for.entry(%iv: index, %sum.iter: f32):
|
||||||
|
%t = *memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
|
||||||
|
%sum.next = *arith.addf(%sum.iter, %t) : (f32, f32) -> f32
|
||||||
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
|
; if final iteration.
|
||||||
|
%iv.next = *arith.addi(%iv, %step) : (index, index) -> index
|
||||||
|
%stop = *arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
|
||||||
|
*cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
|
||||||
|
}
|
||||||
|
^for.end:
|
||||||
|
*func.return(%sum) : (f32) -> ()
|
||||||
|
}) {sym_name = "reduce"} : (memref<1024*i32>, index, index, index) -> f32
|
||||||
|
|
||||||
25
doc/sample/for-loop-4.mie
Normal file
25
doc/sample/for-loop-4.mie
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
*func.func(%buffer, %lb, %ub, %step) ({
|
||||||
|
; Initial sum set to 0.
|
||||||
|
%sum.0 = *arith.constant() {value = 0.0 : f32} : () -> f32
|
||||||
|
|
||||||
|
; iter_args binds initial values to the loop's region arguments.
|
||||||
|
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
|
||||||
|
*cf.br [ ^for.entry(%lb: index, %sum.0: f32) ] : () -> ()
|
||||||
|
|
||||||
|
^for.entry(%iv: index, %sum.iter: f32):
|
||||||
|
%t = *memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
|
||||||
|
%sum.next = *arith.addf(%sum.iter, %t) : (f32, f32) -> f32
|
||||||
|
|
||||||
|
*cf.br [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
|
||||||
|
|
||||||
|
^for.cond(%iv: index, %sum.next: f32):
|
||||||
|
; Yield current iteration sum to next iteration %sum.iter or to %sum
|
||||||
|
; if final iteration.
|
||||||
|
%iv.next = *arith.addi(%iv, %step) : (index, index) -> index
|
||||||
|
%stop = *arith.cmpi(%iv.next, %ub) {predicate = 9 : i64} : (index, index) -> i1
|
||||||
|
*cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
|
||||||
|
|
||||||
|
^for.end(%sum: f32):
|
||||||
|
*func.return(%sum) : (f32) -> ()
|
||||||
|
}) {sym_name = "reduce"} : (memref<1024*f32.abc>, index, index, index) -> f32
|
||||||
|
|
||||||
@@ -4,37 +4,45 @@ endif
|
|||||||
|
|
||||||
let s:save_cpo = &cpoptions
|
let s:save_cpo = &cpoptions
|
||||||
set cpoptions&vim
|
set cpoptions&vim
|
||||||
|
setlocal iskeyword+=-
|
||||||
|
|
||||||
syn keyword mieUnspecifiedStatement record data define type global
|
syn keyword mieUnspecifiedKeyword to step iter-args
|
||||||
syn keyword mieInstruction
|
|
||||||
\ alloca load store call br cmp
|
|
||||||
\ add sub div mul msg
|
|
||||||
\ getelementptr switch ret
|
|
||||||
syn keyword mieInstructionFlag
|
syn keyword mieInstructionFlag
|
||||||
\ eq gt ge lt le
|
\ eq gt ge lt le
|
||||||
syn match mieRegister "%[0-9]\>"
|
syn match mieRegister "%[0-9]\>"
|
||||||
syn match mieRegister "%[1-9][0-9]\+\>"
|
syn match mieRegister "%[1-9][0-9]\+\>"
|
||||||
syn match mieRegister "%[A-Za-z\.][A-Za-z0-9\.]*\>"
|
syn match mieRegister "%[A-Za-z_\-\.][A-Za-z0-9_\-\.]*\>"
|
||||||
syn match mieIdentifier /@\(\w\+\)\(\.\(\w\+\)\)*\>/
|
syn match mieIdentifier /@\(\w\+\)\(\.\(\w\+\)\)*\>/
|
||||||
syn match mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/
|
syn match mieIdentifier /@\.\(\w\+\)\(\.\(\w\+\)\)*\>/
|
||||||
syn match mieLabel /\(\w\+\)\(\.\(\w\+\)\)*\:/
|
syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/
|
||||||
syn keyword mieType id ptr str atom label void
|
syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/
|
||||||
syn keyword mieTypeModifier external
|
syn keyword mieBuiltinType void index
|
||||||
syn match mieType "i[0-9]\>"
|
syn keyword mieBuiltinType f16 f32 f64 f80 f128
|
||||||
syn match mieType "i[1-9][0-9]\+\>"
|
" Use syn match for type names that are ALSO dialect names, to ensure that
|
||||||
syn keyword mieBlockType lambda instance static class
|
" dialect operations are still matched as such.
|
||||||
|
syn match mieBuiltinType /\<memref\>/
|
||||||
|
syn match mieBuiltinType "i[0-9]\>"
|
||||||
|
syn match mieBuiltinType "i[1-9][0-9]\+\>"
|
||||||
|
syn match mieDialectType /#[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
|
||||||
|
|
||||||
syn match mieFieldIndex /#[0-9]\+:\>/
|
syn match mieCustomOperation /\<[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\>/
|
||||||
syn match mieFieldIndex /#-[0-9]\+:\>/
|
syn match mieGenericOperation /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
|
||||||
syn match mieFieldIndex /#0x[:xdigit:]\+:\>/
|
|
||||||
syn match mieFieldIndex /#-0x[:xdigit:]\+:\>/
|
syn match mieAttributeName /\<[A-Za-z][A-Za-z0-9\-_\.]*\(\s*=\)\@=\>/
|
||||||
|
|
||||||
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend
|
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend
|
||||||
|
|
||||||
syn match mieInteger /#[0-9]\+\>/
|
syn match mieFloat /[0-9]\+\.[0-9]\+/
|
||||||
syn match mieInteger /#-[0-9]\+\>/
|
syn match mieFloat /-[0-9]\+\.[0-9]\+/
|
||||||
syn match mieInteger /#0x[:xdigit:]\+\>/
|
syn match mieFloat /+[0-9]\+\.[0-9]\+/
|
||||||
syn match mieInteger /#-0x[:xdigit:]\+\>/
|
|
||||||
|
syn match mieInteger /[0-9]\+\(\.\)\@!\>/
|
||||||
|
syn match mieInteger /-[0-9]\+\(\.\)\@!\>/
|
||||||
|
syn match mieInteger /0x[:xdigit:]\+\>/
|
||||||
|
syn match mieInteger /-0x[:xdigit:]\+\>/
|
||||||
|
|
||||||
|
syn match mieIntegerDimension /[0-9]\+x/
|
||||||
|
syn match mieIntegerDimension /0x[:xdigit:]\+x/
|
||||||
|
|
||||||
syn keyword mieTodo contained TODO FIXME XXX NOTE HACK TBD
|
syn keyword mieTodo contained TODO FIXME XXX NOTE HACK TBD
|
||||||
syn region mieBlockComment start="/\*" end="\*/" contains=mieTodo,mieBlockComment
|
syn region mieBlockComment start="/\*" end="\*/" contains=mieTodo,mieBlockComment
|
||||||
@@ -43,33 +51,39 @@ syn cluster mieComment contains=mieLineComment,mieBlockComment
|
|||||||
|
|
||||||
syn match mieBrackets "[[\]]" display
|
syn match mieBrackets "[[\]]" display
|
||||||
syn match mieParens "[()]" display
|
syn match mieParens "[()]" display
|
||||||
|
syn match mieBraces "[{}]" display
|
||||||
|
syn match mieAngleBrackets "[<>]" display
|
||||||
|
syn match mieOperator "[=:]" display
|
||||||
|
syn match mieOperator "->" display
|
||||||
syn match ivyPropertySymbol "\$" display
|
syn match ivyPropertySymbol "\$" display
|
||||||
|
|
||||||
" The default highlighting.
|
" The default highlighting.
|
||||||
hi def link mieUnspecifiedStatement Statement
|
hi def link mieUnspecifiedKeyword Keyword
|
||||||
hi def link ivyPropertySymbol Statement
|
hi def link ivyPropertySymbol Statement
|
||||||
|
|
||||||
hi def link mieInteger Number
|
hi def link mieInteger Number
|
||||||
|
hi def link mieFloat Number
|
||||||
|
|
||||||
hi def link mieParens Delimiter
|
hi def link mieParens Delimiter
|
||||||
hi def link mieBraces Structure
|
hi def link mieBraces Structure
|
||||||
|
hi def link mieBrackets Delimiter
|
||||||
|
hi def link mieAngleBrackets StorageClass
|
||||||
|
|
||||||
hi def link miePropertyName @property
|
hi def link mieDialectType Type
|
||||||
hi def link mieFieldName @variable.parameter
|
|
||||||
hi def link mieClassName Type
|
|
||||||
hi def link mieLambdaName @variable.parameter
|
|
||||||
|
|
||||||
hi def link mieInstruction Function
|
hi def link mieGenericOperation @function.builtin
|
||||||
|
hi def link mieCustomOperation Function
|
||||||
hi def link mieInstructionFlag StorageClass
|
hi def link mieInstructionFlag StorageClass
|
||||||
hi def link mieIdentifier Identifier
|
hi def link mieIdentifier Identifier
|
||||||
hi def link mieLabel Tag
|
hi def link mieBlockIdentifier Label
|
||||||
hi def link mieIndexBase @variable.builtin
|
hi def link mieBlockLabel Label
|
||||||
hi def link mieRegister Constant
|
hi def link mieRegister @variable
|
||||||
|
|
||||||
hi def link mieString String
|
hi def link mieString String
|
||||||
hi def link mieType Type
|
hi def link mieBuiltinType @type.builtin
|
||||||
hi def link mieBlockType @attribute
|
hi def link mieBlockType @attribute
|
||||||
hi def link mieTypeModifier @attribute
|
hi def link mieTypeModifier @attribute
|
||||||
|
hi def link mieAttributeName @property
|
||||||
|
|
||||||
hi def link mieComment Comment
|
hi def link mieComment Comment
|
||||||
hi def link mieLineComment mieComment
|
hi def link mieLineComment mieComment
|
||||||
|
|||||||
@@ -11,5 +11,5 @@ else ()
|
|||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
|
||||||
target_link_libraries(mie Bluelib::Core Bluelib::Object)
|
target_link_libraries(mie Bluelib::Core Bluelib::Ds)
|
||||||
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${IVY_STATIC})
|
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC})
|
||||||
|
|||||||
30
mie/ctx.c
30
mie/ctx.c
@@ -1,6 +1,6 @@
|
|||||||
#include <blue/object/hashmap.h>
|
#include <blue/ds/hashmap.h>
|
||||||
#include <blue/object/list.h>
|
#include <blue/ds/list.h>
|
||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
#include <mie/ir/const.h>
|
#include <mie/ir/const.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -62,23 +62,25 @@ void mie_ctx_destroy(struct mie_ctx *ctx)
|
|||||||
ctx->ctx_true = NULL;
|
ctx->ctx_true = NULL;
|
||||||
ctx->ctx_false = NULL;
|
ctx->ctx_false = NULL;
|
||||||
|
|
||||||
b_btree_iterator it = {};
|
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
|
||||||
b_btree_iterator_begin(&ctx->ctx_int_cache, &it);
|
while (node) {
|
||||||
while (b_btree_iterator_is_valid(&it)) {
|
|
||||||
struct ctx_int_cache_entry *entry
|
struct ctx_int_cache_entry *entry
|
||||||
= b_unbox(struct ctx_int_cache_entry, it.node, i_node);
|
= b_unbox(struct ctx_int_cache_entry, node, i_node);
|
||||||
b_btree_iterator_erase(&it);
|
b_btree_node *next = b_btree_next(node);
|
||||||
|
b_btree_delete(&ctx->ctx_int_cache, node);
|
||||||
|
|
||||||
b_btree_iterator it2 = {};
|
b_btree_node *node2 = b_btree_first(&entry->i_values);
|
||||||
b_btree_iterator_begin(&entry->i_values, &it2);
|
while (node2) {
|
||||||
while (b_btree_iterator_is_valid(&it2)) {
|
|
||||||
struct ctx_int_value_cache_entry *value = b_unbox(
|
struct ctx_int_value_cache_entry *value = b_unbox(
|
||||||
struct ctx_int_value_cache_entry, it2.node, i_node);
|
struct ctx_int_value_cache_entry, node2, i_node);
|
||||||
b_btree_iterator_erase(&it2);
|
b_btree_node *next2 = b_btree_next(node2);
|
||||||
|
b_btree_delete(&entry->i_values, node2);
|
||||||
free(value);
|
free(value);
|
||||||
|
node2 = next2;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(entry);
|
free(entry);
|
||||||
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
|
const size_t nr_types = sizeof ctx->ctx_types / sizeof ctx->ctx_types[0];
|
||||||
@@ -93,7 +95,7 @@ void mie_ctx_destroy(struct mie_ctx *ctx)
|
|||||||
mie_value_destroy(ctx->ctx_null);
|
mie_value_destroy(ctx->ctx_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_hashmap_release(ctx->ctx_sel_cache);
|
b_hashmap_unref(ctx->ctx_sel_cache);
|
||||||
|
|
||||||
free(ctx);
|
free(ctx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define MIE_CTX_H_
|
#define MIE_CTX_H_
|
||||||
|
|
||||||
#include <blue/core/btree.h>
|
#include <blue/core/btree.h>
|
||||||
|
#include <blue/ds/hashmap.h>
|
||||||
#include <mie/type.h>
|
#include <mie/type.h>
|
||||||
|
|
||||||
struct mie_ctx {
|
struct mie_ctx {
|
||||||
@@ -9,8 +10,8 @@ struct mie_ctx {
|
|||||||
struct mie_value *ctx_null;
|
struct mie_value *ctx_null;
|
||||||
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
|
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
|
||||||
b_btree ctx_int_cache;
|
b_btree ctx_int_cache;
|
||||||
struct b_hashmap *ctx_sel_cache;
|
b_hashmap *ctx_sel_cache;
|
||||||
struct b_hashmap *ctx_string_cache;
|
b_hashmap *ctx_string_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mie_ctx *mie_ctx_create(void);
|
extern struct mie_ctx *mie_ctx_create(void);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#ifndef MIE_CONST_H_
|
#ifndef MIE_CONST_H_
|
||||||
#define MIE_CONST_H_
|
#define MIE_CONST_H_
|
||||||
|
|
||||||
|
#include <blue/ds/list.h>
|
||||||
#include <mie/ir/value.h>
|
#include <mie/ir/value.h>
|
||||||
#include <mie/type.h>
|
#include <mie/type.h>
|
||||||
|
|
||||||
@@ -13,8 +14,6 @@
|
|||||||
#define MIE_SELECTOR(p) ((struct mie_selector *)(p))
|
#define MIE_SELECTOR(p) ((struct mie_selector *)(p))
|
||||||
#define MIE_ARRAY(p) ((struct mie_array *)(p))
|
#define MIE_ARRAY(p) ((struct mie_array *)(p))
|
||||||
|
|
||||||
struct b_list;
|
|
||||||
|
|
||||||
struct mie_const {
|
struct mie_const {
|
||||||
struct mie_value c_base;
|
struct mie_value c_base;
|
||||||
struct mie_type *c_type;
|
struct mie_type *c_type;
|
||||||
@@ -47,7 +46,7 @@ struct mie_selector {
|
|||||||
|
|
||||||
struct mie_array {
|
struct mie_array {
|
||||||
struct mie_const a_base;
|
struct mie_const a_base;
|
||||||
struct b_list *a_values;
|
b_list *a_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void mie_const_init(struct mie_const *c, struct mie_type *type);
|
extern void mie_const_init(struct mie_const *c, struct mie_type *type);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#define MIE_CONVERT_H_
|
#define MIE_CONVERT_H_
|
||||||
|
|
||||||
#include <blue/core/stringstream.h>
|
#include <blue/core/stringstream.h>
|
||||||
#include <blue/object/bitbuffer.h>
|
#include <blue/ds/bitbuffer.h>
|
||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
#define MIE_MODULE(p) ((struct mie_module *)(p))
|
#define MIE_MODULE(p) ((struct mie_module *)(p))
|
||||||
|
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
|
#include <blue/ds/hashmap.h>
|
||||||
#include <mie/ir/value.h>
|
#include <mie/ir/value.h>
|
||||||
#include <mie/name.h>
|
#include <mie/name.h>
|
||||||
|
|
||||||
struct mie_func;
|
struct mie_func;
|
||||||
struct b_hashmap;
|
|
||||||
|
|
||||||
struct mie_module {
|
struct mie_module {
|
||||||
struct mie_value m_base;
|
struct mie_value m_base;
|
||||||
@@ -17,8 +17,8 @@ struct mie_module {
|
|||||||
b_queue m_types;
|
b_queue m_types;
|
||||||
b_queue m_func;
|
b_queue m_func;
|
||||||
|
|
||||||
struct b_hashmap *m_data;
|
b_hashmap *m_data;
|
||||||
struct b_hashmap *m_data_strings;
|
b_hashmap *m_data_strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct mie_module *mie_module_create(void);
|
extern struct mie_module *mie_module_create(void);
|
||||||
|
|||||||
@@ -49,4 +49,7 @@ MIE_API enum mie_status mie_select_builder_set_mem_access(
|
|||||||
struct mie_select_builder *builder, struct mie_value *ir_val,
|
struct mie_select_builder *builder, struct mie_value *ir_val,
|
||||||
struct mie_select_value *graph_val);
|
struct mie_select_value *graph_val);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_select_builder_collapse_chain_ends(
|
||||||
|
struct mie_select_builder *builder, struct mie_select_value *out);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,30 +21,24 @@ struct mie_select_use {
|
|||||||
b_queue_entry u_entry;
|
b_queue_entry u_entry;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mie_select_chain_end {
|
||||||
|
struct mie_select_value c_value;
|
||||||
|
b_queue_entry c_entry;
|
||||||
|
};
|
||||||
|
|
||||||
struct mie_select_graph {
|
struct mie_select_graph {
|
||||||
b_queue g_nodes;
|
b_queue g_nodes;
|
||||||
struct mie_select_node *g_root;
|
struct mie_select_node *g_root;
|
||||||
struct mie_select_value g_entry;
|
struct mie_select_value g_entry;
|
||||||
struct mie_select_value g_last_chain;
|
b_queue g_chain_ends;
|
||||||
size_t g_frame_index;
|
size_t g_frame_index;
|
||||||
size_t g_node_id;
|
size_t g_node_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mie_select_use_iterator {
|
struct mie_select_use_iterator {
|
||||||
b_queue_iterator it_base;
|
b_queue_entry *it_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mie_select_use_foreach(it, q) b_queue_foreach (&(it)->it_base, q)
|
|
||||||
|
|
||||||
static inline struct mie_select_use *mie_select_use_iterator_unbox(
|
|
||||||
struct mie_select_use_iterator *it)
|
|
||||||
{
|
|
||||||
return b_unbox(struct mie_select_use, it->it_base.entry, u_entry);
|
|
||||||
}
|
|
||||||
MIE_API void mie_select_use_iterator_next(struct mie_select_use_iterator *it);
|
|
||||||
MIE_API bool mie_select_use_iterator_is_valid(
|
|
||||||
const struct mie_select_use_iterator *it);
|
|
||||||
|
|
||||||
MIE_API struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx);
|
MIE_API struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx);
|
||||||
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
|
||||||
|
|
||||||
@@ -54,6 +48,7 @@ MIE_API enum mie_status mie_select_graph_get_node(
|
|||||||
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
|
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
|
||||||
|
|
||||||
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
|
||||||
MIE_API void mie_select_graph_dump_dot(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_dump_dot(
|
||||||
|
struct mie_select_graph *graph, const char *filename);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -61,13 +61,13 @@ struct mie_select_node {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct mie_select_node_iterator {
|
struct mie_select_node_iterator {
|
||||||
b_queue_iterator it_base;
|
b_queue_entry *it_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct mie_select_node *mie_select_node_iterator_unbox(
|
static inline struct mie_select_node *mie_select_node_iterator_unbox(
|
||||||
struct mie_select_node_iterator *it)
|
struct mie_select_node_iterator *it)
|
||||||
{
|
{
|
||||||
return b_unbox(struct mie_select_node, it->it_base.entry, n_entry);
|
return b_unbox(struct mie_select_node, it->it_ptr, n_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
MIE_API void mie_select_node_iterator_next(struct mie_select_node_iterator *it);
|
MIE_API void mie_select_node_iterator_next(struct mie_select_node_iterator *it);
|
||||||
|
|||||||
@@ -20,6 +20,12 @@ enum mie_select_opcode {
|
|||||||
MIE_SELECT_OP_MUL,
|
MIE_SELECT_OP_MUL,
|
||||||
MIE_SELECT_OP_DIV,
|
MIE_SELECT_OP_DIV,
|
||||||
MIE_SELECT_OP_XOR,
|
MIE_SELECT_OP_XOR,
|
||||||
|
MIE_SELECT_OP_CMP_EQ,
|
||||||
|
MIE_SELECT_OP_CMP_NEQ,
|
||||||
|
MIE_SELECT_OP_CMP_LT,
|
||||||
|
MIE_SELECT_OP_CMP_GT,
|
||||||
|
MIE_SELECT_OP_CMP_LEQ,
|
||||||
|
MIE_SELECT_OP_CMP_GEQ,
|
||||||
MIE_SELECT_OP_BR,
|
MIE_SELECT_OP_BR,
|
||||||
MIE_SELECT_OP_BR_COND,
|
MIE_SELECT_OP_BR_COND,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -70,19 +70,26 @@ static void cleanup(struct mie_value *value)
|
|||||||
{
|
{
|
||||||
struct mie_block *block = MIE_BLOCK(value);
|
struct mie_block *block = MIE_BLOCK(value);
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&block->b_phi);
|
||||||
b_queue_iterator_begin(&block->b_phi, &it);
|
b_queue_entry *next = NULL;
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
while (entry) {
|
||||||
b_queue_iterator_erase(&it);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&block->b_phi, entry);
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator_begin(&block->b_instr, &it);
|
entry = b_queue_first(&block->b_instr);
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&block->b_instr, entry);
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block->b_terminator) {
|
if (block->b_terminator) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
#include <mie/ir/alloca.h>
|
#include <mie/ir/alloca.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
@@ -52,15 +52,16 @@ struct mie_record *mie_builder_put_record(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator it = {};
|
b_queue_entry *entry = b_queue_first(&builder->b_module->m_records);
|
||||||
b_queue_foreach (&it, &builder->b_module->m_records) {
|
while (entry) {
|
||||||
struct mie_value *rec
|
struct mie_value *rec = b_unbox(struct mie_value, entry, v_entry);
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
|
||||||
|
|
||||||
if (!strcmp(rec->v_name.n_str, name)) {
|
if (!strcmp(rec->v_name.n_str, name)) {
|
||||||
/* TODO what to do about `val` here? */
|
/* TODO what to do about `val` here? */
|
||||||
return MIE_RECORD(rec);
|
return MIE_RECORD(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_record *rec = mie_record_create(val);
|
struct mie_record *rec = mie_record_create(val);
|
||||||
@@ -77,14 +78,15 @@ struct mie_record *mie_builder_get_record(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator it = {};
|
b_queue_entry *entry = b_queue_first(&builder->b_module->m_records);
|
||||||
b_queue_foreach (&it, &builder->b_module->m_records) {
|
while (entry) {
|
||||||
struct mie_value *rec
|
struct mie_value *rec = b_unbox(struct mie_value, entry, v_entry);
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
|
||||||
|
|
||||||
if (!strcmp(rec->v_name.n_str, name)) {
|
if (!strcmp(rec->v_name.n_str, name)) {
|
||||||
return MIE_RECORD(rec);
|
return MIE_RECORD(rec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -579,7 +581,7 @@ struct mie_value *mie_builder_cmp_eq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -615,7 +617,7 @@ struct mie_value *mie_builder_cmp_neq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -651,7 +653,7 @@ struct mie_value *mie_builder_cmp_lt(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -687,7 +689,7 @@ struct mie_value *mie_builder_cmp_gt(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -723,7 +725,7 @@ struct mie_value *mie_builder_cmp_leq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
@@ -759,7 +761,7 @@ struct mie_value *mie_builder_cmp_geq(
|
|||||||
|
|
||||||
sub->op_left = left;
|
sub->op_left = left;
|
||||||
sub->op_right = right;
|
sub->op_right = right;
|
||||||
sub->op_type = mie_value_get_type(left, builder->b_ctx);
|
sub->op_type = mie_ctx_get_int_type(builder->b_ctx, 1);
|
||||||
|
|
||||||
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
if (!mie_block_add_instr(builder->b_current_block, &sub->op_base)) {
|
||||||
free(sub);
|
free(sub);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#include "convert.h"
|
#include "convert.h"
|
||||||
|
|
||||||
#include <blue/object/hashmap.h>
|
#include <blue/ds/hashmap.h>
|
||||||
#include <blue/object/list.h>
|
#include <blue/ds/list.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <mie/ir/alloca.h>
|
#include <mie/ir/alloca.h>
|
||||||
#include <mie/ir/arg.h>
|
#include <mie/ir/arg.h>
|
||||||
@@ -32,7 +32,8 @@ b_status write_char(struct mie_ir_converter *converter, char c)
|
|||||||
|
|
||||||
switch (converter->c_dest_medium) {
|
switch (converter->c_dest_medium) {
|
||||||
case MIE_IR_CONVERTER_STRINGSTREAM:
|
case MIE_IR_CONVERTER_STRINGSTREAM:
|
||||||
return b_stringstream_add(converter->c_dest.stringstream, s);
|
return b_stream_write_string(
|
||||||
|
converter->c_dest.stringstream, s, NULL);
|
||||||
case MIE_IR_CONVERTER_STRING:
|
case MIE_IR_CONVERTER_STRING:
|
||||||
b_string_append_cstr(converter->c_dest.string, s);
|
b_string_append_cstr(converter->c_dest.string, s);
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
@@ -52,7 +53,8 @@ b_status write_string(struct mie_ir_converter *converter, const char *s)
|
|||||||
|
|
||||||
switch (converter->c_dest_medium) {
|
switch (converter->c_dest_medium) {
|
||||||
case MIE_IR_CONVERTER_STRINGSTREAM:
|
case MIE_IR_CONVERTER_STRINGSTREAM:
|
||||||
return b_stringstream_add(converter->c_dest.stringstream, s);
|
return b_stream_write_string(
|
||||||
|
converter->c_dest.stringstream, s, NULL);
|
||||||
case MIE_IR_CONVERTER_STRING:
|
case MIE_IR_CONVERTER_STRING:
|
||||||
b_string_append_cstr(converter->c_dest.string, s);
|
b_string_append_cstr(converter->c_dest.string, s);
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
@@ -79,7 +81,8 @@ b_status write_string_f(struct mie_ir_converter *converter, const char *format,
|
|||||||
switch (converter->c_dest_medium) {
|
switch (converter->c_dest_medium) {
|
||||||
case MIE_IR_CONVERTER_STRINGSTREAM:
|
case MIE_IR_CONVERTER_STRINGSTREAM:
|
||||||
vsnprintf(buf, sizeof buf, format, arg);
|
vsnprintf(buf, sizeof buf, format, arg);
|
||||||
status = b_stringstream_add(converter->c_dest.stringstream, buf);
|
status = b_stream_write_string(
|
||||||
|
converter->c_dest.stringstream, buf, NULL);
|
||||||
break;
|
break;
|
||||||
case MIE_IR_CONVERTER_STRING:
|
case MIE_IR_CONVERTER_STRING:
|
||||||
vsnprintf(buf, sizeof buf, format, arg);
|
vsnprintf(buf, sizeof buf, format, arg);
|
||||||
@@ -147,23 +150,26 @@ static b_status write_operand_const(
|
|||||||
break;
|
break;
|
||||||
case MIE_TYPE_ARRAY: {
|
case MIE_TYPE_ARRAY: {
|
||||||
struct mie_array *array = MIE_ARRAY(value);
|
struct mie_array *array = MIE_ARRAY(value);
|
||||||
b_list_iterator it;
|
b_iterator *it = b_list_begin(array->a_values);
|
||||||
b_list_iterator_begin(array->a_values, &it);
|
|
||||||
|
|
||||||
write_char(converter, '{');
|
write_char(converter, '{');
|
||||||
while (b_list_iterator_is_valid(&it)) {
|
size_t i = 0;
|
||||||
if (it.i > 0) {
|
b_foreach(void *, item, it)
|
||||||
|
{
|
||||||
|
if (i > 0) {
|
||||||
write_char(converter, ',');
|
write_char(converter, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
write_string(converter, "\n ");
|
write_string(converter, "\n ");
|
||||||
|
|
||||||
struct mie_value *child = it.item;
|
struct mie_value *child = item;
|
||||||
write_operand_const(converter, child, F_INCLUDE_TYPE);
|
write_operand_const(converter, child, F_INCLUDE_TYPE);
|
||||||
|
|
||||||
b_list_iterator_next(&it);
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b_iterator_unref(it);
|
||||||
|
|
||||||
if (!b_list_empty(array->a_values)) {
|
if (!b_list_empty(array->a_values)) {
|
||||||
write_char(converter, '\n');
|
write_char(converter, '\n');
|
||||||
}
|
}
|
||||||
@@ -292,39 +298,43 @@ static b_status write_module(
|
|||||||
struct mie_module *mod = MIE_MODULE(value);
|
struct mie_module *mod = MIE_MODULE(value);
|
||||||
b_status status = B_SUCCESS;
|
b_status status = B_SUCCESS;
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&mod->m_records);
|
||||||
b_queue_foreach (&it, &mod->m_records) {
|
while (entry) {
|
||||||
struct mie_value *record
|
struct mie_value *record
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
= b_unbox(struct mie_value, entry, v_entry);
|
||||||
status = write_value_to_text(converter, record);
|
status = write_value_to_text(converter, record);
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!b_queue_empty(&mod->m_records)) {
|
if (!b_queue_empty(&mod->m_records)) {
|
||||||
write_char(converter, '\n');
|
write_char(converter, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_foreach (&it, &mod->m_types) {
|
entry = b_queue_first(&mod->m_types);
|
||||||
struct mie_value *type
|
while (entry) {
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *type = b_unbox(struct mie_value, entry, v_entry);
|
||||||
status = write_value_to_text(converter, type);
|
status = write_value_to_text(converter, type);
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
if (!B_OK(status)) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!b_queue_empty(&mod->m_types)) {
|
if (!b_queue_empty(&mod->m_types)) {
|
||||||
write_char(converter, '\n');
|
write_char(converter, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
b_hashmap_iterator it2;
|
b_iterator *it = b_iterator_begin(mod->m_data);
|
||||||
b_hashmap_foreach(&it2, mod->m_data)
|
b_foreach_ptr(b_hashmap_item, item, it)
|
||||||
{
|
{
|
||||||
struct mie_value *data = it2.value->value_data;
|
struct mie_value *data = item->value.value_data;
|
||||||
status = write_value_to_text(converter, data);
|
status = write_value_to_text(converter, data);
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
if (!B_OK(status)) {
|
||||||
@@ -332,18 +342,20 @@ static b_status write_module(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b_iterator_unref(it);
|
||||||
|
|
||||||
if (!b_hashmap_is_empty(mod->m_data)) {
|
if (!b_hashmap_is_empty(mod->m_data)) {
|
||||||
write_char(converter, '\n');
|
write_char(converter, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long i = 0;
|
unsigned long i = 0;
|
||||||
b_queue_foreach (&it, &mod->m_func) {
|
entry = b_queue_first(&mod->m_func);
|
||||||
|
while (entry) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
write_char(converter, '\n');
|
write_char(converter, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_value *func
|
struct mie_value *func = b_unbox(struct mie_value, entry, v_entry);
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
|
||||||
status = write_value_to_text(converter, func);
|
status = write_value_to_text(converter, func);
|
||||||
|
|
||||||
if (!B_OK(status)) {
|
if (!B_OK(status)) {
|
||||||
@@ -351,6 +363,7 @@ static b_status write_module(
|
|||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_SUCCESS;
|
return B_SUCCESS;
|
||||||
@@ -390,10 +403,10 @@ static b_status write_func_definition(
|
|||||||
converter, "define %s @%s(", type_name, func->f_base.v_name.n_str);
|
converter, "define %s @%s(", type_name, func->f_base.v_name.n_str);
|
||||||
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
b_queue_iterator it;
|
struct b_queue_entry *entry = b_queue_first(&func->f_args);
|
||||||
b_queue_foreach (&it, &func->f_args) {
|
while (entry) {
|
||||||
struct mie_arg *arg = (struct mie_arg *)b_unbox(
|
struct mie_arg *arg = (struct mie_arg *)b_unbox(
|
||||||
struct mie_value, it.entry, v_entry);
|
struct mie_value, entry, v_entry);
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
write_string(converter, ", ");
|
write_string(converter, ", ");
|
||||||
@@ -405,6 +418,7 @@ static b_status write_func_definition(
|
|||||||
converter, "%s %%%s", type_name,
|
converter, "%s %%%s", type_name,
|
||||||
arg->arg_base.v_name.n_str);
|
arg->arg_base.v_name.n_str);
|
||||||
i++;
|
i++;
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_string_f(converter, ")");
|
write_string_f(converter, ")");
|
||||||
@@ -425,10 +439,12 @@ static b_status write_func_definition(
|
|||||||
|
|
||||||
write_string_f(converter, " {\n");
|
write_string_f(converter, " {\n");
|
||||||
|
|
||||||
b_queue_foreach (&it, &func->f_blocks) {
|
entry = b_queue_first(&func->f_blocks);
|
||||||
|
while (entry) {
|
||||||
struct mie_value *block
|
struct mie_value *block
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
= b_unbox(struct mie_value, entry, v_entry);
|
||||||
write_value_to_text(converter, block);
|
write_value_to_text(converter, block);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_string_f(converter, "}\n");
|
write_string_f(converter, "}\n");
|
||||||
@@ -442,17 +458,20 @@ static b_status write_block_definition(
|
|||||||
struct mie_block *block = MIE_BLOCK(value);
|
struct mie_block *block = MIE_BLOCK(value);
|
||||||
|
|
||||||
write_string_f(converter, "%s:\n", block->b_base.v_name.n_str);
|
write_string_f(converter, "%s:\n", block->b_base.v_name.n_str);
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&block->b_phi);
|
||||||
b_queue_foreach (&it, &block->b_phi) {
|
while (entry) {
|
||||||
struct mie_value *instr
|
struct mie_value *instr
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
= b_unbox(struct mie_value, entry, v_entry);
|
||||||
write_value_to_text(converter, instr);
|
write_value_to_text(converter, instr);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_foreach (&it, &block->b_instr) {
|
entry = b_queue_first(&block->b_instr);
|
||||||
|
while (entry) {
|
||||||
struct mie_value *instr
|
struct mie_value *instr
|
||||||
= b_unbox(struct mie_value, it.entry, v_entry);
|
= b_unbox(struct mie_value, entry, v_entry);
|
||||||
write_value_to_text(converter, instr);
|
write_value_to_text(converter, instr);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block->b_terminator) {
|
if (block->b_terminator) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
#include <mie/ir/data.h>
|
#include <mie/ir/data.h>
|
||||||
#include <mie/type.h>
|
#include <mie/type.h>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <blue/core/hash.h>
|
#include <blue/core/hash.h>
|
||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/ir/arg.h>
|
#include <mie/ir/arg.h>
|
||||||
#include <mie/ir/block.h>
|
#include <mie/ir/block.h>
|
||||||
#include <mie/ir/func.h>
|
#include <mie/ir/func.h>
|
||||||
@@ -118,19 +118,26 @@ static void cleanup(struct mie_value *value)
|
|||||||
{
|
{
|
||||||
struct mie_func *func = MIE_FUNC(value);
|
struct mie_func *func = MIE_FUNC(value);
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&func->f_args);
|
||||||
b_queue_iterator_begin(&func->f_args, &it);
|
b_queue_entry *next = NULL;
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&func->f_args, entry);
|
||||||
|
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator_begin(&func->f_blocks, &it);
|
entry = b_queue_first(&func->f_blocks);
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&func->f_blocks, entry);
|
||||||
|
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
mie_name_map_destroy(func->f_names);
|
mie_name_map_destroy(func->f_names);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include <blue/object/hashmap.h>
|
#include <blue/ds/hashmap.h>
|
||||||
#include <mie/ir/const.h>
|
#include <mie/ir/const.h>
|
||||||
#include <mie/ir/data.h>
|
#include <mie/ir/data.h>
|
||||||
#include <mie/ir/func.h>
|
#include <mie/ir/func.h>
|
||||||
@@ -116,30 +116,36 @@ static void cleanup(struct mie_value *value)
|
|||||||
{
|
{
|
||||||
struct mie_module *module = MIE_MODULE(value);
|
struct mie_module *module = MIE_MODULE(value);
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&module->m_records);
|
||||||
b_queue_iterator_begin(&module->m_records, &it);
|
b_queue_entry *next = NULL;
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&module->m_records, entry);
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator_begin(&module->m_types, &it);
|
entry = b_queue_first(&module->m_types);
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&module->m_types, entry);
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_iterator_begin(&module->m_func, &it);
|
entry = b_queue_first(&module->m_func);
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
|
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
|
||||||
b_queue_iterator_erase(&it);
|
next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&module->m_func, entry);
|
||||||
mie_value_destroy(v);
|
mie_value_destroy(v);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
b_hashmap_release(module->m_data_strings);
|
b_hashmap_unref(module->m_data_strings);
|
||||||
b_hashmap_release(module->m_data);
|
b_hashmap_unref(module->m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct mie_value_type module_value_type = {
|
const struct mie_value_type module_value_type = {
|
||||||
|
|||||||
35
mie/name.c
35
mie/name.c
@@ -1,5 +1,5 @@
|
|||||||
#include <blue/core/rope.h>
|
#include <blue/core/rope.h>
|
||||||
#include <blue/object/string.h>
|
#include <blue/ds/string.h>
|
||||||
#include <mie/name.h>
|
#include <mie/name.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -25,11 +25,12 @@ static struct mie_name_bucket *create_bucket(void)
|
|||||||
|
|
||||||
static void destroy_bucket(struct mie_name_bucket *bucket)
|
static void destroy_bucket(struct mie_name_bucket *bucket)
|
||||||
{
|
{
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&bucket->b_names);
|
||||||
b_queue_iterator_begin(&bucket->b_names, &it);
|
|
||||||
|
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
while (entry) {
|
||||||
b_queue_iterator_erase(&it);
|
b_queue_entry *next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&bucket->b_names, entry);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(bucket);
|
free(bucket);
|
||||||
@@ -48,19 +49,20 @@ struct mie_name_map *mie_name_map_create(void)
|
|||||||
|
|
||||||
void mie_name_map_destroy(struct mie_name_map *map)
|
void mie_name_map_destroy(struct mie_name_map *map)
|
||||||
{
|
{
|
||||||
b_btree_iterator it;
|
b_btree_node *node = b_btree_first(&map->m_entries);
|
||||||
b_btree_iterator_begin(&map->m_entries, &it);
|
|
||||||
|
|
||||||
while (b_btree_iterator_is_valid(&it)) {
|
while (node) {
|
||||||
struct mie_name_map_entry *entry
|
struct mie_name_map_entry *entry
|
||||||
= b_unbox(struct mie_name_map_entry, it.node, e_node);
|
= b_unbox(struct mie_name_map_entry, node, e_node);
|
||||||
b_btree_iterator_erase(&it);
|
b_btree_node *next = b_btree_next(node);
|
||||||
|
b_btree_delete(&map->m_entries, node);
|
||||||
if (entry->e_type == MIE_NAME_MAP_E_BUCKET) {
|
if (entry->e_type == MIE_NAME_MAP_E_BUCKET) {
|
||||||
struct mie_name_bucket *bucket
|
struct mie_name_bucket *bucket
|
||||||
= (struct mie_name_bucket *)entry;
|
= (struct mie_name_bucket *)entry;
|
||||||
destroy_bucket(bucket);
|
destroy_bucket(bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(map);
|
free(map);
|
||||||
@@ -69,14 +71,17 @@ void mie_name_map_destroy(struct mie_name_map *map)
|
|||||||
static b_status put_name_in_bucket(
|
static b_status put_name_in_bucket(
|
||||||
struct mie_name_bucket *bucket, struct mie_name *name)
|
struct mie_name_bucket *bucket, struct mie_name *name)
|
||||||
{
|
{
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&bucket->b_names);
|
||||||
b_queue_foreach (&it, &bucket->b_names) {
|
|
||||||
|
while (entry) {
|
||||||
struct mie_name *cur = (struct mie_name *)b_unbox(
|
struct mie_name *cur = (struct mie_name *)b_unbox(
|
||||||
struct mie_name_map_entry, it.entry, e_entry);
|
struct mie_name_map_entry, entry, e_entry);
|
||||||
|
|
||||||
if (!strcmp(cur->n_str, name->n_str)) {
|
if (!strcmp(cur->n_str, name->n_str)) {
|
||||||
return B_ERR_NAME_EXISTS;
|
return B_ERR_NAME_EXISTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_push_back(&bucket->b_names, &name->n_base.e_entry);
|
b_queue_push_back(&bucket->b_names, &name->n_base.e_entry);
|
||||||
@@ -181,7 +186,7 @@ struct mie_name *mie_name_map_put(
|
|||||||
b_rope_to_cstr(&unique_name, str, sizeof str);
|
b_rope_to_cstr(&unique_name, str, sizeof str);
|
||||||
|
|
||||||
entry->n_str = str;
|
entry->n_str = str;
|
||||||
entry->n_base.e_hash = b_hash_string(str);
|
entry->n_base.e_hash = b_hash_cstr(str);
|
||||||
b_status status = put_name(map, entry);
|
b_status status = put_name(map, entry);
|
||||||
|
|
||||||
if (B_OK(status)) {
|
if (B_OK(status)) {
|
||||||
|
|||||||
@@ -50,8 +50,20 @@ DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
|
|||||||
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
|
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
|
||||||
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
|
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
|
||||||
DEFINE_PUSH_FUNCTION(div, MIE_SELECT_OP_DIV);
|
DEFINE_PUSH_FUNCTION(div, MIE_SELECT_OP_DIV);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_eq, MIE_SELECT_OP_CMP_EQ);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_neq, MIE_SELECT_OP_CMP_NEQ);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_lt, MIE_SELECT_OP_CMP_LT);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_gt, MIE_SELECT_OP_CMP_GT);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_leq, MIE_SELECT_OP_CMP_LEQ);
|
||||||
|
DEFINE_PUSH_FUNCTION(cmp_geq, MIE_SELECT_OP_CMP_GEQ);
|
||||||
|
|
||||||
DEFINE_OP(add);
|
DEFINE_OP(add);
|
||||||
DEFINE_OP(sub);
|
DEFINE_OP(sub);
|
||||||
DEFINE_OP(mul);
|
DEFINE_OP(mul);
|
||||||
DEFINE_OP(div);
|
DEFINE_OP(div);
|
||||||
|
DEFINE_OP(cmp_eq);
|
||||||
|
DEFINE_OP(cmp_neq);
|
||||||
|
DEFINE_OP(cmp_lt);
|
||||||
|
DEFINE_OP(cmp_gt);
|
||||||
|
DEFINE_OP(cmp_leq);
|
||||||
|
DEFINE_OP(cmp_geq);
|
||||||
|
|||||||
171
mie/select/br.c
Normal file
171
mie/select/br.c
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
#include "builder.h"
|
||||||
|
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/ir/branch.h>
|
||||||
|
#include <mie/select/graph.h>
|
||||||
|
#include <mie/select/node.h>
|
||||||
|
|
||||||
|
static enum mie_status get_block_node(
|
||||||
|
struct mie_select_builder *builder, struct mie_block *block,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_node *block_node = NULL;
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
struct mie_type *ptr_type = mie_ctx_get_type(
|
||||||
|
mie_select_builder_get_ctx(builder), MIE_TYPE_PTR);
|
||||||
|
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
graph, mie_target_builtin(), MIE_SELECT_OP_BLOCK, NULL, 0,
|
||||||
|
&ptr_type, 1, &block_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
block_node->n_value.v = MIE_VALUE(block);
|
||||||
|
block_node->n_flags |= MIE_SELECT_NODE_F_PVALUE;
|
||||||
|
|
||||||
|
return mie_select_node_get_value(block_node, ptr_type, 0, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status create_br_cond(
|
||||||
|
struct mie_select_builder *builder, struct mie_value *cond,
|
||||||
|
struct mie_select_value *incoming_chain, struct mie_block *dest_block,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
|
||||||
|
if (!incoming_chain || !incoming_chain->v_node) {
|
||||||
|
incoming_chain = mie_select_builder_get_mem_access(builder, cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!incoming_chain || !incoming_chain->v_node) {
|
||||||
|
incoming_chain = &graph->g_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value dest;
|
||||||
|
enum mie_status status = get_block_node(builder, dest_block, &dest);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
incoming_chain,
|
||||||
|
mie_select_builder_get_value(builder, cond),
|
||||||
|
&dest,
|
||||||
|
};
|
||||||
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_type *chain_type = mie_ctx_get_type(
|
||||||
|
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
|
||||||
|
|
||||||
|
struct mie_select_node *br_node = NULL;
|
||||||
|
|
||||||
|
status = mie_select_graph_get_node(
|
||||||
|
graph, mie_target_builtin(), MIE_SELECT_OP_BR_COND, operands,
|
||||||
|
nr_operands, &chain_type, 1, &br_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(br_node, chain_type, 0, out);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status create_br(
|
||||||
|
struct mie_select_builder *builder, struct mie_block *dest_block,
|
||||||
|
struct mie_select_value *incoming_chain, struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
if (!incoming_chain || !incoming_chain->v_node) {
|
||||||
|
incoming_chain = &graph->g_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value dest;
|
||||||
|
enum mie_status status = get_block_node(builder, dest_block, &dest);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value *operands[] = {
|
||||||
|
incoming_chain,
|
||||||
|
&dest,
|
||||||
|
};
|
||||||
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
|
struct mie_type *chain_type = mie_ctx_get_type(
|
||||||
|
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
|
||||||
|
|
||||||
|
struct mie_select_node *br_node = NULL;
|
||||||
|
|
||||||
|
status = mie_select_graph_get_node(
|
||||||
|
graph, mie_target_builtin(), MIE_SELECT_OP_BR, operands,
|
||||||
|
nr_operands, &chain_type, 1, &br_node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
mie_select_node_get_value(br_node, chain_type, 0, out);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status push_br(
|
||||||
|
struct mie_select_builder *builder, struct mie_instr *instr)
|
||||||
|
{
|
||||||
|
struct mie_branch *br = (struct mie_branch *)instr;
|
||||||
|
|
||||||
|
struct mie_select_value incoming_chain = {};
|
||||||
|
enum mie_status status = mie_select_builder_collapse_chain_ends(
|
||||||
|
builder, &incoming_chain);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value br_result;
|
||||||
|
status = create_br(builder, br->b_dest, &incoming_chain, &br_result);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &br_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum mie_status push_br_if(
|
||||||
|
struct mie_select_builder *builder, struct mie_instr *instr)
|
||||||
|
{
|
||||||
|
struct mie_branch_if *br = (struct mie_branch_if *)instr;
|
||||||
|
|
||||||
|
struct mie_select_value incoming_chain = {};
|
||||||
|
enum mie_status status = mie_select_builder_collapse_chain_ends(
|
||||||
|
builder, &incoming_chain);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_value br_true_result, br_false_result;
|
||||||
|
status = create_br_cond(
|
||||||
|
builder, br->b_cond, &incoming_chain, br->b_true_block,
|
||||||
|
&br_true_result);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = create_br(
|
||||||
|
builder, br->b_false_block, &br_true_result, &br_false_result);
|
||||||
|
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mie_select_builder_set_value(
|
||||||
|
builder, MIE_VALUE(instr), &br_false_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct select_instr_type select_br = {
|
||||||
|
.i_push = push_br,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct select_instr_type select_br_if = {
|
||||||
|
.i_push = push_br_if,
|
||||||
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
|
|
||||||
#include <blue/object/hashmap.h>
|
#include <blue/ds/hashmap.h>
|
||||||
#include <mie/ctx.h>
|
#include <mie/ctx.h>
|
||||||
#include <mie/ir/const.h>
|
#include <mie/ir/const.h>
|
||||||
#include <mie/ir/data.h>
|
#include <mie/ir/data.h>
|
||||||
@@ -51,7 +51,7 @@ struct mie_select_builder *mie_select_builder_create(
|
|||||||
|
|
||||||
out->b_mem_access = b_hashmap_create(NULL, NULL);
|
out->b_mem_access = b_hashmap_create(NULL, NULL);
|
||||||
if (!out->b_mem_access) {
|
if (!out->b_mem_access) {
|
||||||
b_hashmap_release(out->b_nodes);
|
b_hashmap_unref(out->b_nodes);
|
||||||
mie_select_graph_destroy(out->b_graph);
|
mie_select_graph_destroy(out->b_graph);
|
||||||
free(out);
|
free(out);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -63,11 +63,11 @@ struct mie_select_builder *mie_select_builder_create(
|
|||||||
void mie_select_builder_destroy(struct mie_select_builder *builder)
|
void mie_select_builder_destroy(struct mie_select_builder *builder)
|
||||||
{
|
{
|
||||||
if (builder->b_nodes) {
|
if (builder->b_nodes) {
|
||||||
b_hashmap_release(builder->b_nodes);
|
b_hashmap_unref(builder->b_nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builder->b_mem_access) {
|
if (builder->b_mem_access) {
|
||||||
b_hashmap_release(builder->b_mem_access);
|
b_hashmap_unref(builder->b_mem_access);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builder->b_graph) {
|
if (builder->b_graph) {
|
||||||
@@ -94,16 +94,6 @@ const struct mie_target *mie_select_builder_get_target(
|
|||||||
return builder->b_target;
|
return builder->b_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_node_map(struct mie_select_builder *builder)
|
|
||||||
{
|
|
||||||
b_hashmap_iterator it;
|
|
||||||
b_hashmap_iterator_begin(builder->b_nodes, &it);
|
|
||||||
while (b_hashmap_iterator_is_valid(&it)) {
|
|
||||||
free(it.value->value_data);
|
|
||||||
b_hashmap_iterator_erase(&it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *builder)
|
struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *builder)
|
||||||
{
|
{
|
||||||
enum mie_status status = MIE_SUCCESS;
|
enum mie_status status = MIE_SUCCESS;
|
||||||
@@ -114,8 +104,14 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
|
|||||||
};
|
};
|
||||||
size_t nr_root_operands = 0;
|
size_t nr_root_operands = 0;
|
||||||
|
|
||||||
if (graph->g_last_chain.v_node) {
|
struct mie_select_value incoming_chain = {};
|
||||||
root_operands[0] = &graph->g_last_chain;
|
status = mie_select_builder_collapse_chain_ends(builder, &incoming_chain);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (incoming_chain.v_node) {
|
||||||
|
root_operands[0] = &incoming_chain;
|
||||||
nr_root_operands++;
|
nr_root_operands++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,9 +123,13 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_node_map(builder);
|
b_hashmap_unref(builder->b_nodes);
|
||||||
|
builder->b_nodes = b_hashmap_create(NULL, NULL);
|
||||||
|
|
||||||
builder->b_graph = NULL;
|
b_hashmap_unref(builder->b_mem_access);
|
||||||
|
builder->b_mem_access = b_hashmap_create(NULL, NULL);
|
||||||
|
|
||||||
|
builder->b_graph = mie_select_graph_create(builder->b_ctx);
|
||||||
|
|
||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
@@ -142,28 +142,30 @@ enum mie_status mie_select_builder_get_const(
|
|||||||
struct mie_type *ctype = mie_ctx_get_int_type(builder->b_ctx, 32);
|
struct mie_type *ctype = mie_ctx_get_int_type(builder->b_ctx, 32);
|
||||||
struct mie_select_node *node = NULL;
|
struct mie_select_node *node = NULL;
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&builder->b_graph->g_nodes);
|
||||||
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
|
while (entry) {
|
||||||
node = b_unbox(struct mie_select_node, it.entry, n_entry);
|
node = b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
|
|
||||||
if (node->n_target != builtin) {
|
if (node->n_target != builtin) {
|
||||||
continue;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_opcode != MIE_SELECT_OP_CONSTANT) {
|
if (node->n_opcode != MIE_SELECT_OP_CONSTANT) {
|
||||||
continue;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(node->n_flags & MIE_SELECT_NODE_F_IVALUE)) {
|
if (!(node->n_flags & MIE_SELECT_NODE_F_IVALUE)) {
|
||||||
continue;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_value.i != value) {
|
if (node->n_value.i != value) {
|
||||||
continue;
|
goto skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
mie_select_node_get_value(node, ctype, 0, out);
|
mie_select_node_get_value(node, ctype, 0, out);
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
|
skip:
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
@@ -247,6 +249,32 @@ static enum mie_status get_data_node(
|
|||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum mie_status get_external_value_node(
|
||||||
|
struct mie_select_builder *builder, struct mie_value *ir_val,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
struct mie_type *type = mie_value_get_type(ir_val, builder->b_ctx);
|
||||||
|
|
||||||
|
if (!type) {
|
||||||
|
return MIE_ERR_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_node *node;
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_REGISTER,
|
||||||
|
NULL, 0, &type, 1, &node);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
|
||||||
|
node->n_value.v = ir_val;
|
||||||
|
|
||||||
|
mie_select_node_get_value(node, type, 0, out);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_select_value *mie_select_builder_get_value(
|
struct mie_select_value *mie_select_builder_get_value(
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val)
|
struct mie_select_builder *builder, struct mie_value *ir_val)
|
||||||
{
|
{
|
||||||
@@ -276,6 +304,7 @@ struct mie_select_value *mie_select_builder_get_value(
|
|||||||
status = get_data_node(builder, ir_val, select_val);
|
status = get_data_node(builder, ir_val, select_val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
status = get_external_value_node(builder, ir_val, select_val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,19 +393,92 @@ enum mie_status mie_select_builder_set_mem_access(
|
|||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_select_builder_collapse_chain_ends(
|
||||||
|
struct mie_select_builder *builder, struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
size_t nr_chains = b_queue_length(&builder->b_graph->g_chain_ends);
|
||||||
|
b_queue_entry *entry = NULL;
|
||||||
|
struct mie_select_chain_end *end = NULL;
|
||||||
|
|
||||||
|
switch (nr_chains) {
|
||||||
|
case 0:
|
||||||
|
memset(out, 0x0, sizeof *out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
case 1:
|
||||||
|
entry = b_queue_first(&builder->b_graph->g_chain_ends);
|
||||||
|
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
|
||||||
|
memcpy(out, end, sizeof *out);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_type *chain_type
|
||||||
|
= mie_ctx_get_type(builder->b_ctx, MIE_TYPE_OTHER);
|
||||||
|
|
||||||
|
struct mie_select_value **operands = calloc(nr_chains, sizeof *operands);
|
||||||
|
if (!operands) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = b_queue_first(&builder->b_graph->g_chain_ends);
|
||||||
|
size_t i = 0;
|
||||||
|
while (entry) {
|
||||||
|
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
|
||||||
|
operands[i++] = &end->c_value;
|
||||||
|
entry = b_queue_next(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_node *group = NULL;
|
||||||
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
|
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_CHAIN_GROUP,
|
||||||
|
operands, nr_chains, &chain_type, 1, &group);
|
||||||
|
free(operands);
|
||||||
|
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = b_queue_first(&builder->b_graph->g_chain_ends);
|
||||||
|
while (entry) {
|
||||||
|
end = b_unbox(struct mie_select_chain_end, entry, c_entry);
|
||||||
|
b_queue_entry *next = b_queue_next(entry);
|
||||||
|
|
||||||
|
b_queue_delete(&builder->b_graph->g_chain_ends, entry);
|
||||||
|
free(end);
|
||||||
|
|
||||||
|
entry = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_chain_end *group_end = malloc(sizeof *group_end);
|
||||||
|
if (!group_end) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(group_end, 0x0, sizeof *group_end);
|
||||||
|
|
||||||
|
mie_select_node_get_value(group, chain_type, 0, &group_end->c_value);
|
||||||
|
b_queue_push_back(&builder->b_graph->g_chain_ends, &group_end->c_entry);
|
||||||
|
*out = group_end->c_value;
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_select_node *mie_select_builder_find_node_with_ivalue(
|
struct mie_select_node *mie_select_builder_find_node_with_ivalue(
|
||||||
struct mie_select_builder *builder, const struct mie_target *target,
|
struct mie_select_builder *builder, const struct mie_target *target,
|
||||||
unsigned int opcode, long long val)
|
unsigned int opcode, long long val)
|
||||||
{
|
{
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&builder->b_graph->g_nodes);
|
||||||
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
|
while (entry) {
|
||||||
struct mie_select_node *node
|
struct mie_select_node *node
|
||||||
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
|
|
||||||
if (node->n_target == target && node->n_opcode == opcode
|
if (node->n_target == target && node->n_opcode == opcode
|
||||||
&& node->n_value.i == val) {
|
&& node->n_value.i == val) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ static b_status write_operand_const(struct mie_value *value, b_stream *out)
|
|||||||
static void write_operand(struct mie_value *value, b_stream *out)
|
static void write_operand(struct mie_value *value, b_stream *out)
|
||||||
{
|
{
|
||||||
if (!value) {
|
if (!value) {
|
||||||
b_stream_write_fmt(out, NULL, "<null>");
|
b_stream_write_fmt(out, NULL, "null");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ static void write_operand(struct mie_value *value, b_stream *out)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
b_stream_write_fmt(
|
b_stream_write_fmt(
|
||||||
out, NULL, "<unknown-value:%d>", value->v_type->t_id);
|
out, NULL, "unknown-value:%d", value->v_type->t_id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -245,17 +245,18 @@ static void node_links_dump_dot(struct mie_select_node *node, b_stream *out)
|
|||||||
|
|
||||||
void mie_select_graph_dump_text(struct mie_select_graph *graph)
|
void mie_select_graph_dump_text(struct mie_select_graph *graph)
|
||||||
{
|
{
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
|
||||||
b_queue_foreach (&it, &graph->g_nodes) {
|
while (entry) {
|
||||||
struct mie_select_node *node
|
struct mie_select_node *node
|
||||||
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
node_dump_text(node);
|
node_dump_text(node);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mie_select_graph_dump_dot(struct mie_select_graph *graph)
|
void mie_select_graph_dump_dot(struct mie_select_graph *graph, const char *filename)
|
||||||
{
|
{
|
||||||
FILE *fp = fopen("graph.dot", "w");
|
FILE *fp = fopen(filename, "w");
|
||||||
|
|
||||||
b_stream *tmpstream = b_stream_open_fp(fp);
|
b_stream *tmpstream = b_stream_open_fp(fp);
|
||||||
|
|
||||||
@@ -263,24 +264,29 @@ void mie_select_graph_dump_dot(struct mie_select_graph *graph)
|
|||||||
b_stream_write_string(tmpstream, "\tnode [shape=Mrecord];\n", NULL);
|
b_stream_write_string(tmpstream, "\tnode [shape=Mrecord];\n", NULL);
|
||||||
b_stream_write_string(tmpstream, "\trankdir=\"BT\";\n", NULL);
|
b_stream_write_string(tmpstream, "\trankdir=\"BT\";\n", NULL);
|
||||||
|
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
|
||||||
b_queue_foreach (&it, &graph->g_nodes) {
|
while (entry) {
|
||||||
struct mie_select_node *node
|
struct mie_select_node *node
|
||||||
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
node_dump_dot(node, tmpstream);
|
node_dump_dot(node, tmpstream);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_queue_foreach (&it, &graph->g_nodes) {
|
entry = b_queue_first(&graph->g_nodes);
|
||||||
|
while (entry) {
|
||||||
struct mie_select_node *node
|
struct mie_select_node *node
|
||||||
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
node_links_dump_dot(node, tmpstream);
|
node_links_dump_dot(node, tmpstream);
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
b_stream_write_string(tmpstream, "}\n", NULL);
|
b_stream_write_string(tmpstream, "}\n", NULL);
|
||||||
|
|
||||||
b_stream_close(tmpstream);
|
b_stream_unref(tmpstream);
|
||||||
|
|
||||||
system("open graph.dot");
|
char cmd[256];
|
||||||
|
snprintf(cmd, sizeof cmd, "open %s", filename);
|
||||||
|
system(cmd);
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,12 +42,12 @@ struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx)
|
|||||||
|
|
||||||
void mie_select_graph_destroy(struct mie_select_graph *graph)
|
void mie_select_graph_destroy(struct mie_select_graph *graph)
|
||||||
{
|
{
|
||||||
b_queue_iterator it;
|
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
|
||||||
b_queue_iterator_begin(&graph->g_nodes, &it);
|
while (entry) {
|
||||||
while (b_queue_iterator_is_valid(&it)) {
|
|
||||||
struct mie_select_node *node
|
struct mie_select_node *node
|
||||||
= b_unbox(struct mie_select_node, it.entry, n_entry);
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
||||||
b_queue_iterator_erase(&it);
|
b_queue_entry *next = b_queue_next(entry);
|
||||||
|
b_queue_delete(&graph->g_nodes, entry);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (node->n_value) {
|
if (node->n_value) {
|
||||||
@@ -56,11 +56,49 @@ void mie_select_graph_destroy(struct mie_select_graph *graph)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(node);
|
free(node);
|
||||||
|
entry = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(graph);
|
free(graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum mie_status update_chain_ends(
|
||||||
|
struct mie_select_graph *graph, struct mie_select_value *new_chain)
|
||||||
|
{
|
||||||
|
struct mie_select_node *new_node = new_chain->v_node;
|
||||||
|
|
||||||
|
b_queue_entry *entry = b_queue_first(&graph->g_chain_ends);
|
||||||
|
while (entry) {
|
||||||
|
struct mie_select_chain_end *end
|
||||||
|
= b_unbox(struct mie_select_chain_end, entry, c_entry);
|
||||||
|
struct mie_select_node *value_node = end->c_value.v_node;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < new_node->n_nr_operands; i++) {
|
||||||
|
struct mie_select_node *operand_node
|
||||||
|
= new_node->n_operands[i].u_value.v_node;
|
||||||
|
|
||||||
|
if (value_node == operand_node) {
|
||||||
|
memcpy(&end->c_value, new_chain, sizeof *new_chain);
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mie_select_chain_end *end = malloc(sizeof *end);
|
||||||
|
if (!end) {
|
||||||
|
return MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(end, 0x0, sizeof *end);
|
||||||
|
memcpy(&end->c_value, new_chain, sizeof *new_chain);
|
||||||
|
|
||||||
|
b_queue_push_back(&graph->g_chain_ends, &end->c_entry);
|
||||||
|
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
enum mie_status mie_select_graph_get_node(
|
enum mie_status mie_select_graph_get_node(
|
||||||
struct mie_select_graph *graph, const struct mie_target *target,
|
struct mie_select_graph *graph, const struct mie_target *target,
|
||||||
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
||||||
@@ -86,9 +124,18 @@ enum mie_status mie_select_graph_get_node(
|
|||||||
node->n_target = target;
|
node->n_target = target;
|
||||||
|
|
||||||
for (size_t i = 0; i < nr_values; i++) {
|
for (size_t i = 0; i < nr_values; i++) {
|
||||||
if (values[i]->t_id == MIE_TYPE_OTHER) {
|
if (values[i]->t_id != MIE_TYPE_OTHER) {
|
||||||
graph->g_last_chain.v_node = node;
|
continue;
|
||||||
graph->g_last_chain.v_index = i;
|
}
|
||||||
|
|
||||||
|
struct mie_select_value chain = {
|
||||||
|
.v_node = node,
|
||||||
|
.v_index = i,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum mie_status status = update_chain_ends(graph, &chain);
|
||||||
|
if (status != MIE_SUCCESS) {
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,15 +11,27 @@ DECLARE_INSTR_TYPE(add);
|
|||||||
DECLARE_INSTR_TYPE(sub);
|
DECLARE_INSTR_TYPE(sub);
|
||||||
DECLARE_INSTR_TYPE(mul);
|
DECLARE_INSTR_TYPE(mul);
|
||||||
DECLARE_INSTR_TYPE(div);
|
DECLARE_INSTR_TYPE(div);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_eq);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_neq);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_lt);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_gt);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_leq);
|
||||||
|
DECLARE_INSTR_TYPE(cmp_geq);
|
||||||
DECLARE_INSTR_TYPE(load);
|
DECLARE_INSTR_TYPE(load);
|
||||||
DECLARE_INSTR_TYPE(store);
|
DECLARE_INSTR_TYPE(store);
|
||||||
DECLARE_INSTR_TYPE(msg);
|
DECLARE_INSTR_TYPE(msg);
|
||||||
|
DECLARE_INSTR_TYPE(br);
|
||||||
|
DECLARE_INSTR_TYPE(br_if);
|
||||||
|
|
||||||
static const struct select_instr_type *instr_types[] = {
|
static const struct select_instr_type *instr_types[] = {
|
||||||
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
|
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(LOAD, load),
|
||||||
INSTR_TYPE_ENTRY(SUB, sub), INSTR_TYPE_ENTRY(MUL, mul),
|
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
|
||||||
INSTR_TYPE_ENTRY(DIV, div), INSTR_TYPE_ENTRY(LOAD, load),
|
INSTR_TYPE_ENTRY(BR, br), INSTR_TYPE_ENTRY(BR_IF, br_if),
|
||||||
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
|
INSTR_TYPE_ENTRY(ADD, add), INSTR_TYPE_ENTRY(SUB, sub),
|
||||||
|
INSTR_TYPE_ENTRY(MUL, mul), INSTR_TYPE_ENTRY(DIV, div),
|
||||||
|
INSTR_TYPE_ENTRY(CMP_EQ, cmp_eq), INSTR_TYPE_ENTRY(CMP_NEQ, cmp_neq),
|
||||||
|
INSTR_TYPE_ENTRY(CMP_LT, cmp_lt), INSTR_TYPE_ENTRY(CMP_GT, cmp_gt),
|
||||||
|
INSTR_TYPE_ENTRY(CMP_LEQ, cmp_leq), INSTR_TYPE_ENTRY(CMP_GEQ, cmp_geq),
|
||||||
};
|
};
|
||||||
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];
|
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const struct select_node_type *select_type_for_node(enum mie_select_opcode node)
|
|||||||
return node_types[node];
|
return node_types[node];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
void mie_select_node_iterator_next(struct mie_select_node_iterator *it)
|
void mie_select_node_iterator_next(struct mie_select_node_iterator *it)
|
||||||
{
|
{
|
||||||
b_queue_iterator_next(&it->it_base);
|
b_queue_iterator_next(&it->it_base);
|
||||||
@@ -31,6 +32,7 @@ bool mie_select_node_iterator_is_valid(const struct mie_select_node_iterator *it
|
|||||||
{
|
{
|
||||||
return b_queue_iterator_is_valid(&it->it_base);
|
return b_queue_iterator_is_valid(&it->it_base);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
struct mie_select_node *mie_select_node_create(
|
struct mie_select_node *mie_select_node_create(
|
||||||
const struct mie_target *target, unsigned int op,
|
const struct mie_target *target, unsigned int op,
|
||||||
@@ -101,13 +103,16 @@ enum mie_status mie_select_node_set_operands(
|
|||||||
|
|
||||||
enum mie_status mie_select_node_clear_operands(struct mie_select_node *node)
|
enum mie_status mie_select_node_clear_operands(struct mie_select_node *node)
|
||||||
{
|
{
|
||||||
struct mie_select_use_iterator it;
|
b_queue_entry *entry = b_queue_first(&node->n_use);
|
||||||
mie_select_use_foreach(&it, &node->n_use)
|
while (entry) {
|
||||||
{
|
|
||||||
struct mie_select_use *use = mie_select_use_iterator_unbox(&it);
|
struct mie_select_use *use
|
||||||
|
= b_unbox(struct mie_select_use, entry, u_entry);
|
||||||
if (use->u_value.v_node == node) {
|
if (use->u_value.v_node == node) {
|
||||||
memset(&use->u_value, 0x0, sizeof use->u_value);
|
memset(&use->u_value, 0x0, sizeof use->u_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entry = b_queue_next(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_operands) {
|
if (node->n_operands) {
|
||||||
@@ -158,12 +163,12 @@ enum mie_status mie_select_node_set_description(
|
|||||||
{
|
{
|
||||||
va_list arg;
|
va_list arg;
|
||||||
va_start(arg, format);
|
va_start(arg, format);
|
||||||
b_stringstream str;
|
b_stringstream *str = b_stringstream_create();
|
||||||
b_stringstream_begin_dynamic(&str);
|
b_stream_write_vfmt(str, NULL, format, arg);
|
||||||
b_stringstream_addvf(&str, format, arg);
|
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
|
|
||||||
node->n_description = b_stringstream_end(&str);
|
node->n_description = b_stringstream_steal(str);
|
||||||
|
b_stringstream_unref(str);
|
||||||
return node->n_description ? MIE_SUCCESS : MIE_ERR_NO_MEMORY;
|
return node->n_description ? MIE_SUCCESS : MIE_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ static size_t node_name(
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
NODE_NAME(ENTRY, "Entry");
|
NODE_NAME(ENTRY, "Entry");
|
||||||
NODE_NAME(ROOT, "Root");
|
NODE_NAME(ROOT, "Root");
|
||||||
NODE_NAME(BLOCK, "Root");
|
NODE_NAME(BLOCK, "Block");
|
||||||
NODE_NAME(CONSTANT, "Constant");
|
NODE_NAME(CONSTANT, "Constant");
|
||||||
NODE_NAME(FRAME_INDEX, "FrameIndex");
|
NODE_NAME(FRAME_INDEX, "FrameIndex");
|
||||||
NODE_NAME(REGISTER, "Register");
|
NODE_NAME(REGISTER, "Register");
|
||||||
@@ -27,6 +27,12 @@ static size_t node_name(
|
|||||||
NODE_NAME(SUB, "Sub");
|
NODE_NAME(SUB, "Sub");
|
||||||
NODE_NAME(MUL, "Mul");
|
NODE_NAME(MUL, "Mul");
|
||||||
NODE_NAME(DIV, "Div");
|
NODE_NAME(DIV, "Div");
|
||||||
|
NODE_NAME(CMP_EQ, "Cmp.Eq");
|
||||||
|
NODE_NAME(CMP_NEQ, "Cmp.Neq");
|
||||||
|
NODE_NAME(CMP_LT, "Cmp.Lt");
|
||||||
|
NODE_NAME(CMP_GT, "Cmp.Gt");
|
||||||
|
NODE_NAME(CMP_LEQ, "Cmp.Leq");
|
||||||
|
NODE_NAME(CMP_GEQ, "Cmp.Geq");
|
||||||
NODE_NAME(XOR, "Xor");
|
NODE_NAME(XOR, "Xor");
|
||||||
NODE_NAME(BR, "Branch");
|
NODE_NAME(BR, "Branch");
|
||||||
NODE_NAME(BR_COND, "CondBranch");
|
NODE_NAME(BR_COND, "CondBranch");
|
||||||
|
|||||||
18
tool/CMakeLists.txt
Normal file
18
tool/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
file(GLOB tool_sources
|
||||||
|
*.c *.h
|
||||||
|
cmd/*.c cmd/*.h)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(rc_file ${CMAKE_CURRENT_SOURCE_DIR}/../res/win32/frontend.rc)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
add_executable(mie-tool ${tool_sources} ${rc_file})
|
||||||
|
target_link_libraries(
|
||||||
|
mie-tool
|
||||||
|
mie
|
||||||
|
Bluelib::Core
|
||||||
|
Bluelib::Ds
|
||||||
|
Bluelib::Cmd)
|
||||||
|
|
||||||
|
set_target_properties(mie-tool PROPERTIES OUTPUT_NAME "mie")
|
||||||
|
target_compile_definitions(mie-tool PRIVATE MIE_STATIC=${MIE_STATIC})
|
||||||
10
tool/cmd/cmd.h
Normal file
10
tool/cmd/cmd.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CMD_CMD_H_
|
||||||
|
#define CMD_CMD_H_
|
||||||
|
|
||||||
|
enum command_id {
|
||||||
|
CMD_ROOT,
|
||||||
|
CMD_VALIDATE,
|
||||||
|
CMD_INTERNAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
50
tool/cmd/internal.c
Normal file
50
tool/cmd/internal.c
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include "cmd.h"
|
||||||
|
#include <blue/cmd.h>
|
||||||
|
#include <blue/term.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPT_PRINT_SYMBOLS = 0x1000,
|
||||||
|
OPT_PRINT_KEYWORDS,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int internal(const b_command* cmd, const b_arglist* args, const b_array* _)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (b_arglist_get_count(args, OPT_PRINT_SYMBOLS, B_COMMAND_INVALID_ID)) {
|
||||||
|
internal_lexer_print_symbol_tree(lex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b_arglist_get_count(args, OPT_PRINT_KEYWORDS, B_COMMAND_INVALID_ID)) {
|
||||||
|
internal_lexer_print_keyword_dict(lex);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
B_COMMAND(CMD_INTERNAL, CMD_ROOT)
|
||||||
|
{
|
||||||
|
B_COMMAND_NAME("internal");
|
||||||
|
B_COMMAND_SHORT_NAME('X');
|
||||||
|
B_COMMAND_DESC("internal frontend debugging tools.");
|
||||||
|
B_COMMAND_FUNCTION(internal);
|
||||||
|
|
||||||
|
B_COMMAND_OPTION(OPT_PRINT_SYMBOLS)
|
||||||
|
{
|
||||||
|
B_OPTION_LONG_NAME("print-symbols");
|
||||||
|
B_OPTION_SHORT_NAME('s');
|
||||||
|
B_OPTION_DESC(
|
||||||
|
"print the symbol tree used by the language lexer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
B_COMMAND_OPTION(OPT_PRINT_KEYWORDS)
|
||||||
|
{
|
||||||
|
B_OPTION_LONG_NAME("print-keywords");
|
||||||
|
B_OPTION_SHORT_NAME('k');
|
||||||
|
B_OPTION_DESC(
|
||||||
|
"print the keyword dictionary used by the language lexer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
B_COMMAND_HELP_OPTION();
|
||||||
|
}
|
||||||
18
tool/cmd/root.c
Normal file
18
tool/cmd/root.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
|
#include <blue/cmd.h>
|
||||||
|
|
||||||
|
B_COMMAND(CMD_ROOT, B_COMMAND_INVALID_ID)
|
||||||
|
{
|
||||||
|
B_COMMAND_NAME("mie");
|
||||||
|
B_COMMAND_DESC("Mie IR manipulation tool.");
|
||||||
|
B_COMMAND_HELP_OPTION();
|
||||||
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||||
|
|
||||||
|
B_COMMAND_USAGE()
|
||||||
|
{
|
||||||
|
B_COMMAND_USAGE_COMMAND_PLACEHOLDER();
|
||||||
|
B_COMMAND_USAGE_OPT_PLACEHOLDER();
|
||||||
|
B_COMMAND_USAGE_ARG_PLACEHOLDER();
|
||||||
|
}
|
||||||
|
}
|
||||||
29
tool/cmd/validate.c
Normal file
29
tool/cmd/validate.c
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#include "cmd.h"
|
||||||
|
|
||||||
|
#include <blue/cmd.h>
|
||||||
|
#include <blue/term.h>
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/ir/convert.h>
|
||||||
|
#include <mie/ir/value.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
enum {
|
||||||
|
OPT_TEMP,
|
||||||
|
};
|
||||||
|
|
||||||
|
int validate(const b_command* cmd, const b_arglist* args, const b_array* _)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
B_COMMAND(CMD_VALIDATE, CMD_ROOT)
|
||||||
|
{
|
||||||
|
B_COMMAND_NAME("validate");
|
||||||
|
B_COMMAND_SHORT_NAME('V');
|
||||||
|
B_COMMAND_DESC("validate a mie ir file.");
|
||||||
|
B_COMMAND_HELP_OPTION();
|
||||||
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||||
|
B_COMMAND_FUNCTION(validate);
|
||||||
|
}
|
||||||
8
tool/main.c
Normal file
8
tool/main.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "cmd/cmd.h"
|
||||||
|
|
||||||
|
#include <blue/cmd.h>
|
||||||
|
|
||||||
|
int main(int argc, const char **argv)
|
||||||
|
{
|
||||||
|
return b_command_dispatch(CMD_ROOT, argc, argv);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user