Compare commits

...

10 Commits

42 changed files with 1494 additions and 234 deletions

331
.gitignore vendored Normal file
View 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
View 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
View 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
View File

@@ -0,0 +1,41 @@
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

14
doc/sample/for-loop-1.mie Normal file
View 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
View 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
View 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
View 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

View File

@@ -4,37 +4,45 @@ endif
let s:save_cpo = &cpoptions
set cpoptions&vim
setlocal iskeyword+=-
syn keyword mieUnspecifiedStatement record data define type global
syn keyword mieInstruction
\ alloca load store call br cmp
\ add sub div mul msg
\ getelementptr switch ret
syn keyword mieUnspecifiedKeyword to step iter-args
syn keyword mieInstructionFlag
\ eq gt ge lt le
syn match mieRegister "%[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 mieLabel /\(\w\+\)\(\.\(\w\+\)\)*\:/
syn keyword mieType id ptr str atom label void
syn keyword mieTypeModifier external
syn match mieType "i[0-9]\>"
syn match mieType "i[1-9][0-9]\+\>"
syn keyword mieBlockType lambda instance static class
syn match mieBlockIdentifier /\^\(\w\+\)\(\.\(\w\+\)\)*/
syn match mieBlockLabel /\^\(\w\+\)\(\.\(\w\+\)\)*\:/
syn keyword mieBuiltinType void index
syn keyword mieBuiltinType f16 f32 f64 f80 f128
" Use syn match for type names that are ALSO dialect names, to ensure that
" 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 mieFieldIndex /#-[0-9]\+:\>/
syn match mieFieldIndex /#0x[:xdigit:]\+:\>/
syn match mieFieldIndex /#-0x[:xdigit:]\+:\>/
syn match mieCustomOperation /\<[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\>/
syn match mieGenericOperation /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieAttributeName /\<[A-Za-z][A-Za-z0-9\-_\.]*\(\s*=\)\@=\>/
syn region mieString start=+"+ end=+"\%(u8\)\=+ end=+$+ extend
syn match mieInteger /#[0-9]\+\>/
syn match mieInteger /#-[0-9]\+\>/
syn match mieInteger /#0x[:xdigit:]\+\>/
syn match mieInteger /#-0x[:xdigit:]\+\>/
syn match mieFloat /[0-9]\+\.[0-9]\+/
syn match mieFloat /-[0-9]\+\.[0-9]\+/
syn match mieFloat /+[0-9]\+\.[0-9]\+/
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 region mieBlockComment start="/\*" end="\*/" contains=mieTodo,mieBlockComment
@@ -43,33 +51,39 @@ syn cluster mieComment contains=mieLineComment,mieBlockComment
syn match mieBrackets "[[\]]" 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
" The default highlighting.
hi def link mieUnspecifiedStatement Statement
hi def link mieUnspecifiedKeyword Keyword
hi def link ivyPropertySymbol Statement
hi def link mieInteger Number
hi def link mieFloat Number
hi def link mieParens Delimiter
hi def link mieBraces Structure
hi def link mieBrackets Delimiter
hi def link mieAngleBrackets StorageClass
hi def link miePropertyName @property
hi def link mieFieldName @variable.parameter
hi def link mieClassName Type
hi def link mieLambdaName @variable.parameter
hi def link mieDialectType Type
hi def link mieInstruction Function
hi def link mieGenericOperation @function.builtin
hi def link mieCustomOperation Function
hi def link mieInstructionFlag StorageClass
hi def link mieIdentifier Identifier
hi def link mieLabel Tag
hi def link mieIndexBase @variable.builtin
hi def link mieRegister Constant
hi def link mieBlockIdentifier Label
hi def link mieBlockLabel Label
hi def link mieRegister @variable
hi def link mieString String
hi def link mieType Type
hi def link mieBuiltinType @type.builtin
hi def link mieBlockType @attribute
hi def link mieTypeModifier @attribute
hi def link mieAttributeName @property
hi def link mieComment Comment
hi def link mieLineComment mieComment

View File

@@ -11,5 +11,5 @@ else ()
endif ()
target_include_directories(mie PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include/)
target_link_libraries(mie Bluelib::Core Bluelib::Object)
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${IVY_STATIC})
target_link_libraries(mie Bluelib::Core Bluelib::Ds)
target_compile_definitions(mie PRIVATE MIE_EXPORT=1 MIE_STATIC=${MIE_STATIC})

View File

@@ -1,6 +1,6 @@
#include <blue/object/hashmap.h>
#include <blue/object/list.h>
#include <blue/object/string.h>
#include <blue/ds/hashmap.h>
#include <blue/ds/list.h>
#include <blue/ds/string.h>
#include <mie/ctx.h>
#include <mie/ir/const.h>
#include <stdlib.h>
@@ -62,23 +62,25 @@ void mie_ctx_destroy(struct mie_ctx *ctx)
ctx->ctx_true = NULL;
ctx->ctx_false = NULL;
b_btree_iterator it = {};
b_btree_iterator_begin(&ctx->ctx_int_cache, &it);
while (b_btree_iterator_is_valid(&it)) {
b_btree_node *node = b_btree_first(&ctx->ctx_int_cache);
while (node) {
struct ctx_int_cache_entry *entry
= b_unbox(struct ctx_int_cache_entry, it.node, i_node);
b_btree_iterator_erase(&it);
= b_unbox(struct ctx_int_cache_entry, node, i_node);
b_btree_node *next = b_btree_next(node);
b_btree_delete(&ctx->ctx_int_cache, node);
b_btree_iterator it2 = {};
b_btree_iterator_begin(&entry->i_values, &it2);
while (b_btree_iterator_is_valid(&it2)) {
b_btree_node *node2 = b_btree_first(&entry->i_values);
while (node2) {
struct ctx_int_value_cache_entry *value = b_unbox(
struct ctx_int_value_cache_entry, it2.node, i_node);
b_btree_iterator_erase(&it2);
struct ctx_int_value_cache_entry, node2, i_node);
b_btree_node *next2 = b_btree_next(node2);
b_btree_delete(&entry->i_values, node2);
free(value);
node2 = next2;
}
free(entry);
node = next;
}
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);
}
b_hashmap_release(ctx->ctx_sel_cache);
b_hashmap_unref(ctx->ctx_sel_cache);
free(ctx);
}

View File

@@ -2,6 +2,7 @@
#define MIE_CTX_H_
#include <blue/core/btree.h>
#include <blue/ds/hashmap.h>
#include <mie/type.h>
struct mie_ctx {
@@ -9,8 +10,8 @@ struct mie_ctx {
struct mie_value *ctx_null;
struct mie_type *ctx_types[__MIE_TYPE_COUNT];
b_btree ctx_int_cache;
struct b_hashmap *ctx_sel_cache;
struct b_hashmap *ctx_string_cache;
b_hashmap *ctx_sel_cache;
b_hashmap *ctx_string_cache;
};
extern struct mie_ctx *mie_ctx_create(void);

View File

@@ -1,6 +1,7 @@
#ifndef MIE_CONST_H_
#define MIE_CONST_H_
#include <blue/ds/list.h>
#include <mie/ir/value.h>
#include <mie/type.h>
@@ -13,8 +14,6 @@
#define MIE_SELECTOR(p) ((struct mie_selector *)(p))
#define MIE_ARRAY(p) ((struct mie_array *)(p))
struct b_list;
struct mie_const {
struct mie_value c_base;
struct mie_type *c_type;
@@ -47,7 +46,7 @@ struct mie_selector {
struct mie_array {
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);

View File

@@ -2,8 +2,8 @@
#define MIE_CONVERT_H_
#include <blue/core/stringstream.h>
#include <blue/object/bitbuffer.h>
#include <blue/object/string.h>
#include <blue/ds/bitbuffer.h>
#include <blue/ds/string.h>
#include <mie/misc.h>
#include <stdio.h>

View File

@@ -4,11 +4,11 @@
#define MIE_MODULE(p) ((struct mie_module *)(p))
#include <blue/core/queue.h>
#include <blue/ds/hashmap.h>
#include <mie/ir/value.h>
#include <mie/name.h>
struct mie_func;
struct b_hashmap;
struct mie_module {
struct mie_value m_base;
@@ -17,8 +17,8 @@ struct mie_module {
b_queue m_types;
b_queue m_func;
struct b_hashmap *m_data;
struct b_hashmap *m_data_strings;
b_hashmap *m_data;
b_hashmap *m_data_strings;
};
extern struct mie_module *mie_module_create(void);

View File

@@ -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_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

View File

@@ -21,30 +21,24 @@ struct mie_select_use {
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 {
b_queue g_nodes;
struct mie_select_node *g_root;
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_node_id;
};
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 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);
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

View File

@@ -61,13 +61,13 @@ struct mie_select_node {
};
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(
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);

View File

@@ -20,6 +20,12 @@ enum mie_select_opcode {
MIE_SELECT_OP_MUL,
MIE_SELECT_OP_DIV,
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_COND,
};

View File

@@ -70,19 +70,26 @@ static void cleanup(struct mie_value *value)
{
struct mie_block *block = MIE_BLOCK(value);
b_queue_iterator it;
b_queue_iterator_begin(&block->b_phi, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
b_queue_entry *entry = b_queue_first(&block->b_phi);
b_queue_entry *next = NULL;
while (entry) {
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);
entry = next;
}
b_queue_iterator_begin(&block->b_instr, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
entry = b_queue_first(&block->b_instr);
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&block->b_instr, entry);
mie_value_destroy(v);
entry = next;
}
if (block->b_terminator) {

View File

@@ -1,4 +1,4 @@
#include <blue/object/string.h>
#include <blue/ds/string.h>
#include <mie/ctx.h>
#include <mie/ir/alloca.h>
#include <mie/ir/block.h>
@@ -52,15 +52,16 @@ struct mie_record *mie_builder_put_record(
return NULL;
}
b_queue_iterator it = {};
b_queue_foreach (&it, &builder->b_module->m_records) {
struct mie_value *rec
= b_unbox(struct mie_value, it.entry, v_entry);
b_queue_entry *entry = b_queue_first(&builder->b_module->m_records);
while (entry) {
struct mie_value *rec = b_unbox(struct mie_value, entry, v_entry);
if (!strcmp(rec->v_name.n_str, name)) {
/* TODO what to do about `val` here? */
return MIE_RECORD(rec);
}
entry = b_queue_next(entry);
}
struct mie_record *rec = mie_record_create(val);
@@ -77,14 +78,15 @@ struct mie_record *mie_builder_get_record(
return NULL;
}
b_queue_iterator it = {};
b_queue_foreach (&it, &builder->b_module->m_records) {
struct mie_value *rec
= b_unbox(struct mie_value, it.entry, v_entry);
b_queue_entry *entry = b_queue_first(&builder->b_module->m_records);
while (entry) {
struct mie_value *rec = b_unbox(struct mie_value, entry, v_entry);
if (!strcmp(rec->v_name.n_str, name)) {
return MIE_RECORD(rec);
}
entry = b_queue_next(entry);
}
return NULL;
@@ -579,7 +581,7 @@ struct mie_value *mie_builder_cmp_eq(
sub->op_left = left;
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)) {
free(sub);
@@ -615,7 +617,7 @@ struct mie_value *mie_builder_cmp_neq(
sub->op_left = left;
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)) {
free(sub);
@@ -651,7 +653,7 @@ struct mie_value *mie_builder_cmp_lt(
sub->op_left = left;
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)) {
free(sub);
@@ -687,7 +689,7 @@ struct mie_value *mie_builder_cmp_gt(
sub->op_left = left;
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)) {
free(sub);
@@ -723,7 +725,7 @@ struct mie_value *mie_builder_cmp_leq(
sub->op_left = left;
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)) {
free(sub);
@@ -759,7 +761,7 @@ struct mie_value *mie_builder_cmp_geq(
sub->op_left = left;
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)) {
free(sub);

View File

@@ -1,7 +1,7 @@
#include "convert.h"
#include <blue/object/hashmap.h>
#include <blue/object/list.h>
#include <blue/ds/hashmap.h>
#include <blue/ds/list.h>
#include <inttypes.h>
#include <mie/ir/alloca.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) {
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:
b_string_append_cstr(converter->c_dest.string, s);
return B_SUCCESS;
@@ -52,7 +53,8 @@ b_status write_string(struct mie_ir_converter *converter, const char *s)
switch (converter->c_dest_medium) {
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:
b_string_append_cstr(converter->c_dest.string, s);
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) {
case MIE_IR_CONVERTER_STRINGSTREAM:
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;
case MIE_IR_CONVERTER_STRING:
vsnprintf(buf, sizeof buf, format, arg);
@@ -147,23 +150,26 @@ static b_status write_operand_const(
break;
case MIE_TYPE_ARRAY: {
struct mie_array *array = MIE_ARRAY(value);
b_list_iterator it;
b_list_iterator_begin(array->a_values, &it);
b_iterator *it = b_list_begin(array->a_values);
write_char(converter, '{');
while (b_list_iterator_is_valid(&it)) {
if (it.i > 0) {
size_t i = 0;
b_foreach(void *, item, it)
{
if (i > 0) {
write_char(converter, ',');
}
write_string(converter, "\n ");
struct mie_value *child = it.item;
struct mie_value *child = item;
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)) {
write_char(converter, '\n');
}
@@ -292,39 +298,43 @@ static b_status write_module(
struct mie_module *mod = MIE_MODULE(value);
b_status status = B_SUCCESS;
b_queue_iterator it;
b_queue_foreach (&it, &mod->m_records) {
b_queue_entry *entry = b_queue_first(&mod->m_records);
while (entry) {
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);
if (!B_OK(status)) {
return status;
}
entry = b_queue_next(entry);
}
if (!b_queue_empty(&mod->m_records)) {
write_char(converter, '\n');
}
b_queue_foreach (&it, &mod->m_types) {
struct mie_value *type
= b_unbox(struct mie_value, it.entry, v_entry);
entry = b_queue_first(&mod->m_types);
while (entry) {
struct mie_value *type = b_unbox(struct mie_value, entry, v_entry);
status = write_value_to_text(converter, type);
if (!B_OK(status)) {
return status;
}
entry = b_queue_next(entry);
}
if (!b_queue_empty(&mod->m_types)) {
write_char(converter, '\n');
}
b_hashmap_iterator it2;
b_hashmap_foreach(&it2, mod->m_data)
b_iterator *it = b_iterator_begin(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);
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)) {
write_char(converter, '\n');
}
unsigned long i = 0;
b_queue_foreach (&it, &mod->m_func) {
entry = b_queue_first(&mod->m_func);
while (entry) {
if (i > 0) {
write_char(converter, '\n');
}
struct mie_value *func
= b_unbox(struct mie_value, it.entry, v_entry);
struct mie_value *func = b_unbox(struct mie_value, entry, v_entry);
status = write_value_to_text(converter, func);
if (!B_OK(status)) {
@@ -351,6 +363,7 @@ static b_status write_module(
}
i++;
entry = b_queue_next(entry);
}
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);
unsigned int i = 0;
b_queue_iterator it;
b_queue_foreach (&it, &func->f_args) {
struct b_queue_entry *entry = b_queue_first(&func->f_args);
while (entry) {
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) {
write_string(converter, ", ");
@@ -405,6 +418,7 @@ static b_status write_func_definition(
converter, "%s %%%s", type_name,
arg->arg_base.v_name.n_str);
i++;
entry = b_queue_next(entry);
}
write_string_f(converter, ")");
@@ -425,10 +439,12 @@ static b_status write_func_definition(
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
= b_unbox(struct mie_value, it.entry, v_entry);
= b_unbox(struct mie_value, entry, v_entry);
write_value_to_text(converter, block);
entry = b_queue_next(entry);
}
write_string_f(converter, "}\n");
@@ -442,17 +458,20 @@ static b_status write_block_definition(
struct mie_block *block = MIE_BLOCK(value);
write_string_f(converter, "%s:\n", block->b_base.v_name.n_str);
b_queue_iterator it;
b_queue_foreach (&it, &block->b_phi) {
b_queue_entry *entry = b_queue_first(&block->b_phi);
while (entry) {
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);
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
= b_unbox(struct mie_value, it.entry, v_entry);
= b_unbox(struct mie_value, entry, v_entry);
write_value_to_text(converter, instr);
entry = b_queue_next(entry);
}
if (block->b_terminator) {

View File

@@ -1,4 +1,4 @@
#include <blue/object/string.h>
#include <blue/ds/string.h>
#include <mie/ctx.h>
#include <mie/ir/data.h>
#include <mie/type.h>

View File

@@ -1,5 +1,5 @@
#include <blue/core/hash.h>
#include <blue/object/string.h>
#include <blue/ds/string.h>
#include <mie/ir/arg.h>
#include <mie/ir/block.h>
#include <mie/ir/func.h>
@@ -118,19 +118,26 @@ static void cleanup(struct mie_value *value)
{
struct mie_func *func = MIE_FUNC(value);
b_queue_iterator it;
b_queue_iterator_begin(&func->f_args, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
b_queue_entry *entry = b_queue_first(&func->f_args);
b_queue_entry *next = NULL;
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&func->f_args, entry);
mie_value_destroy(v);
entry = next;
}
b_queue_iterator_begin(&func->f_blocks, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
entry = b_queue_first(&func->f_blocks);
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&func->f_blocks, entry);
mie_value_destroy(v);
entry = next;
}
mie_name_map_destroy(func->f_names);

View File

@@ -1,4 +1,4 @@
#include <blue/object/hashmap.h>
#include <blue/ds/hashmap.h>
#include <mie/ir/const.h>
#include <mie/ir/data.h>
#include <mie/ir/func.h>
@@ -116,30 +116,36 @@ static void cleanup(struct mie_value *value)
{
struct mie_module *module = MIE_MODULE(value);
b_queue_iterator it;
b_queue_iterator_begin(&module->m_records, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
b_queue_entry *entry = b_queue_first(&module->m_records);
b_queue_entry *next = NULL;
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&module->m_records, entry);
mie_value_destroy(v);
entry = next;
}
b_queue_iterator_begin(&module->m_types, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
entry = b_queue_first(&module->m_types);
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&module->m_types, entry);
mie_value_destroy(v);
entry = next;
}
b_queue_iterator_begin(&module->m_func, &it);
while (b_queue_iterator_is_valid(&it)) {
struct mie_value *v = b_unbox(struct mie_value, it.entry, v_entry);
b_queue_iterator_erase(&it);
entry = b_queue_first(&module->m_func);
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&module->m_func, entry);
mie_value_destroy(v);
entry = next;
}
b_hashmap_release(module->m_data_strings);
b_hashmap_release(module->m_data);
b_hashmap_unref(module->m_data_strings);
b_hashmap_unref(module->m_data);
}
const struct mie_value_type module_value_type = {

View File

@@ -1,5 +1,5 @@
#include <blue/core/rope.h>
#include <blue/object/string.h>
#include <blue/ds/string.h>
#include <mie/name.h>
#include <stdlib.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)
{
b_queue_iterator it;
b_queue_iterator_begin(&bucket->b_names, &it);
b_queue_entry *entry = b_queue_first(&bucket->b_names);
while (b_queue_iterator_is_valid(&it)) {
b_queue_iterator_erase(&it);
while (entry) {
b_queue_entry *next = b_queue_next(entry);
b_queue_delete(&bucket->b_names, entry);
entry = next;
}
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)
{
b_btree_iterator it;
b_btree_iterator_begin(&map->m_entries, &it);
b_btree_node *node = b_btree_first(&map->m_entries);
while (b_btree_iterator_is_valid(&it)) {
while (node) {
struct mie_name_map_entry *entry
= b_unbox(struct mie_name_map_entry, it.node, e_node);
b_btree_iterator_erase(&it);
= b_unbox(struct mie_name_map_entry, node, e_node);
b_btree_node *next = b_btree_next(node);
b_btree_delete(&map->m_entries, node);
if (entry->e_type == MIE_NAME_MAP_E_BUCKET) {
struct mie_name_bucket *bucket
= (struct mie_name_bucket *)entry;
destroy_bucket(bucket);
}
node = next;
}
free(map);
@@ -69,14 +71,17 @@ void mie_name_map_destroy(struct mie_name_map *map)
static b_status put_name_in_bucket(
struct mie_name_bucket *bucket, struct mie_name *name)
{
b_queue_iterator it;
b_queue_foreach (&it, &bucket->b_names) {
b_queue_entry *entry = b_queue_first(&bucket->b_names);
while (entry) {
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)) {
return B_ERR_NAME_EXISTS;
}
entry = b_queue_next(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);
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);
if (B_OK(status)) {

View File

@@ -50,8 +50,20 @@ DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
DEFINE_PUSH_FUNCTION(sub, MIE_SELECT_OP_SUB);
DEFINE_PUSH_FUNCTION(mul, MIE_SELECT_OP_MUL);
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(sub);
DEFINE_OP(mul);
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
View 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,
};

View File

@@ -1,6 +1,6 @@
#include "builder.h"
#include <blue/object/hashmap.h>
#include <blue/ds/hashmap.h>
#include <mie/ctx.h>
#include <mie/ir/const.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);
if (!out->b_mem_access) {
b_hashmap_release(out->b_nodes);
b_hashmap_unref(out->b_nodes);
mie_select_graph_destroy(out->b_graph);
free(out);
return NULL;
@@ -63,11 +63,11 @@ struct mie_select_builder *mie_select_builder_create(
void mie_select_builder_destroy(struct mie_select_builder *builder)
{
if (builder->b_nodes) {
b_hashmap_release(builder->b_nodes);
b_hashmap_unref(builder->b_nodes);
}
if (builder->b_mem_access) {
b_hashmap_release(builder->b_mem_access);
b_hashmap_unref(builder->b_mem_access);
}
if (builder->b_graph) {
@@ -94,16 +94,6 @@ const struct mie_target *mie_select_builder_get_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)
{
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;
if (graph->g_last_chain.v_node) {
root_operands[0] = &graph->g_last_chain;
struct mie_select_value incoming_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++;
}
@@ -127,9 +123,13 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
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;
}
@@ -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_select_node *node = NULL;
b_queue_iterator it;
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
node = b_unbox(struct mie_select_node, it.entry, n_entry);
b_queue_entry *entry = b_queue_first(&builder->b_graph->g_nodes);
while (entry) {
node = b_unbox(struct mie_select_node, entry, n_entry);
if (node->n_target != builtin) {
continue;
goto skip;
}
if (node->n_opcode != MIE_SELECT_OP_CONSTANT) {
continue;
goto skip;
}
if (!(node->n_flags & MIE_SELECT_NODE_F_IVALUE)) {
continue;
goto skip;
}
if (node->n_value.i != value) {
continue;
goto skip;
}
mie_select_node_get_value(node, ctype, 0, out);
return MIE_SUCCESS;
skip:
entry = b_queue_next(entry);
}
enum mie_status status = mie_select_graph_get_node(
@@ -247,6 +249,32 @@ static enum mie_status get_data_node(
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_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);
break;
default:
status = get_external_value_node(builder, ir_val, select_val);
break;
}
@@ -364,19 +393,92 @@ enum mie_status mie_select_builder_set_mem_access(
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_builder *builder, const struct mie_target *target,
unsigned int opcode, long long val)
{
b_queue_iterator it;
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
b_queue_entry *entry = b_queue_first(&builder->b_graph->g_nodes);
while (entry) {
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
&& node->n_value.i == val) {
return node;
}
entry = b_queue_next(entry);
}
return NULL;

View File

@@ -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)
{
if (!value) {
b_stream_write_fmt(out, NULL, "<null>");
b_stream_write_fmt(out, NULL, "null");
return;
}
@@ -73,7 +73,7 @@ static void write_operand(struct mie_value *value, b_stream *out)
break;
default:
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;
}
}
@@ -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)
{
b_queue_iterator it;
b_queue_foreach (&it, &graph->g_nodes) {
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
while (entry) {
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);
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);
@@ -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, "\trankdir=\"BT\";\n", NULL);
b_queue_iterator it;
b_queue_foreach (&it, &graph->g_nodes) {
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
while (entry) {
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);
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
= 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);
entry = b_queue_next(entry);
}
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);
}

View File

@@ -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)
{
b_queue_iterator it;
b_queue_iterator_begin(&graph->g_nodes, &it);
while (b_queue_iterator_is_valid(&it)) {
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
while (entry) {
struct mie_select_node *node
= b_unbox(struct mie_select_node, it.entry, n_entry);
b_queue_iterator_erase(&it);
= b_unbox(struct mie_select_node, entry, n_entry);
b_queue_entry *next = b_queue_next(entry);
b_queue_delete(&graph->g_nodes, entry);
#if 0
if (node->n_value) {
@@ -56,11 +56,49 @@ void mie_select_graph_destroy(struct mie_select_graph *graph)
#endif
free(node);
entry = next;
}
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(
struct mie_select_graph *graph, const struct mie_target *target,
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;
for (size_t i = 0; i < nr_values; i++) {
if (values[i]->t_id == MIE_TYPE_OTHER) {
graph->g_last_chain.v_node = node;
graph->g_last_chain.v_index = i;
if (values[i]->t_id != MIE_TYPE_OTHER) {
continue;
}
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;
}
}

View File

@@ -11,15 +11,27 @@ DECLARE_INSTR_TYPE(add);
DECLARE_INSTR_TYPE(sub);
DECLARE_INSTR_TYPE(mul);
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(store);
DECLARE_INSTR_TYPE(msg);
DECLARE_INSTR_TYPE(br);
DECLARE_INSTR_TYPE(br_if);
static const struct select_instr_type *instr_types[] = {
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
INSTR_TYPE_ENTRY(SUB, sub), INSTR_TYPE_ENTRY(MUL, mul),
INSTR_TYPE_ENTRY(DIV, div), INSTR_TYPE_ENTRY(LOAD, load),
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(LOAD, load),
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
INSTR_TYPE_ENTRY(BR, br), INSTR_TYPE_ENTRY(BR_IF, br_if),
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];

View File

@@ -22,6 +22,7 @@ const struct select_node_type *select_type_for_node(enum mie_select_opcode node)
return node_types[node];
}
#if 0
void mie_select_node_iterator_next(struct mie_select_node_iterator *it)
{
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);
}
#endif
struct mie_select_node *mie_select_node_create(
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)
{
struct mie_select_use_iterator it;
mie_select_use_foreach(&it, &node->n_use)
{
struct mie_select_use *use = mie_select_use_iterator_unbox(&it);
b_queue_entry *entry = b_queue_first(&node->n_use);
while (entry) {
struct mie_select_use *use
= b_unbox(struct mie_select_use, entry, u_entry);
if (use->u_value.v_node == node) {
memset(&use->u_value, 0x0, sizeof use->u_value);
}
entry = b_queue_next(entry);
}
if (node->n_operands) {
@@ -158,12 +163,12 @@ enum mie_status mie_select_node_set_description(
{
va_list arg;
va_start(arg, format);
b_stringstream str;
b_stringstream_begin_dynamic(&str);
b_stringstream_addvf(&str, format, arg);
b_stringstream *str = b_stringstream_create();
b_stream_write_vfmt(str, NULL, format, 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;
}

View File

@@ -13,7 +13,7 @@ static size_t node_name(
switch (opcode) {
NODE_NAME(ENTRY, "Entry");
NODE_NAME(ROOT, "Root");
NODE_NAME(BLOCK, "Root");
NODE_NAME(BLOCK, "Block");
NODE_NAME(CONSTANT, "Constant");
NODE_NAME(FRAME_INDEX, "FrameIndex");
NODE_NAME(REGISTER, "Register");
@@ -27,6 +27,12 @@ static size_t node_name(
NODE_NAME(SUB, "Sub");
NODE_NAME(MUL, "Mul");
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(BR, "Branch");
NODE_NAME(BR_COND, "CondBranch");

18
tool/CMakeLists.txt Normal file
View 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
View 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
View 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
View 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
View 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
View 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);
}